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
25 from openerp
import pooler
26 from openerp
.osv
import osv
27 from openerp
.report
import report_sxw
28 from openerp
.tools
.translate
import _
29 from .common_partner_reports
import CommonPartnersReportHeaderWebkit
30 from .webkit_parser_header_fix
import HeaderFooterTextWebKitParser
33 class PartnersLedgerWebkit(report_sxw
.rml_parse
, CommonPartnersReportHeaderWebkit
):
35 def __init__(self
, cursor
, uid
, name
, context
):
36 super(PartnersLedgerWebkit
, self
).__init
__(cursor
, uid
, name
, context
=context
)
37 self
.pool
= pooler
.get_pool(self
.cr
.dbname
)
40 company
= self
.pool
.get('res.users').browse(self
.cr
, uid
, uid
, context
=context
).company_id
41 header_report_name
= ' - '.join((_('PARTNER LEDGER'), company
.name
, company
.currency_id
.name
))
43 footer_date_time
= self
.formatLang(str(datetime
.today()), date_time
=True)
45 self
.localcontext
.update({
48 'report_name': _('Partner Ledger'),
49 'display_account_raw': self
._get
_display
_account
_raw
,
50 'filter_form': self
._get
_filter
,
51 'target_move': self
._get
_target
_move
,
52 'initial_balance': self
._get
_initial
_balance
,
53 'amount_currency': self
._get
_amount
_currency
,
54 'display_partner_account': self
._get
_display
_partner
_account
,
55 'display_target_move': self
._get
_display
_target
_move
,
57 ('--header-font-name', 'Helvetica'),
58 ('--footer-font-name', 'Helvetica'),
59 ('--header-font-size', '10'),
60 ('--footer-font-size', '6'),
61 ('--header-left', header_report_name
),
62 ('--header-spacing', '2'),
63 ('--footer-left', footer_date_time
),
64 ('--footer-right', ' '.join((_('Page'), '[page]', _('of'), '[topage]'))),
69 def _get_initial_balance_mode(self
, start_period
):
70 """ Force computing of initial balance for the partner ledger,
71 because we cannot use the entries generated by
72 OpenERP in the opening period.
74 OpenERP allows to reconcile move lines between different partners,
75 so the generated entries in the opening period are unreliable.
77 return 'initial_balance'
79 def set_context(self
, objects
, data
, ids
, report_type
=None):
80 """Populate a ledger_lines attribute on each browse record that will be used
82 new_ids
= data
['form']['chart_account_id']
84 # account partner memoizer
86 main_filter
= self
._get
_form
_param
('filter', data
, default
='filter_no')
87 target_move
= self
._get
_form
_param
('target_move', data
, default
='all')
88 start_date
= self
._get
_form
_param
('date_from', data
)
89 stop_date
= self
._get
_form
_param
('date_to', data
)
90 start_period
= self
.get_start_period_br(data
)
91 stop_period
= self
.get_end_period_br(data
)
92 fiscalyear
= self
.get_fiscalyear_br(data
)
93 partner_ids
= self
._get
_form
_param
('partner_ids', data
)
94 result_selection
= self
._get
_form
_param
('result_selection', data
)
95 chart_account
= self
._get
_chart
_account
_id
_br
(data
)
97 if main_filter
== 'filter_no' and fiscalyear
:
98 start_period
= self
.get_first_fiscalyear_period(fiscalyear
)
99 stop_period
= self
.get_last_fiscalyear_period(fiscalyear
)
101 # Retrieving accounts
102 filter_type
= ('payable', 'receivable')
103 if result_selection
== 'customer':
104 filter_type
= ('receivable',)
105 if result_selection
== 'supplier':
106 filter_type
= ('payable',)
108 accounts
= self
.get_all_accounts(new_ids
, exclude_type
=['view'],
109 only_type
=filter_type
)
112 raise osv
.except_osv(_('Error'), _('No accounts to print.'))
114 if main_filter
== 'filter_date':
121 # when the opening period is included in the selected range of periods and
122 # the opening period contains move lines, we must not compute the initial balance from previous periods
123 # but only display the move lines of the opening period
124 # we identify them as:
125 # - 'initial_balance' means compute the sums of move lines from previous periods
126 # - 'opening_balance' means display the move lines of the opening period
127 init_balance
= main_filter
in ('filter_no', 'filter_period')
128 initial_balance_mode
= init_balance
and self
._get
_initial
_balance
_mode
(start
) or False
130 initial_balance_lines
= {}
131 if initial_balance_mode
== 'initial_balance':
132 initial_balance_lines
= self
._compute
_partners
_initial
_balances
(accounts
,
134 partner_filter
=partner_ids
,
135 exclude_reconcile
=False)
137 ledger_lines
= self
._compute
_partner
_ledger
_lines
(accounts
,
142 partner_filter
=partner_ids
)
144 for account
in self
.pool
.get('account.account').browse(self
.cursor
, self
.uid
, accounts
):
145 account
.ledger_lines
= ledger_lines
.get(account
.id, {})
146 account
.init_balance
= initial_balance_lines
.get(account
.id, {})
147 ## we have to compute partner order based on inital balance
148 ## and ledger line as we may have partner with init bal
149 ## that are not in ledger line and vice versa
150 ledg_lines_pids
= ledger_lines
.get(account
.id, {}).keys()
151 if initial_balance_mode
:
152 non_null_init_balances
= dict([(ib
, amounts
) for ib
, amounts
in account
.init_balance
.iteritems()
153 if amounts
['init_balance'] or amounts
['init_balance_currency']])
154 init_bal_lines_pids
= non_null_init_balances
.keys()
156 account
.init_balance
= {}
157 init_bal_lines_pids
= []
159 account
.partners_order
= self
._order
_partners
(ledg_lines_pids
, init_bal_lines_pids
)
160 objects
.append(account
)
162 self
.localcontext
.update({
163 'fiscalyear': fiscalyear
,
164 'start_date': start_date
,
165 'stop_date': stop_date
,
166 'start_period': start_period
,
167 'stop_period': stop_period
,
168 'partner_ids': partner_ids
,
169 'chart_account': chart_account
,
170 'initial_balance_mode': initial_balance_mode
,
173 return super(PartnersLedgerWebkit
, self
).set_context(objects
, data
, new_ids
,
174 report_type
=report_type
)
176 def _compute_partner_ledger_lines(self
, accounts_ids
, main_filter
, target_move
, start
, stop
, partner_filter
=False):
177 res
= defaultdict(dict)
179 for acc_id
in accounts_ids
:
180 move_line_ids
= self
.get_partners_move_lines_ids(acc_id
,
185 exclude_reconcile
=False,
186 partner_filter
=partner_filter
)
187 if not move_line_ids
:
189 for partner_id
in move_line_ids
:
190 partner_line_ids
= move_line_ids
.get(partner_id
, [])
191 lines
= self
._get
_move
_line
_datas
(list(set(partner_line_ids
)))
192 res
[acc_id
][partner_id
] = lines
196 HeaderFooterTextWebKitParser('report.account.account_report_partners_ledger_webkit',
198 'addons/account_financial_report_webkit/report/templates/account_report_partners_ledger.mako',
199 parser
=PartnersLedgerWebkit
)