Commit f3bebea3 authored by Jérome Perrin's avatar Jérome Perrin

Extend grouping_reference with grouping_date

The grouping date is a property representing the date when this grouping is
effective.
In erp5_accounting, when setting a grouping reference, the grouping date will
be set to the latest date of grouped line. When running reports with
"omit_grouping_reference", lines that are grouped after the end date of the
report will still be displayed.

SQLCatalog structure changed, and can be updated with:
alter table catalog add column grouping_date datetime after grouping_reference;

You might also want to set a grouping date on movements with a grouping
reference in the migration.
parent c9febbef
......@@ -54,13 +54,12 @@
"""Get the report sections for general ledger\n
"""\n
from Products.ZSQLCatalog.SQLCatalog import Query\n
from Products.ZSQLCatalog.SQLCatalog import Query, ComplexQuery\n
from Products.ERP5Form.Report import ReportSection\n
portal = context.portal_url.getPortalObject()\n
request = portal.REQUEST\n
cat_tool = portal.portal_categories\n
sim_tool = portal.portal_simulation\n
Base_translateString = context.Base_translateString\n
Base_translateString = portal.Base_translateString\n
\n
at_date = request[\'at_date\']\n
section_category = request[\'section_category\']\n
......@@ -133,6 +132,17 @@ if mirror_section:\n
\n
default_selection_params = params.copy()\n
\n
# if user request report without grouping reference, don\'t show accounts that only have grouped lines in the period.\n
if request.get(\'omit_grouping_reference\', False):\n
if at_date:\n
params[\'grouping_query\'] = ComplexQuery(\n
Query(grouping_reference=None),\n
Query(grouping_date=at_date, range="min"),\n
operator="OR")\n
else:\n
params[\'grouping_reference\'] = None\n
\n
\n
analytic_column_list = ()\n
if hide_analytic:\n
default_selection_params[\'group_by\'] = ( \'explanation_uid\',\n
......@@ -197,7 +207,7 @@ def getFullAccountName(account_info):\n
\n
\n
# look at inventories to decide which sections will be shown\n
balance_sheet_account_type_list = [c[0] for c in \n
balance_sheet_account_type_list = [c[0] for c in\n
cat_tool.account_type.asset.getCategoryChildItemList(base=1, is_self_excluded=False, display_none_category=False ) + \\\n
cat_tool.account_type.equity.getCategoryChildItemList(base=1, is_self_excluded=False, display_none_category=False) + \\\n
cat_tool.account_type.liability.getCategoryChildItemList(base=1, is_self_excluded=False, display_none_category=False) ]\n
......
......@@ -55,6 +55,7 @@
"""Reset the grouping reference after a copy & paste.\n
"""\n
context.setGroupingReference(None)\n
context.setGroupingDate(None)\n
]]></string> </value>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>"""This script is a placeholder for projects to implement extra constraint to prevent grouping of accounting transaction lines.\n
Note that the sequence of letters will still remain unique for section, mirror_section and node, regardless of extra grouping parameters.\n
\n
For instance, we can refuse to group together lines for different order by returning the reference of the order in that script.\n
\n
The returned value must be hashable.\n
"""\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>source=True</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>AccountingTransactionLine_getGroupingExtraParameterList</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -90,11 +90,12 @@ line_list = portal.portal_simulation.getMovementHistoryList(\n
mirror_section_uid=mirror_section_uid)\n
\n
# If the group is still valid, we may want to keep it as is.\n
if round(sum([(l.total_price or 0) for l in line_list]), precision) == 0 and keep_if_valid_group:\n
if keep_if_valid_group and round(sum([(l.total_price or 0) for l in line_list]), precision) == 0:\n
return\n
\n
\n
for line in line_list:\n
line.setGroupingReference(None)\n
line.setGroupingDate(None)\n
\n
return line_list\n
</string> </value>
......
......@@ -97,6 +97,7 @@
<string>my_source_credit</string>
<string>my_resource</string>
<string>my_grouping_reference</string>
<string>my_grouping_date</string>
</list>
</value>
</item>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ProxyField" module="Products.ERP5Form.ProxyField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>delegated_list</string> </key>
<value>
<list>
<string>description</string>
<string>editable</string>
<string>title</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>my_grouping_date</string> </value>
</item>
<item>
<key> <string>message_values</string> </key>
<value>
<dictionary>
<item>
<key> <string>external_validator_failed</string> </key>
<value> <string>The input failed the external validator.</string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>overrides</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>tales</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>editable</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_date_time_field</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewFieldLibrary</string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string>Click to edit the target</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Grouping Date</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -97,6 +97,7 @@
<string>my_destination_credit</string>
<string>my_resource</string>
<string>my_grouping_reference</string>
<string>my_grouping_date</string>
</list>
</value>
</item>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ProxyField" module="Products.ERP5Form.ProxyField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>delegated_list</string> </key>
<value>
<list>
<string>description</string>
<string>editable</string>
<string>title</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>my_grouping_date</string> </value>
</item>
<item>
<key> <string>message_values</string> </key>
<value>
<dictionary>
<item>
<key> <string>external_validator_failed</string> </key>
<value> <string>The input failed the external validator.</string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>overrides</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>tales</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>editable</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_date_time_field</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewFieldLibrary</string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string>Click to edit the target</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Grouping Date</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -50,17 +50,18 @@
</item>
<item>
<key> <string>_body</string> </key>
<value> <string encoding="cdata"><![CDATA[
"""Guess a grouping references for lines whose uids are passed as\n
<value> <string>"""Guess a grouping references for lines whose uids are passed as\n
accounting_transaction_line_uid_list.\n
If accounting_transaction_line_uid_list is not passed, this script assumes that\n
it\'s called on the context of an accounting transaction and it guess the group\n
of accounting transaction using causality relations.\n
it\'s called on the context of an accounting transaction and it guess the grouping\n
of related accounting transactions using causality.\n
"""\n
\n
# this dict associates (node, section, mirror_section) to a list of\n
# accounting lines info (ie total_price and path).\n
from Products.ERP5Type.Utils import int2letter\n
\n
# this dict associates (node, section, mirror_section,\n
# extra_grouping_parameter) to a list of\n
# accounting lines info (total_price, date and path).\n
lines_per_node = {}\n
\n
portal = context.getPortalObject()\n
......@@ -69,15 +70,6 @@ ctool = portal.portal_catalog\n
allow_grouping_with_different_quantity = portal.portal_preferences.getPreference(\n
\'preferred_grouping_with_different_quantities\', 0)\n
\n
def int2letter(i):\n
"""Convert an integer to letters, to use as a grouping reference code.\n
A, B, C ..., Z, AA, AB, ..., AZ, BA, ..., ZZ, AAA ...\n
"""\n
if i < 26:\n
return (chr(i + ord(\'A\')))\n
d, m = divmod(i, 26)\n
return int2letter(d - 1) + int2letter(m)\n
\n
\n
accounting_transaction_line_value_list = []\n
if accounting_transaction_line_uid_list is None:\n
......@@ -107,8 +99,11 @@ for line in accounting_transaction_line_value_list:\n
lines_per_node.setdefault(\n
(line.getSource(portal_type=\'Account\'),\n
section_relative_url,\n
line.getDestinationSection(), ), []).append(\n
line.getDestinationSection(),\n
line.AccountingTransactionLine_getGroupingExtraParameterList(source=True),\n
), []).append(\n
dict(total_price=line.getSourceInventoriatedTotalAssetPrice() or 0,\n
date=line.getStartDate(),\n
path=line.getRelativeUrl()))\n
else:\n
section_relative_url = None\n
......@@ -121,12 +116,15 @@ for line in accounting_transaction_line_value_list:\n
lines_per_node.setdefault(\n
(line.getDestination(portal_type=\'Account\'),\n
section_relative_url,\n
line.getSourceSection(), ), []).append(\n
line.getSourceSection(),\n
line.AccountingTransactionLine_getGroupingExtraParameterList(source=False),\n
), []).append(\n
dict(total_price=line.getDestinationInventoriatedTotalAssetPrice() or 0,\n
date=line.getStopDate(),\n
path=line.getRelativeUrl()))\n
\n
changed_lines = []\n
for (node, section, mirror_section), line_info_list in lines_per_node.items():\n
changed_line_list = []\n
for (node, section, mirror_section, extra_parameter), line_info_list in lines_per_node.items():\n
if node is None:\n
continue\n
total_price = sum([l[\'total_price\'] for l in line_info_list])\n
......@@ -143,20 +141,22 @@ for (node, section, mirror_section), line_info_list in lines_per_node.items():\n
grouping_reference = portal.portal_ids.generateNewId(id_generator=\'uid\',\n
id_group=id_group,\n
default=previous_default + 1)\n
\n
\n
# convert from int to letters\n
string_reference = int2letter(grouping_reference)\n
\n
# get the grouping date\n
date = max([line[\'date\'] for line in line_info_list])\n
\n
for line in line_info_list:\n
line_obj = portal.restrictedTraverse(line[\'path\'])\n
line_obj.setGroupingReference(string_reference)\n
line_obj.setGroupingDate(date)\n
line_obj.reindexObject(activate_kw=dict(tag=\'accounting_grouping_reference\'))\n
changed_lines.append(line[\'path\'])\n
changed_line_list.append(line[\'path\'])\n
\n
return changed_lines\n
]]></string> </value>
return changed_line_list\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
......
......@@ -75,6 +75,9 @@ Here, a group of movement means:\n
mirror_section_uid is the same\n
node_uid is the same\n
grouping_reference is the same\n
\n
XXX now that grouping_date exists, this script will become useless.\n
\n
</dtml-comment>\n
\n
( SELECT catalog.path as path,\n
......
......@@ -52,7 +52,7 @@
<key> <string>_body</string> </key>
<value> <string encoding="cdata"><![CDATA[
from Products.ZSQLCatalog.SQLCatalog import Query\n
from Products.ZSQLCatalog.SQLCatalog import Query, ComplexQuery\n
from Products.ERP5Type.Message import translateString\n
from Products.ERP5Type.Log import log\n
portal = context.getPortalObject()\n
......@@ -141,6 +141,15 @@ period_start_date = params.pop(\'period_start_date\', None)\n
if is_pl_account and not from_date:\n
from_date = period_start_date\n
\n
if portal.portal_selections.getSelectionParamsFor(selection_name).get(\'hide_grouping\'):\n
if params.get(\'at_date\'):\n
params[\'grouping_query\'] = ComplexQuery(\n
Query(grouping_reference=None),\n
Query(grouping_date=params[\'at_date\'], range="min"),\n
operator="OR")\n
else:\n
params[\'grouping_reference\'] = None\n
\n
if from_date or is_pl_account:\n
# Create a new parameter list to get the previous balance\n
get_inventory_kw = params.copy()\n
......@@ -228,8 +237,6 @@ if from_date or is_pl_account:\n
previous_balance.edit(Movement_getExplanationTitle=\'\')\n
\n
new_result = [previous_balance]\n
if context.portal_selections.getSelectionParamsFor(selection_name).get(\'hide_grouping\'):\n
params[\'where_expression\'] = \'catalog.grouping_reference is NULL\'\n
new_result.extend(\n
portal.portal_simulation.getMovementHistoryList(\n
from_date=from_date,\n
......@@ -242,9 +249,6 @@ if from_date or is_pl_account:\n
**params))\n
return new_result\n
\n
if context.portal_selections.getSelectionParamsFor(selection_name).get(\'hide_grouping\'):\n
params[\'where_expression\'] = \'catalog.grouping_reference is NULL\'\n
\n
# We try not to convert to a list, hence the copy & paste\n
return portal.portal_simulation.getMovementHistoryList(\n
from_date=from_date,\n
......
1504
\ No newline at end of file
1505
\ No newline at end of file
......@@ -131,3 +131,12 @@ class AccountingTransactionLine(DeliveryLine):
# directly from the URL, that's why this method is without docstring.
self._baseSetGroupingReference(value)
self.reindexObject()
security.declareProtected(Permissions.AccessContentsInformation,
'setGroupingDate')
def setGroupingDate(self, value):
# Sets the grouping date.
# See also setGroupingReference.
self._baseSetGroupingDate(value)
self.reindexObject()
......@@ -2,6 +2,7 @@
<key>alarm.alarm_date</key>
<key>alarm_date</key>
<key>catalog.creation_date</key>
<key>catalog.grouping_date</key>
<key>catalog.modification_date</key>
<key>creation_date</key>
<key>date</key>
......@@ -13,6 +14,7 @@
<key>delivery.stop_date_range_min</key>
<key>effective_date</key>
<key>expiration_date</key>
<key>grouping_date</key>
<key>inventory.date</key>
<key>inventory_stock.date</key>
<key>inventory_stock.mirror_date</key>
......
......@@ -38,6 +38,7 @@ getEventState\r\n
getImmobilisationState\r\n
getReference\r\n
getGroupingReference\r\n
getGroupingDate\r\n
getSourceReference\r\n
getDestinationReference\r\n
getStringIndex\r\n
......@@ -89,7 +90,7 @@ REPLACE INTO\n
catalog\n
(`uid`, `security_uid`, `owner`, `viewable_owner`, `path`, `relative_url`, `parent_uid`, `id`, `description`, `title`, `meta_type`,\n
`portal_type`, `opportunity_state`, `corporate_registration_code`, `ean13_code`, `validation_state`, `simulation_state`,\n
`causality_state`, `invoice_state`, `payment_state`, `event_state`, `immobilisation_state`, `reference`, `grouping_reference`,\n
`causality_state`, `invoice_state`, `payment_state`, `event_state`, `immobilisation_state`, `reference`, `grouping_reference`, `grouping_date`,\n
`source_reference`, `destination_reference`, `string_index`, `int_index`, `float_index`, `has_cell_content`, `creation_date`,\n
`modification_date`)\n
VALUES\n
......@@ -119,6 +120,7 @@ VALUES\n
<dtml-sqlvar expr="getImmobilisationState[loop_item]" type="string" optional>,\n
<dtml-sqlvar expr="getReference[loop_item]" type="string" optional>,\n
<dtml-sqlvar expr="getGroupingReference[loop_item]" type="string" optional>,\n
<dtml-sqlvar expr="getGroupingDate[loop_item]" type="datetime" optional>,\n
<dtml-sqlvar expr="getSourceReference[loop_item]" type="string" optional>,\n
<dtml-sqlvar expr="getDestinationReference[loop_item]" type="string" optional>,\n
<dtml-sqlvar expr="getStringIndex[loop_item]" type="string" optional>,\n
......
......@@ -87,6 +87,7 @@ CREATE TABLE `catalog` (\n
`immobilisation_state` varchar(255) default \'\',\n
`reference` varchar(255) binary default \'\',\n
`grouping_reference` varchar(255) default \'\',\n
`grouping_date` datetime,\n
`source_reference` varchar(255) default \'\',\n
`destination_reference` varchar(255) default \'\',\n
`string_index` varchar(255),\n
......
233
\ No newline at end of file
234
\ No newline at end of file
......@@ -3,6 +3,8 @@ alarm_date
catalog.creation_date
catalog.modification_date
creation_date
grouping_date
catalog.grouping_date
date
delivery.start_date
delivery.start_date_range_max
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Standard Property" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_local_properties</string> </key>
<value>
<tuple>
<dictionary>
<item>
<key> <string>id</string> </key>
<value> <string>mode</string> </value>
</item>
<item>
<key> <string>type</string> </key>
<value> <string>string</string> </value>
</item>
</dictionary>
</tuple>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>elementary_type/date</string>
</tuple>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>The date when the grouping reference is effective.</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>grouping_date_property</string> </value>
</item>
<item>
<key> <string>mode</string> </key>
<value> <string>w</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Standard Property</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
54
\ No newline at end of file
55
\ No newline at end of file
......@@ -2813,12 +2813,15 @@ class TestTransactions(AccountingTestCase):
line = accounting_transaction.newContent(
id = 'line_with_grouping_reference',
grouping_reference='A',
grouping_date=DateTime(),
portal_type=transaction_to_line_mapping[portal_type])
cp = accounting_module.manage_copyObjects(ids=[accounting_transaction.getId()])
copy_id = accounting_module.manage_pasteObjects(cp)[0]['new_id']
self.failIf(accounting_module[copy_id]\
.line_with_grouping_reference.getGroupingReference())
self.failIf(accounting_module[copy_id]\
.line_with_grouping_reference.getGroupingDate())
def test_AccountingTransaction_lineResetGroupingReference(self):
invoice = self._makeOne(
......@@ -2829,6 +2832,7 @@ class TestTransactions(AccountingTestCase):
dict(source_value=self.account_module.receivable,
source_credit=100,
id='line_with_grouping_reference',
grouping_date=DateTime(),
grouping_reference='A'),))
invoice_line = invoice.line_with_grouping_reference
......@@ -2840,6 +2844,7 @@ class TestTransactions(AccountingTestCase):
dict(source_value=self.account_module.goods_sales,
source_credit=100,
id='line_with_grouping_reference',
grouping_date=DateTime(),
grouping_reference='A'),))
other_account_line = other_account_invoice.line_with_grouping_reference
......@@ -2851,6 +2856,7 @@ class TestTransactions(AccountingTestCase):
dict(source_value=self.account_module.receivable,
source_credit=100,
id='line_with_grouping_reference',
grouping_date=DateTime(),
grouping_reference='A'),))
other_section_line = other_section_invoice.line_with_grouping_reference
......@@ -2862,6 +2868,7 @@ class TestTransactions(AccountingTestCase):
dict(source_value=self.account_module.receivable,
source_credit=100,
id='line_with_grouping_reference',
grouping_date=DateTime(),
grouping_reference='B'),))
other_letter_line = other_letter_invoice.line_with_grouping_reference
......@@ -2874,6 +2881,7 @@ class TestTransactions(AccountingTestCase):
lines=(dict(source_value=self.account_module.receivable,
id='line_with_grouping_reference',
grouping_reference='A',
grouping_date=DateTime(),
source_debit=100),
dict(source_value=self.account_module.bank,
source_credit=100,)))
......@@ -2883,16 +2891,21 @@ class TestTransactions(AccountingTestCase):
# ungrouped
payment_line.AccountingTransactionLine_resetGroupingReference()
self.failIf(payment_line.getGroupingReference())
self.failIf(payment_line.getGroupingDate())
self.failIf(invoice_line.getGroupingReference())
self.failIf(invoice_line.getGroupingDate())
# other lines are not touched:
self.failUnless(other_account_line.getGroupingReference())
self.failUnless(other_account_line.getGroupingDate())
self.failUnless(other_section_line.getGroupingReference())
self.failUnless(other_letter_line.getGroupingReference())
self.failUnless(other_section_line.getGroupingDate())
self.failUnless(other_letter_line.getGroupingDate())
def test_automatically_setting_grouping_reference(self):
invoice = self._makeOne(
title='First Invoice',
start_date=DateTime(2012, 1, 2),
destination_section_value=self.organisation_module.client_1,
lines=(dict(source_value=self.account_module.goods_purchase,
source_debit=100),
......@@ -2905,6 +2918,7 @@ class TestTransactions(AccountingTestCase):
title='First Invoice Payment',
portal_type='Payment Transaction',
simulation_state='delivered',
start_date=DateTime(2012, 1, 3),
causality_value=invoice,
source_payment_value=self.section.newContent(
portal_type='Bank Account'),
......@@ -2915,23 +2929,34 @@ class TestTransactions(AccountingTestCase):
dict(source_value=self.account_module.bank,
source_credit=100,)))
payment_line = payment.line_for_grouping_reference
self.failIf(invoice_line.getGroupingReference())
self.failIf(invoice_line.getGroupingDate())
self.failIf(payment_line.getGroupingReference())
self.failIf(payment_line.getGroupingDate())
# lines match, they are automatically grouped
invoice.stop()
self.failUnless(invoice_line.getGroupingReference())
self.failUnless(payment_line.getGroupingReference())
# the grouping date is set to the latest date of all grouped lines
self.assertEquals(DateTime(2012, 1, 3), invoice_line.getGroupingDate())
self.assertEquals(DateTime(2012, 1, 3), payment_line.getGroupingDate())
# when restarting, grouping is removed
invoice.restart()
self.tic()
self.failIf(invoice_line.getGroupingReference())
self.failIf(invoice_line.getGroupingDate())
self.failIf(payment_line.getGroupingReference())
self.failIf(payment_line.getGroupingDate())
# when stopping again, grouping is set again
invoice.stop()
self.failUnless(invoice_line.getGroupingReference())
self.failUnless(payment_line.getGroupingReference())
self.assertEquals(DateTime(2012, 1, 3), invoice_line.getGroupingDate())
self.assertEquals(DateTime(2012, 1, 3), payment_line.getGroupingDate())
def test_automatically_setting_grouping_reference_same_group(self):
# invoice is for section, payment is for main_section
......
......@@ -1013,6 +1013,170 @@ class TestAccountingReports(AccountingTestCase, ERP5ReportTestCase):
data_line_list[0].getColumnProperty('Movement_getSpecificReference'))
def createHideGroupingDataSet(self):
account_module = self.account_module
# before the date
self._makeOne(
portal_type='Accounting Transaction',
simulation_state='delivered',
start_date=DateTime(2006, 1, 1),
lines=(dict(source_value=account_module.equity,
source_debit=100),
dict(source_value=account_module.stocks,
source_credit=100)))
first = self._makeOne(
portal_type='Sale Invoice Transaction',
title='Grouped during period',
simulation_state='delivered',
reference='1',
destination_section_value=self.organisation_module.client_1,
start_date=DateTime(2006, 2, 2),
lines=(dict(source_value=account_module.receivable,
grouping_reference='A',
grouping_date=DateTime(2006, 2, 2),
source_debit=119.60),
dict(source_value=account_module.collected_vat,
source_credit=19.60),
dict(source_value=account_module.goods_sales,
source_credit=100.00)))
second = self._makeOne(
portal_type='Sale Invoice Transaction',
title='Grouped after period',
simulation_state='delivered',
reference='ref2',
source_reference='2',
destination_section_value=self.organisation_module.client_2,
start_date=DateTime(2006, 2, 3),
lines=(dict(source_value=account_module.receivable,
grouping_reference='B',
grouping_date=DateTime(2006, 3, 2),
source_debit=239.20),
dict(source_value=account_module.collected_vat,
source_credit=39.20),
dict(source_value=account_module.goods_sales,
source_credit=200.00)))
def testAccountStatementHideGrouping(self):
"""Simple test for hide grouping on account statement.
"""
self.createHideGroupingDataSet()
request_form = self.portal.REQUEST.form
request_form['node'] = \
self.portal.account_module.receivable.getRelativeUrl()
request_form['at_date'] = DateTime(2006, 3, 1)
request_form['section_category'] = 'group/demo_group/sub1'
request_form['section_category_strict'] = False
request_form['simulation_state'] = ['delivered']
request_form['hide_analytic'] = False
request_form['omit_grouping_reference'] = True
report_section_list = self.getReportSectionList(
self.portal.accounting_module,
'AccountModule_viewAccountStatementReport')
self.assertEquals(1, len(report_section_list))
line_list = self.getListBoxLineList(report_section_list[0])
data_line_list = [l for l in line_list if l.isDataLine()]
# we have 1 transactions, because 1st is grouped during the period.
self.assertEquals(1, len(data_line_list))
# test columns values
line = data_line_list[0]
self.assertEquals(line.column_id_list,
['Movement_getSpecificReference', 'date',
'Movement_getExplanationTitle', 'Movement_getMirrorSectionTitle',
'Movement_getExplanationReference',
'debit_price', 'credit_price', 'running_total_price'])
self.checkLineProperties(data_line_list[0],
Movement_getSpecificReference='2',
Movement_getExplanationReference='ref2',
date=DateTime(2006, 2, 3),
Movement_getExplanationTitle='Grouped after period',
Movement_getMirrorSectionTitle='Client 2',
debit_price=239.20,
credit_price=0,
running_total_price=239.20)
self.failUnless(line_list[-1].isStatLine())
self.checkLineProperties(line_list[-1],
Movement_getSpecificReference=None,
date=None,
Movement_getExplanationTitle=None,
Movement_getMirrorSectionTitle=None,
# The bottom line remain the same as when showing
# grouped lines
debit_price=358.80,
credit_price=0,
running_total_price=None)
def testGeneralLedgerHideGrouping(self):
# similar to testAccountStatementHideGrouping, but in general ledger.
self.createHideGroupingDataSet()
request_form = self.portal.REQUEST.form
request_form['from_date'] = DateTime(2006, 1, 1)
request_form['at_date'] = DateTime(2006, 3, 1)
request_form['section_category'] = 'group/demo_group'
request_form['section_category_strict'] = False
request_form['simulation_state'] = ['delivered']
request_form['hide_analytic'] = False
request_form['gap_list'] = ['my_country/my_accounting_standards/4/41']
request_form['omit_grouping_reference'] = True
report_section_list = self.getReportSectionList(
self.portal.accounting_module,
'AccountModule_viewGeneralLedgerReport')
# Except the stat, we only have one report section, because Client 1 is
# grouped in the period.
self.assertEquals(2, len(report_section_list))
self.assertEquals('41 - Receivable (Client 2)',
report_section_list[0].getTitle())
line_list = self.getListBoxLineList(report_section_list[0])
data_line_list = [l for l in line_list if l.isDataLine()]
# report layout
self.assertEquals(['Movement_getSpecificReference',
'Movement_getExplanationTitle', 'date',
'Movement_getExplanationTranslatedPortalType',
'Movement_getExplanationReference', 'Movement_getMirrorSectionTitle',
'debit_price', 'credit_price', 'running_total_price'],
data_line_list[0].column_id_list)
self.assertEquals(1, len(data_line_list))
self.checkLineProperties(data_line_list[0],
Movement_getSpecificReference='2',
Movement_getExplanationTitle='Grouped after period',
date=DateTime(2006, 2, 3),
Movement_getExplanationTranslatedPortalType='Sale Invoice Transaction',
Movement_getExplanationReference='ref2',
Movement_getMirrorSectionTitle='Client 2',
debit_price=239.20, credit_price=0, running_total_price=239.20, )
self.failUnless(line_list[-1].isStatLine())
self.checkLineProperties(line_list[-1],
Movement_getSpecificReference=None,
Movement_getExplanationTitle=None,
date=None,
Movement_getExplanationTranslatedPortalType=None,
Movement_getExplanationReference=None,
Movement_getMirrorSectionTitle=None,
debit_price=239.20, credit_price=0, )
self.assertEquals('Total', report_section_list[1].getTitle())
line_list = self.getListBoxLineList(report_section_list[1])
data_line_list = [l for l in line_list if l.isDataLine()]
# report layout
self.assertEquals(['debit_price', 'credit_price'], data_line_list[0].column_id_list)
self.assertEquals(1, len(data_line_list))
# The bottom line remain the same as when showing grouped lines
self.checkLineProperties(data_line_list[0], debit_price=358.80, credit_price=0)
def testAccountStatementFromDateDetailedSummary(self):
# Detailed from date summary shows all lines corresponding to the balance
# at the beginning of the period.
......
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