diff --git a/account_financial_report_webkit/report/common_partner_reports.py b/account_financial_report_webkit/report/common_partner_reports.py index d2fa7a29..deb5122d 100644 --- a/account_financial_report_webkit/report/common_partner_reports.py +++ b/account_financial_report_webkit/report/common_partner_reports.py @@ -23,7 +23,9 @@ # By using properties we will have a more simple signature in fuctions from collections import defaultdict +from datetime import datetime +from openerp.tools import DEFAULT_SERVER_DATE_FORMAT from common_reports import CommonReportHeaderWebkit @@ -33,8 +35,7 @@ class CommonPartnersReportHeaderWebkit(CommonReportHeaderWebkit): ####################Account move line retrieval helper ########################## def get_partners_move_lines_ids(self, account_id, main_filter, start, stop, target_move, exclude_reconcile=False, - partner_filter=False, - opening_mode='exclude_opening'): + partner_filter=False): filter_from = False if main_filter in ('filter_period', 'filter_no'): filter_from = 'period' @@ -46,18 +47,70 @@ class CommonPartnersReportHeaderWebkit(CommonReportHeaderWebkit): start, stop, target_move, - opening_mode=opening_mode, exclude_reconcile=exclude_reconcile, partner_filter=partner_filter) + def _get_first_special_period(self): + """ + Returns the browse record of the period with the `special` flag, which + is the special period of the first fiscal year used in the accounting. + + i.e. it searches the first fiscal year with at least one journal entry, + and it returns the id of the first period for which `special` is True + in this fiscal year. + + It is used for example in the partners reports, where we have to include + the first, and only the first opening period. + + :return: browse record of the first special period. + """ + move_line_obj = self.pool.get('account.move.line') + first_entry_id = move_line_obj.search( + self.cr, self.uid, [], order='date ASC', limit=1) + # it means there is no entry at all, that's unlikely to happen, but + # it may so + if not first_entry_id: + return + first_entry = move_line_obj.browse(self.cr, self.uid, first_entry_id[0]) + fiscalyear = first_entry.period_id.fiscalyear_id + special_periods = [period for period in fiscalyear.period_ids if period.special] + # so, we have no opening period on the first year, nothing to return + if not special_periods: + return + return min(special_periods, + key=lambda p: datetime.strptime(p.date_start, DEFAULT_SERVER_DATE_FORMAT)) + + def _get_period_range_from_start_period(self, start_period, include_opening=False, + fiscalyear=False, + stop_at_previous_opening=False): + """We retrieve all periods before start period""" + periods = super(CommonPartnersReportHeaderWebkit, self).\ + _get_period_range_from_start_period( + start_period, + include_opening=include_opening, + fiscalyear=fiscalyear, + stop_at_previous_opening=stop_at_previous_opening) + first_special = self._get_first_special_period() + if first_special and first_special.id not in periods: + periods.append(first_special.id) + return periods + def _get_query_params_from_periods(self, period_start, period_stop, mode='exclude_opening'): + """ + Build the part of the sql "where clause" which filters on the selected + periods. + + :param browse_record period_start: first period of the report to print + :param browse_record period_stop: last period of the report to print + :param str mode: deprecated + """ # we do not want opening period so we exclude opening - periods = self.pool.get('account.period').build_ctx_periods(self.cr, self.uid, period_start.id, period_stop.id) + periods = self.pool.get('account.period').build_ctx_periods( + self.cr, self.uid, period_start.id, period_stop.id) if not periods: return [] - if mode == 'exclude_opening': - periods = self.exclude_opening_periods(periods) + periods = self.exclude_opening_periods(periods) search_params = {'period_ids': tuple(periods), 'date_stop': period_stop.date_stop} @@ -67,6 +120,12 @@ class CommonPartnersReportHeaderWebkit(CommonReportHeaderWebkit): return sql_conditions, search_params def _get_query_params_from_dates(self, date_start, date_stop, **args): + """ + Build the part of the sql where clause based on the dates to print. + + :param str date_start: start date of the report to print + :param str date_stop: end date of the report to print + """ periods = self._get_opening_periods() if not periods: @@ -81,8 +140,22 @@ class CommonPartnersReportHeaderWebkit(CommonReportHeaderWebkit): return sql_conditions, search_params - def _get_partners_move_line_ids(self, filter_from, account_id, start, stop, target_move, opening_mode='exclude_opening', - exclude_reconcile=False, partner_filter=False): + def _get_partners_move_line_ids(self, filter_from, account_id, start, stop, + target_move, opening_mode='exclude_opening', + exclude_reconcile=False, partner_filter=None): + """ + + :param str filter_from: "periods" or "dates" + :param int account_id: id of the account where to search move lines + :param str or browse_record start: start date or start period + :param str or browse_record stop: stop date or stop period + :param str target_move: 'posted' or 'all' + :param opening_mode: deprecated + :param boolean exclude_reconcile: wether the reconciled entries are + filtred or not + :param list partner_filter: list of partner ids, will filter on their + move lines + """ final_res = defaultdict(list) @@ -90,8 +163,8 @@ class CommonPartnersReportHeaderWebkit(CommonReportHeaderWebkit): sql_joins = '' sql_where = " WHERE account_move_line.account_id = %(account_ids)s " \ " AND account_move_line.state = 'valid' " - - sql_conditions, search_params = getattr(self, '_get_query_params_from_'+filter_from+'s')(start, stop, mode=opening_mode) + + sql_conditions, search_params = getattr(self, '_get_query_params_from_'+filter_from+'s')(start, stop) sql_where += sql_conditions @@ -252,3 +325,4 @@ class CommonPartnersReportHeaderWebkit(CommonReportHeaderWebkit): if not res: return [] return res + diff --git a/account_financial_report_webkit/report/open_invoices.py b/account_financial_report_webkit/report/open_invoices.py index f0b3ffd3..a6bd720f 100644 --- a/account_financial_report_webkit/report/open_invoices.py +++ b/account_financial_report_webkit/report/open_invoices.py @@ -208,8 +208,7 @@ class PartnersOpenInvoicesWebkit(report_sxw.rml_parse, CommonPartnersReportHeade stop, target_move, exclude_reconcile=True, - partner_filter=partner_filter, - opening_mode='exclude_opening') + partner_filter=partner_filter) if not initial_move_lines_ids_per_partner and not move_line_ids_per_partner: continue diff --git a/account_financial_report_webkit/report/partners_ledger.py b/account_financial_report_webkit/report/partners_ledger.py index f30b512a..ea261be5 100644 --- a/account_financial_report_webkit/report/partners_ledger.py +++ b/account_financial_report_webkit/report/partners_ledger.py @@ -127,27 +127,27 @@ class PartnersLedgerWebkit(report_sxw.rml_parse, CommonPartnersReportHeaderWebki init_balance = main_filter in ('filter_no', 'filter_period') initial_balance_mode = init_balance and self._get_initial_balance_mode(start) or False - init_balance_memoizer = {} + initial_balance_lines = {} if initial_balance_mode == 'initial_balance': - init_balance_memoizer = self._compute_partners_initial_balances(accounts, + initial_balance_lines = self._compute_partners_initial_balances(accounts, start_period, partner_filter=partner_ids, exclude_reconcile=False) - ledger_lines_memoizer = self._compute_partner_ledger_lines(accounts, - main_filter, - target_move, - start, - stop, - partner_filter=partner_ids) + ledger_lines = self._compute_partner_ledger_lines(accounts, + main_filter, + target_move, + start, + stop, + partner_filter=partner_ids) objects = [] for account in self.pool.get('account.account').browse(self.cursor, self.uid, accounts): - account.ledger_lines = ledger_lines_memoizer.get(account.id, {}) - account.init_balance = init_balance_memoizer.get(account.id, {}) + account.ledger_lines = ledger_lines.get(account.id, {}) + account.init_balance = initial_balance_lines.get(account.id, {}) ## we have to compute partner order based on inital balance ## and ledger line as we may have partner with init bal ## that are not in ledger line and vice versa - ledg_lines_pids = ledger_lines_memoizer.get(account.id, {}).keys() + ledg_lines_pids = ledger_lines.get(account.id, {}).keys() if initial_balance_mode: non_null_init_balances = dict([(ib, amounts) for ib, amounts in account.init_balance.iteritems() if amounts['init_balance'] or amounts['init_balance_currency']]) @@ -157,7 +157,6 @@ class PartnersLedgerWebkit(report_sxw.rml_parse, CommonPartnersReportHeaderWebki init_bal_lines_pids = [] account.partners_order = self._order_partners(ledg_lines_pids, init_bal_lines_pids) - account.ledger_lines = ledger_lines_memoizer.get(account.id, {}) objects.append(account) self.localcontext.update({ @@ -184,8 +183,7 @@ class PartnersLedgerWebkit(report_sxw.rml_parse, CommonPartnersReportHeaderWebki stop, target_move, exclude_reconcile=False, - partner_filter=partner_filter, - opening_mode='exclude_opening') + partner_filter=partner_filter) if not move_line_ids: continue for partner_id in move_line_ids: diff --git a/account_financial_report_webkit/report/templates/account_report_partner_balance.mako b/account_financial_report_webkit/report/templates/account_report_partner_balance.mako index 89112c34..dd3ab367 100644 --- a/account_financial_report_webkit/report/templates/account_report_partner_balance.mako +++ b/account_financial_report_webkit/report/templates/account_report_partner_balance.mako @@ -15,7 +15,7 @@ font-size: 15px; background-color:#F0F0F0; } - + .account_line .act_as_cell { height: 30px; vertical-align: bottom; @@ -27,6 +27,9 @@ <%! def amount(text): return text.replace('-', '‑') # replace by a non-breaking hyphen (it will not word-wrap between hyphen and numbers) + + def display_line(all_comparison_lines): + return any([line.get('balance') for line in all_comparison_lines]) %> <%setLang(user.context_lang)%> @@ -99,7 +102,6 @@ %endfor - %for current_account in objects: <% partners_order = current_account.partners_order @@ -110,9 +112,13 @@ comparisons = current_account.comparisons - all_comparison_lines = [comp['partners_amounts'][partner_id[1]] for partner_id in partners_order for comp in comparisons] - if not current_account.balance and not any([line.get('balance') for line in all_comparison_lines]): - continue + # in multiple columns mode, we do not want to print accounts without any rows + if comparison_mode in ('single', 'multiple'): + all_comparison_lines = [comp['partners_amounts'][partner_id[1]] + for partner_id in partners_order + for comp in comparisons] + if not display_line(all_comparison_lines): + continue current_partner_amounts = current_account.partners_amounts @@ -178,9 +184,18 @@ <% partner = current_partner_amounts.get(partner_id, {}) - all_comparison_lines = [comp['partners_amounts'][partner_id] for comp in comparisons if comp['partners_amounts'].get(partner_id)] - if not partner.get('balance') and not any([line.get('balance') for line in all_comparison_lines]): - continue + # in single mode, we have to display all the partners + # even if their balance is 0.0 because the initial balance + # should match with the previous year closings + + # in multiple columns mode, we do not want to print partners + # which have a balance at 0.0 in each comparison column + if comparison_mode in ('single', 'multiple'): + all_comparison_lines = [comp['partners_amounts'][partner_id] + for comp in comparisons + if comp['partners_amounts'].get(partner_id)] + if not display_line(all_comparison_lines): + continue total_initial_balance += partner.get('init_balance', 0.0) total_debit += partner.get('debit', 0.0) diff --git a/account_financial_report_webkit/report/templates/account_report_partners_ledger.mako b/account_financial_report_webkit/report/templates/account_report_partners_ledger.mako index b651df3d..9182b7ed 100644 --- a/account_financial_report_webkit/report/templates/account_report_partners_ledger.mako +++ b/account_financial_report_webkit/report/templates/account_report_partners_ledger.mako @@ -79,7 +79,7 @@ %>
${account.code} - ${account.name}
- + %for partner_name, p_id, p_ref, p_name in account.partners_order: <% total_debit = 0.0 @@ -88,7 +88,7 @@ cumul_balance_curr = 0.0 part_cumul_balance = 0.0 - part_cumul_balance_curr = 0.0 + part_cumul_balance_curr = 0.0 %>