FollowUp reports

bzr revid: fp@tinyerp.com-6b109199834f90f01a5853eafcc49c6c25b219ca
This commit is contained in:
Fabien Pinckaers
2007-06-26 08:13:30 +00:00
parent 35526fbf10
commit d1c7e0f80d
4 changed files with 140 additions and 27 deletions
@@ -0,0 +1,83 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2004-2006 TINY SPRL. (http://tiny.be) All Rights Reserved.
#
# $Id: account.py 1005 2005-07-25 08:41:42Z nicoe $
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
from osv import fields, osv
def _code_get(self, cr, uid, context={}):
acc_type_obj = self.pool.get('account.account.type')
ids = acc_type_obj.search(cr, uid, [])
res = acc_type_obj.read(cr, uid, ids, ['code', 'name'], context)
return [(r['code'], r['name']) for r in res]
class account_followup_stat(osv.osv):
_name = "account_followup.stat"
_description = "Followup statistics"
_auto = False
_columns = {
'name': fields.many2one('res.partner', 'Partner', readonly=True),
'account_type': fields.selection(_code_get, 'Account Type', required=True),
'date_move':fields.date('First move', readonly=True),
'date_move_last':fields.date('Last move', readonly=True),
'date_followup':fields.date('Latest followup', readonly=True),
'followup_id': fields.many2one('account_followup.followup.line', 'Follow Ups', required=True, ondelete="cascade"),
'balance':fields.float('Balance', readonly=True),
'debit':fields.float('Debit', readonly=True),
'credit':fields.float('Credit', readonly=True),
}
_order = 'date_move'
def init(self, cr):
cr.execute("""
create or replace view account_followup_stat as (
select
l.partner_id as id,
l.partner_id as name,
min(l.date) as date_move,
max(l.date) as date_move_last,
max(l.followup_date) as date_followup,
max(l.followup_line_id) as followup_id,
sum(l.debit) as debit,
sum(l.credit) as credit,
sum(l.debit - l.credit) as balance,
a.type as account_type
from
account_move_line l
left join
account_account a on (l.account_id=a.id)
where
l.reconcile_id is NULL and
a.type in ('receivable', 'payable')
group by
l.partner_id, a.type
)""")
account_followup_stat()
@@ -0,0 +1,56 @@
<?xml version="1.0"?>
<terp>
<data>
<record model="ir.ui.view" id="view_account_followup_stat_form">
<field name="name">account_followup.stat.form</field>
<field name="model">account_followup.stat</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Follow-Up lines">
<field name="name" select="1"/>
<field name="account_type" select="2"/>
<field name="date_move" select="1"/>
<field name="date_move_last" select="1"/>
<field name="date_followup" select="2"/>
<field name="followup_id" select="2"/>
<field name="balance" select="2"/>
<field name="debit"/>
<field name="credit"/>
</form>
</field>
</record>
<record model="ir.ui.view" id="view_account_followup_stat_tree">
<field name="name">account_followup.stat.tree</field>
<field name="model">account_followup.stat</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="Follow-Up lines">
<field name="name"/>
<field name="account_type"/>
<field name="date_move"/>
<field name="date_move_last"/>
<field name="date_followup"/>
<field name="followup_id"/>
<field name="balance"/>
<field name="debit"/>
<field name="credit"/>
</tree>
</field>
</record>
<record model="ir.actions.act_window" id="action_followup_stat">
<field name="name">Follow-Ups</field>
<field name="res_model">account_followup.stat</field>
<field name="view_type">form</field>
</record>
<menuitem
name="Financial Management/Reporting/"
id="menu_action_followup_stat"
action="action_followup_stat"/>
</data>
</terp>
@@ -54,11 +54,8 @@ class report_rappel(report_sxw.rml_parse):
return res_partner_address.read(self.cr, self.uid, [adr])[0]
def _lines_get(self, partner):
acc = partner.property_account_receivable[0]
moveline_obj = pooler.get_pool(self.cr.dbname).get('account.move.line')
movelines = moveline_obj.search(self.cr, self.uid, [('partner_id','=',partner.id), ('account_id','=',acc), ('state','=','valid')])
movelines = moveline_obj.search(self.cr, self.uid, [('partner_id','=',partner.id), ('account_id','=','type:receivable'), ('reconcile_id','=',False),('state','<>','draft')])
movelines = moveline_obj.read(self.cr, self.uid, movelines)
return movelines
report_sxw.report_sxw('report.account_followup.followup.print', 'res.partner', 'addons/account_followup/report/rappel.rml',parser=report_rappel)
@@ -70,11 +70,6 @@ class followup_all_print(wizard.interface):
'You must define at least one follow up for your company !')
fup_id = fup_ids[0]
# fups = {
# previous fup line id: (limit date for current fup line,
# current fup line id),
# ...
# }
current_date = datetime.date.today()
cr.execute(
"SELECT * "\
@@ -82,36 +77,20 @@ class followup_all_print(wizard.interface):
"WHERE followup_id=%d "\
"ORDER BY sequence", (fup_id,))
for result in cr.dictfetchall():
# compute date from when move lines entered earlier than it need
# a follow up
delay = datetime.timedelta(days=result['delay'])
fups[old] = (current_date - delay, result['id'])
if result['start'] == 'end_of_month':
#CHECKME: I have a bad feeling about this...
# but it depends on the semantic of the field, which I don't
# know
fups[old][0].replace(day=1)
# old = id of previous fup line
old = result['id']
# we don't want any followup after the last one
fups[old] = (datetime.date(datetime.MAXYEAR, 12, 31), old)
partner_list = []
for partner_id, followup_line_id, date, id in move_lines:
if (partner_id in partner_list) or (not partner_id):
continue
# if the move line has already a followup line but it is invalid,
# we just skip the move line.
# Note that having no follow-up line *is* valid because of the way
# fups is constructed (fups[None] = ...)
if followup_line_id not in fups:
continue
# if the move_line happened before the limit date for this level
# of followup, we mark the partner as needing a follow up, and
# mark the line has having had this level of follow up
if date <= fups[followup_line_id][0].strftime('%Y-%m-%d'):
partner_list.append(partner_id)
cr.execute(
@@ -121,7 +100,6 @@ class followup_all_print(wizard.interface):
(fups[followup_line_id][1],
current_date.strftime('%Y-%m-%d'), id,))
return {'partner_id': partner_list}
states = {
'init' : {
'actions': [_get_partners],
@@ -135,7 +113,6 @@ class followup_all_print(wizard.interface):
'actions': [_update_partners],
'result': {'type':'print', 'report':'account_followup.followup.print', 'state':'end'},
},
}
followup_all_print('account_followup.followup.print.all')