You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

190 lines
9.2 KiB

  1. # -*- encoding: utf-8 -*-
  2. ##############################################################################
  3. #
  4. # Author: Nicolas Bessi, Guewen Baconnier
  5. # Copyright Camptocamp SA 2011
  6. #
  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.
  11. #
  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.
  16. #
  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/>.
  19. #
  20. ##############################################################################
  21. import pooler
  22. from collections import defaultdict
  23. from report import report_sxw
  24. from osv import osv
  25. from tools.translate import _
  26. from datetime import datetime
  27. from common_partner_reports import CommonPartnersReportHeaderWebkit
  28. from webkit_parser_header_fix import HeaderFooterTextWebKitParser
  29. class PartnersLedgerWebkit(report_sxw.rml_parse, CommonPartnersReportHeaderWebkit):
  30. def __init__(self, cursor, uid, name, context):
  31. super(PartnersLedgerWebkit, self).__init__(cursor, uid, name, context=context)
  32. self.pool = pooler.get_pool(self.cr.dbname)
  33. self.cursor = self.cr
  34. company = self.pool.get('res.users').browse(self.cr, uid, uid, context=context).company_id
  35. header_report_name = ' - '.join((_('PARTNER LEDGER'), company.name, company.currency_id.name))
  36. footer_date_time = self.formatLang(str(datetime.today()), date_time=True)
  37. self.localcontext.update({
  38. 'cr': cursor,
  39. 'uid': uid,
  40. 'report_name':_('Partner Ledger'),
  41. 'display_account_raw': self._get_display_account_raw,
  42. 'filter_form': self._get_filter,
  43. 'target_move': self._get_target_move,
  44. 'initial_balance': self._get_initial_balance,
  45. 'amount_currency': self._get_amount_currency,
  46. 'display_partner_account': self._get_display_partner_account,
  47. 'display_target_move': self._get_display_target_move,
  48. 'additional_args': [
  49. ('--header-font-name', 'Helvetica'),
  50. ('--footer-font-name', 'Helvetica'),
  51. ('--header-font-size', '10'),
  52. ('--footer-font-size', '6'),
  53. ('--header-left', header_report_name),
  54. ('--header-spacing', '2'),
  55. ('--footer-left', footer_date_time),
  56. ('--footer-right', ' '.join((_('Page'), '[page]', _('of'), '[topage]'))),
  57. ('--footer-line',),
  58. ],
  59. })
  60. def set_context(self, objects, data, ids, report_type=None):
  61. """Populate a ledger_lines attribute on each browse record that will be used
  62. by mako template"""
  63. new_ids = data['form']['chart_account_id']
  64. # account partner memoizer
  65. # Reading form
  66. main_filter = self._get_form_param('filter', data, default='filter_no')
  67. target_move = self._get_form_param('target_move', data, default='all')
  68. start_date = self._get_form_param('date_from', data)
  69. stop_date = self._get_form_param('date_to', data)
  70. start_period = self.get_start_period_br(data)
  71. stop_period = self.get_end_period_br(data)
  72. fiscalyear = self.get_fiscalyear_br(data)
  73. partner_ids = self._get_form_param('partner_ids', data)
  74. result_selection = self._get_form_param('result_selection', data)
  75. chart_account = self._get_chart_account_id_br(data)
  76. if main_filter == 'filter_no' and fiscalyear:
  77. start_period = self.get_first_fiscalyear_period(fiscalyear)
  78. stop_period = self.get_last_fiscalyear_period(fiscalyear)
  79. # Retrieving accounts
  80. filter_type = ('payable', 'receivable')
  81. if result_selection == 'customer':
  82. filter_type = ('receivable',)
  83. if result_selection == 'supplier':
  84. filter_type = ('payable',)
  85. accounts = self.get_all_accounts(new_ids, exclude_type=['view'],
  86. only_type=filter_type)
  87. if not accounts:
  88. raise osv.except_osv(_('Error'), _('No accounts to print.'))
  89. if main_filter == 'filter_date':
  90. start = start_date
  91. stop = stop_date
  92. else:
  93. start = start_period
  94. stop = stop_period
  95. # when the opening period is included in the selected range of periods and
  96. # the opening period contains move lines, we must not compute the initial balance from previous periods
  97. # but only display the move lines of the opening period
  98. # we identify them as :
  99. # - 'initial_balance' means compute the sums of move lines from previous periods
  100. # - 'opening_balance' means display the move lines of the opening period
  101. init_balance = main_filter in ('filter_no', 'filter_period')
  102. initial_balance_mode = init_balance and self._get_initial_balance_mode(start) or False
  103. init_balance_memoizer = {}
  104. if initial_balance_mode == 'initial_balance':
  105. init_balance_memoizer = self._compute_partners_initial_balances(accounts,
  106. start_period,
  107. partner_filter=partner_ids,
  108. exclude_reconcile=False)
  109. ledger_lines_memoizer = self._compute_partner_ledger_lines(accounts,
  110. main_filter,
  111. target_move,
  112. start,
  113. stop,
  114. partner_filter=partner_ids)
  115. objects = []
  116. for account in self.pool.get('account.account').browse(self.cursor, self.uid, accounts):
  117. account.ledger_lines = ledger_lines_memoizer.get(account.id, {})
  118. account.init_balance = init_balance_memoizer.get(account.id, {})
  119. ## we have to compute partner order based on inital balance
  120. ## and ledger line as we may have partner with init bal
  121. ## that are not in ledger line and vice versa
  122. ledg_lines_pids = ledger_lines_memoizer.get(account.id, {}).keys()
  123. if initial_balance_mode:
  124. non_null_init_balances = dict([(ib, amounts) for ib, amounts in account.init_balance.iteritems()
  125. if amounts['init_balance'] or amounts['init_balance_currency']])
  126. init_bal_lines_pids = non_null_init_balances.keys()
  127. else:
  128. account.init_balance = {}
  129. init_bal_lines_pids = []
  130. account.partners_order = self._order_partners(ledg_lines_pids, init_bal_lines_pids)
  131. account.ledger_lines = ledger_lines_memoizer.get(account.id, {})
  132. objects.append(account)
  133. self.localcontext.update({
  134. 'fiscalyear': fiscalyear,
  135. 'start_date': start_date,
  136. 'stop_date': stop_date,
  137. 'start_period': start_period,
  138. 'stop_period': stop_period,
  139. 'partner_ids': partner_ids,
  140. 'chart_account': chart_account,
  141. 'initial_balance_mode': initial_balance_mode,
  142. })
  143. return super(PartnersLedgerWebkit, self).set_context(objects, data, new_ids,
  144. report_type=report_type)
  145. def _compute_partner_ledger_lines(self, accounts_ids, main_filter, target_move, start, stop, partner_filter=False):
  146. res = defaultdict(dict)
  147. for acc_id in accounts_ids:
  148. move_line_ids = self.get_partners_move_lines_ids(acc_id,
  149. main_filter,
  150. start,
  151. stop,
  152. target_move,
  153. exclude_reconcile=False,
  154. partner_filter=partner_filter)
  155. if not move_line_ids:
  156. continue
  157. for partner_id in move_line_ids:
  158. partner_line_ids = move_line_ids.get(partner_id, [])
  159. lines = self._get_move_line_datas(list(set(partner_line_ids)))
  160. res[acc_id][partner_id] = lines
  161. return res
  162. HeaderFooterTextWebKitParser('report.account.account_report_partners_ledger_webkit',
  163. 'account.account',
  164. 'addons/account_financial_report_webkit/report/templates/account_report_partners_ledger.mako',
  165. parser=PartnersLedgerWebkit)