From ed21149a5f66c37d3e779442e5108336c71c062d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9rome=20Perrin?= <jerome@nexedi.com> Date: Mon, 28 Jul 2014 15:32:02 +0200 Subject: [PATCH] Accounting: Fix bug with closing period when all accounts have 0 balance --- ...ountingPeriod_createBalanceTransaction.xml | 30 +++++++++- bt5/erp5_accounting/bt/revision | 2 +- product/ERP5/tests/testAccounting.py | 56 +++++++++++++++++++ 3 files changed, 86 insertions(+), 2 deletions(-) diff --git a/bt5/erp5_accounting/SkinTemplateItem/portal_skins/erp5_accounting/AccountingPeriod_createBalanceTransaction.xml b/bt5/erp5_accounting/SkinTemplateItem/portal_skins/erp5_accounting/AccountingPeriod_createBalanceTransaction.xml index 72ba82c5db..37276ddf3d 100644 --- a/bt5/erp5_accounting/SkinTemplateItem/portal_skins/erp5_accounting/AccountingPeriod_createBalanceTransaction.xml +++ b/bt5/erp5_accounting/SkinTemplateItem/portal_skins/erp5_accounting/AccountingPeriod_createBalanceTransaction.xml @@ -158,7 +158,17 @@ for section in section_list:\n precision=section_currency_precision,\n portal_type=portal.getPortalAccountingMovementTypeList(),\n at_date=at_date.latestTime(),)\n - \n + \n + # Calculate the sum of profit and loss accounts balances for that period.\n + # This must match the difference between assets, liability and equity accounts.\n + profit_and_loss_accounts_balance = portal.portal_simulation.getInventoryAssetPrice(\n + from_date=context.getStartDate(),\n + node_category=profit_and_loss_node_category_list,\n + **inventory_param_dict)\n + selected_profit_and_loss_account_balance = portal.portal_simulation.getInventoryAssetPrice(\n + node=profit_and_loss_account,\n + **inventory_param_dict)\n + \n section_currency_uid = context.getParentValue().getPriceCurrencyUid()\n \n profit_and_loss_quantity = 0\n @@ -300,8 +310,26 @@ for section in section_list:\n \n if balance_transaction is None:\n # we did not have any transaction for this section\n + \n + # One possible corner case is that we have only transactions that brings\n + # the balance of all balance sheets accounts to 0. In this case we want to\n + # create a balance transaction that notes that the current balance of profit\n + # and loss account is 0, so that the delta gets indexed. \n + if profit_and_loss_accounts_balance:\n + balance_transaction = createBalanceTransaction(section)\n + balance_transaction.newContent(\n + activate_kw=activate_kw,\n + portal_type=\'Balance Transaction Line\',\n + destination=profit_and_loss_account,\n + quantity=0)\n + balance_transaction.stop()\n + balance_transaction.deliver()\n continue\n \n + assert roundCurrency(profit_and_loss_accounts_balance, section_currency) == (\n + - roundCurrency(selected_profit_and_loss_account_balance, section_currency)\n + - roundCurrency(profit_and_loss_quantity, section_currency))\n + \n # add a final line for p&l\n balance_transaction.newContent(\n id=\'%03d\' % (line_count + 1),\n diff --git a/bt5/erp5_accounting/bt/revision b/bt5/erp5_accounting/bt/revision index a907bf0316..139fc46884 100644 --- a/bt5/erp5_accounting/bt/revision +++ b/bt5/erp5_accounting/bt/revision @@ -1 +1 @@ -1571 \ No newline at end of file +1572 \ No newline at end of file diff --git a/product/ERP5/tests/testAccounting.py b/product/ERP5/tests/testAccounting.py index 3bc8a6e0fc..0550d0d840 100644 --- a/product/ERP5/tests/testAccounting.py +++ b/product/ERP5/tests/testAccounting.py @@ -1854,6 +1854,62 @@ class TestClosingPeriod(AccountingTestCase): balance_transaction.reindexObject() self.tic() + def test_BalanceTransactionWhenProfitAndLossBalanceIsZero(self): + # The case of a balance transaction after all accounts have a 0 balance. + period1 = self.section.newContent(portal_type='Accounting Period') + period1.setStartDate(DateTime(2006, 1, 1)) + period1.setStopDate(DateTime(2006, 12, 31)) + period2 = self.section.newContent(portal_type='Accounting Period') + period2.setStartDate(DateTime(2007, 1, 1)) + period2.setStopDate(DateTime(2007, 12, 31)) + pl = self.portal.account_module.newContent( + portal_type='Account', + account_type='equity') + + transaction1 = self._makeOne( + start_date=DateTime(2006, 1, 1), + portal_type='Sale Invoice Transaction', + destination_section_value=self.organisation_module.client_1, + simulation_state='delivered', + lines=(dict(source_value=self.account_module.receivable, + source_debit=100), + dict(source_value=self.account_module.goods_sales, + source_credit=100))) + self.tic() + + period1.AccountingPeriod_createBalanceTransaction( + profit_and_loss_account=pl.getRelativeUrl()) + year_1_accounting_transaction_list = self.accounting_module.contentValues() + self.assertEqual(2, len(year_1_accounting_transaction_list)) + self.tic() + + transaction2 = self._makeOne( + start_date=DateTime(2007, 1, 1), + portal_type='Sale Invoice Transaction', + destination_section_value=self.organisation_module.client_1, + simulation_state='delivered', + lines=(dict(source_value=self.account_module.receivable, + source_debit=-100), + dict(source_value=self.account_module.goods_sales, + source_credit=-100))) + self.tic() + + period2.AccountingPeriod_createBalanceTransaction( + profit_and_loss_account=pl.getRelativeUrl()) + accounting_transaction_list = self.accounting_module.contentValues() + self.assertEqual(4, len(accounting_transaction_list)) + self.tic() + + balance_transaction, = [t for t in accounting_transaction_list if t not in + year_1_accounting_transaction_list and t != transaction2] + # Maybe we want to add line for each account in that case ? + line, = balance_transaction.contentValues() + + self.assertEquals(line.getDestinationValue(), pl) + self.assertEquals(line.getQuantity(), 0) + self.assertEquals(line.getDestinationTotalAssetPrice(), None) + + def test_InventoryIndexingNodeAndMirrorSection(self): # Balance Transactions are indexed as Inventories. transaction1 = self._makeOne( -- 2.30.9