1 # -*- encoding: utf-8 -*-
2 ##############################################################################
4 # Author: Nicolas Bessi, Guewen Baconnier
5 # Copyright Camptocamp SA 2011
7 # This program is free software: you can redistribute it and/or modify
8 # it under the terms of the GNU Affero General Public License as
9 # published by the Free Software Foundation, either version 3 of the
10 # License, or (at your option) any later version.
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU Affero General Public License for more details.
17 # You should have received a copy of the GNU Affero General Public License
18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
20 ##############################################################################
22 from collections
import defaultdict
23 from datetime
import datetime
24 from itertools
import groupby
25 from operator
import itemgetter
26 from mako
.template
import Template
30 from openerp
import pooler
31 from openerp
.osv
import osv
32 from openerp
.report
import report_sxw
33 from openerp
.tools
.translate
import _
34 from openerp
.addons
.report_webkit
import report_helper
35 from .common_partner_reports
import CommonPartnersReportHeaderWebkit
36 from .webkit_parser_header_fix
import HeaderFooterTextWebKitParser
39 def get_mako_template(obj
, *args
):
40 template_path
= openerp
.addons
.get_module_resource(*args
)
41 return Template(filename
=template_path
, input_encoding
='utf-8')
43 report_helper
.WebKitHelper
.get_mako_template
= get_mako_template
46 class PartnersOpenInvoicesWebkit(report_sxw
.rml_parse
, CommonPartnersReportHeaderWebkit
):
48 def __init__(self
, cursor
, uid
, name
, context
):
49 super(PartnersOpenInvoicesWebkit
, self
).__init
__(cursor
, uid
, name
, context
=context
)
50 self
.pool
= pooler
.get_pool(self
.cr
.dbname
)
53 company
= self
.pool
.get('res.users').browse(self
.cr
, uid
, uid
, context
=context
).company_id
54 header_report_name
= ' - '.join((_('OPEN INVOICES REPORT'), company
.name
, company
.currency_id
.name
))
56 footer_date_time
= self
.formatLang(str(datetime
.today()), date_time
=True)
58 self
.localcontext
.update({
61 'report_name': _('Open Invoices Report'),
62 'display_account_raw': self
._get
_display
_account
_raw
,
63 'filter_form': self
._get
_filter
,
64 'target_move': self
._get
_target
_move
,
65 'amount_currency': self
._get
_amount
_currency
,
66 'display_partner_account': self
._get
_display
_partner
_account
,
67 'display_target_move': self
._get
_display
_target
_move
,
69 ('--header-font-name', 'Helvetica'),
70 ('--footer-font-name', 'Helvetica'),
71 ('--header-font-size', '10'),
72 ('--footer-font-size', '6'),
73 ('--header-left', header_report_name
),
74 ('--header-spacing', '2'),
75 ('--footer-left', footer_date_time
),
76 ('--footer-right', ' '.join((_('Page'), '[page]', _('of'), '[topage]'))),
81 def _group_lines_by_currency(self
, account_br
):
82 account_br
.grouped_ledger_lines
= {}
83 if not account_br
.ledger_lines
:
85 for part_id
, plane_lines
in account_br
.ledger_lines
.items():
86 account_br
.grouped_ledger_lines
[part_id
] = []
87 plane_lines
.sort(key
=itemgetter('currency_code'))
88 for curr
, lines
in groupby(plane_lines
, key
=itemgetter('currency_code')):
89 tmp
= [x
for x
in lines
]
90 account_br
.grouped_ledger_lines
[part_id
].append((curr
, tmp
)) # I want to reiter many times
92 def set_context(self
, objects
, data
, ids
, report_type
=None):
93 """Populate a ledger_lines attribute on each browse record that will be used
95 new_ids
= data
['form']['chart_account_id']
96 # Account initial balance memoizer
97 init_balance_memoizer
= {}
99 main_filter
= self
._get
_form
_param
('filter', data
, default
='filter_no')
100 target_move
= self
._get
_form
_param
('target_move', data
, default
='all')
101 start_date
= self
._get
_form
_param
('date_from', data
)
102 stop_date
= self
._get
_form
_param
('date_to', data
)
103 start_period
= self
.get_start_period_br(data
)
104 stop_period
= self
.get_end_period_br(data
)
105 fiscalyear
= self
.get_fiscalyear_br(data
)
106 partner_ids
= self
._get
_form
_param
('partner_ids', data
)
107 result_selection
= self
._get
_form
_param
('result_selection', data
)
108 date_until
= self
._get
_form
_param
('until_date', data
)
109 chart_account
= self
._get
_chart
_account
_id
_br
(data
)
110 group_by_currency
= self
._get
_form
_param
('group_by_currency', data
)
112 if main_filter
== 'filter_no' and fiscalyear
:
113 start_period
= self
.get_first_fiscalyear_period(fiscalyear
)
114 stop_period
= self
.get_last_fiscalyear_period(fiscalyear
)
116 # Retrieving accounts
117 filter_type
= ('payable', 'receivable')
118 if result_selection
== 'customer':
119 filter_type
= ('receivable',)
120 if result_selection
== 'supplier':
121 filter_type
= ('payable',)
123 account_ids
= self
.get_all_accounts(new_ids
, exclude_type
=['view'], only_type
=filter_type
)
126 raise osv
.except_osv(_('Error'), _('No accounts to print.'))
128 # computation of ledeger lines
129 if main_filter
== 'filter_date':
135 ledger_lines_memoizer
= self
._compute
_open
_transactions
_lines
(account_ids
,
141 partner_filter
=partner_ids
)
143 for account
in self
.pool
.get('account.account').browse(self
.cursor
, self
.uid
, account_ids
):
144 account
.ledger_lines
= ledger_lines_memoizer
.get(account
.id, {})
145 account
.init_balance
= init_balance_memoizer
.get(account
.id, {})
146 ## we have to compute partner order based on inital balance
147 ## and ledger line as we may have partner with init bal
148 ## that are not in ledger line and vice versa
149 ledg_lines_pids
= ledger_lines_memoizer
.get(account
.id, {}).keys()
150 non_null_init_balances
= dict([(ib
, amounts
) for ib
, amounts
in account
.init_balance
.iteritems()
151 if amounts
['init_balance'] or amounts
['init_balance_currency']])
152 init_bal_lines_pids
= non_null_init_balances
.keys()
154 account
.partners_order
= self
._order
_partners
(ledg_lines_pids
, init_bal_lines_pids
)
155 account
.ledger_lines
= ledger_lines_memoizer
.get(account
.id, {})
156 if group_by_currency
:
157 self
._group
_lines
_by
_currency
(account
)
158 objects
.append(account
)
160 self
.localcontext
.update({
161 'fiscalyear': fiscalyear
,
162 'start_date': start_date
,
163 'stop_date': stop_date
,
164 'start_period': start_period
,
165 'stop_period': stop_period
,
166 'date_until': date_until
,
167 'partner_ids': partner_ids
,
168 'chart_account': chart_account
,
171 return super(PartnersOpenInvoicesWebkit
, self
).set_context(objects
, data
, new_ids
,
172 report_type
=report_type
)
174 def _compute_open_transactions_lines(self
, accounts_ids
, main_filter
, target_move
, start
, stop
, date_until
=False, partner_filter
=False):
175 res
= defaultdict(dict)
177 ## we check if until date and date stop have the same value
178 if main_filter
in ('filter_period', 'filter_no'):
179 date_stop
= stop
.date_stop
180 date_until_match
= (date_stop
== date_until
)
182 elif main_filter
== 'filter_date':
184 date_until_match
= (stop
== date_until
)
187 raise osv
.except_osv(_('Unsuported filter'),
188 _('Filter has to be in filter date, period, or none'))
190 initial_move_lines_per_account
= {}
191 if main_filter
in ('filter_period', 'filter_no'):
192 initial_move_lines_per_account
= self
._tree
_move
_line
_ids
(
193 self
._partners
_initial
_balance
_line
_ids
(accounts_ids
,
196 exclude_reconcile
=True,
197 force_period_ids
=False,
198 date_stop
=date_stop
), key
='id')
200 for account_id
in accounts_ids
:
201 initial_move_lines_ids_per_partner
= initial_move_lines_per_account
.get(account_id
, {})
203 # We get the move line ids of the account
204 move_line_ids_per_partner
= self
.get_partners_move_lines_ids(account_id
,
209 exclude_reconcile
=True,
210 partner_filter
=partner_filter
)
212 if not initial_move_lines_ids_per_partner
and not move_line_ids_per_partner
:
214 for partner_id
in list(set(initial_move_lines_ids_per_partner
.keys() + move_line_ids_per_partner
.keys())):
215 partner_line_ids
= (move_line_ids_per_partner
.get(partner_id
, []) +
216 initial_move_lines_ids_per_partner
.get(partner_id
, []))
218 clearance_line_ids
= []
219 if date_until
and not date_until_match
and partner_line_ids
:
220 clearance_line_ids
= self
._get
_clearance
_move
_line
_ids
(partner_line_ids
, date_stop
, date_until
)
221 partner_line_ids
+= clearance_line_ids
223 lines
= self
._get
_move
_line
_datas
(list(set(partner_line_ids
)))
225 if line
['id'] in initial_move_lines_ids_per_partner
.get(partner_id
, []):
226 line
['is_from_previous_periods'] = True
227 if line
['id'] in clearance_line_ids
:
228 line
['is_clearance_line'] = True
230 res
[account_id
][partner_id
] = lines
234 HeaderFooterTextWebKitParser('report.account.account_report_open_invoices_webkit',
236 'addons/account_financial_report_webkit/report/templates/account_report_open_invoices.mako',
237 parser
=PartnersOpenInvoicesWebkit
)