Commit 48c20c8d authored by Jérome Perrin's avatar Jérome Perrin

accounting: fix GL problem with organisations member of multiple selected roles

This fixes #20170313-5DDBB0 (partially, but I think it's enough)

 ... update. It's not enough see
https://nexedi.erp5.net/test_result_module/20170313-4DA9CA7B/59
this only works for payable / receiveable accounts.
In reality, the number of mirror_section_uid is potentially very large
(think role/client with thousands of individual customer), so that
approach to use getInventoryList(group_by_mirror_section=True) to
collect all mirror section uids seems wrong to me now.
parent aa66b679
......@@ -210,8 +210,13 @@ if gap_list or gap_root:
if mirror_section_category_list:
params['mirror_section_category'] = mirror_section_category_list
default_selection_params['mirror_section_category'] =\
mirror_section_category_list
# inventory parameters for the total section
total_params = default_selection_params.copy()
# we'll append all the node used, instead of using node_category.
total_params['node_uid'] = set([])
# and the mirror_section_uid used, from mirror_section_category.
total_params['mirror_section_uid'] = set([])
report_section_list = []
......@@ -317,6 +322,8 @@ for inventory in portal.portal_simulation.getInventoryList(
addReportSection(path=inventory.node_relative_url,
selection_params=selection_params,
title=getFullAccountName(key))
total_params['node_uid'].add(inventory.node_uid)
total_params['mirror_section_uid'].add(inventory.mirror_section_uid)
# non zero balance at begining of period
for inventory in portal.portal_simulation.getInventoryList(
......@@ -345,6 +352,8 @@ for inventory in portal.portal_simulation.getInventoryList(
addReportSection(path=inventory.node_relative_url,
selection_params=selection_params,
title=getFullAccountName(key))
total_params['node_uid'].add(inventory.node_uid)
total_params['mirror_section_uid'].add(inventory.mirror_section_uid)
# group by payment
# movements in the period
......@@ -404,6 +413,22 @@ report_section_list = [x[1] for x in sorted(report_section_list, key=lambda x: x
if not export:
total_params = default_selection_params.copy()
total_params['at_date'] = at_date
total_params['node_uid'] = list(total_params['node_uid'])
mirror_section_uid = total_params.pop('mirror_section_uid')
if mirror_section_category_list:
if mirror_section_uid:
total_params['mirror_section_uid'] = list(mirror_section_uid)
else:
# mirror_section_uid was only populated if we have some receivable / payable
# accounts to group_by_mirror_section=True.
# In that case, we use mirror_section_category to apply this filter.
#
# XXX General ledgers with a mirror_section_category filter that selects some
# organisation twice and a gap filter that would not select any receivable or
# payable account still have the problem of #20170313-5DDBB0 . That said, I don't
# see the use case of such a report, so we can probably assume this will not happen.
total_params['mirror_section_category'] = mirror_section_category_list
report_section_list.append(ReportSection(
path=context.getPhysicalPath(),
title=Base_translateString("Total"),
......
......@@ -4305,6 +4305,81 @@ class TestAccountingReports(AccountingTestCase, ERP5ReportTestCase):
self.checkLineProperties(data_line_list[0], debit_price=300,
credit_price=300)
def testGeneralLedgerMirrorSectionRoleSelectedTwice(self):
# general ledger restricted to a mirror section role - edge case where the
# mirror section filter selects the same organisation twice.
# similar to createMirrorSectionRoleDataSet, but using a mirror section who
# is both supplier and client
mirror_section = self.portal.organisation_module.newContent(
title='Client and Supplier',
role_value_list=(
self.portal.portal_categories.role.client,
self.portal.portal_categories.role.supplier,
)
)
mirror_section.validate()
account_module = self.portal.account_module
self._makeOne(
portal_type='Sale Invoice Transaction',
title='Invoice to client and supplier',
source_reference='2',
reference='Is',
simulation_state='delivered',
destination_section_value=mirror_section,
start_date=DateTime(2006, 2, 2),
lines=(dict(source_value=account_module.receivable,
source_debit=300.0),
dict(source_value=account_module.goods_sales,
source_credit=300.0)))
self.tic()
request_form = self.portal.REQUEST.form
request_form['from_date'] = DateTime(2006, 1, 1)
request_form['at_date'] = DateTime(2006, 12, 31)
request_form['section_category'] = 'group/demo_group'
request_form['section_category_strict'] = False
request_form['simulation_state'] = ['delivered']
request_form['mirror_section_category_list'] = [
'role/supplier',
'role/client'
]
request_form['hide_analytic'] = False
request_form['export'] = False
report_section_list = self.getReportSectionList(
self.portal.accounting_module,
'AccountModule_viewGeneralLedgerReport')
self.assertEqual(3, len(report_section_list))
line_list = self.getListBoxLineList(report_section_list[0])
data_line_list = [l for l in line_list if l.isDataLine()]
self.assertEqual(1, len(data_line_list))
self.checkLineProperties(data_line_list[0],
Movement_getSpecificReference='2',
Movement_getExplanationTitleAndAnalytics='Invoice to client and supplier\nIs',
date=DateTime(2006, 2, 2),
debit_price=300, credit_price=0, running_total_price=300, )
self.assertTrue(line_list[-1].isStatLine())
self.checkLineProperties(line_list[-1], debit_price=300, credit_price=0)
line_list = self.getListBoxLineList(report_section_list[1])
data_line_list = [l for l in line_list if l.isDataLine()]
self.assertEqual(1, len(data_line_list))
self.checkLineProperties(data_line_list[0],
Movement_getSpecificReference='2',
Movement_getExplanationTitleAndAnalytics='Invoice to client and supplier\nIs',
date=DateTime(2006, 2, 2),
debit_price=0, credit_price=300, running_total_price=-300, )
self.assertTrue(line_list[-1].isStatLine())
self.checkLineProperties(line_list[-1], debit_price=0, credit_price=300)
line_list = self.getListBoxLineList(report_section_list[2])
data_line_list = [l for l in line_list if l.isDataLine()]
self.assertEqual(1, len(data_line_list))
self.checkLineProperties(data_line_list[0], debit_price=300,
credit_price=300)
def testProfitAndLoss(self):
# Simple test of profit and loss
self.createAccountStatementDataSet(use_two_bank_accounts=1)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment