[Erp5-report] r37282 jerome - in /erp5/trunk/products/ERP5: Document/ tests/
nobody at svn.erp5.org
nobody at svn.erp5.org
Tue Jul 27 14:43:00 CEST 2010
Author: jerome
Date: Tue Jul 27 14:42:41 2010
New Revision: 37282
URL: http://svn.erp5.org?rev=37282&view=rev
Log:
- use selected uids in getInventoryList as cell keys, this makes the "inventory
list" way of calculating consumption working properly with summary cells
- cache cell keys lookups
- support movement_strict_membership inventory axis
- add tests
Modified:
erp5/trunk/products/ERP5/Document/BudgetLine.py
erp5/trunk/products/ERP5/Document/BudgetModel.py
erp5/trunk/products/ERP5/Document/BudgetVariation.py
erp5/trunk/products/ERP5/Document/CategoryBudgetVariation.py
erp5/trunk/products/ERP5/Document/NodeBudgetVariation.py
erp5/trunk/products/ERP5/tests/testBudget.py
Modified: erp5/trunk/products/ERP5/Document/BudgetLine.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5/Document/BudgetLine.py?rev=37282&r1=37281&r2=37282&view=diff
==============================================================================
--- erp5/trunk/products/ERP5/Document/BudgetLine.py [utf8] (original)
+++ erp5/trunk/products/ERP5/Document/BudgetLine.py [utf8] Tue Jul 27 14:42:41 2010
@@ -116,14 +116,15 @@ class BudgetLine(Predicate, XMLMatrix, V
query_dict.setdefault('ignore_group_by', True)
sign = self.BudgetLine_getConsumptionSign()
+ cell_key_cache = dict()
budget_dict = dict()
for brain in self.getPortalObject().portal_simulation\
.getCurrentInventoryList(**query_dict):
+ cell_key = budget_model._getCellKeyFromInventoryListBrain(brain, self,
+ cell_key_cache=cell_key_cache)
# XXX total_quantity or total_price ??
- previous_value = budget_dict.get(
- budget_model._getCellKeyFromInventoryListBrain(brain, self), 0)
- budget_dict[budget_model._getCellKeyFromInventoryListBrain(brain, self)] = \
- previous_value + brain.total_price * sign
+ previous_value = budget_dict.get(cell_key, 0)
+ budget_dict[cell_key] = previous_value + brain.total_price * sign
return budget_dict
Modified: erp5/trunk/products/ERP5/Document/BudgetModel.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5/Document/BudgetModel.py?rev=37282&r1=37281&r2=37282&view=diff
==============================================================================
--- erp5/trunk/products/ERP5/Document/BudgetModel.py [utf8] (original)
+++ erp5/trunk/products/ERP5/Document/BudgetModel.py [utf8] Tue Jul 27 14:42:41 2010
@@ -99,10 +99,16 @@ class BudgetModel(Predicate):
for budget_variation in sorted(self.contentValues(
portal_type=self.getPortalBudgetVariationTypeList()),
key=lambda x:x.getIntIndex()):
- variation_query_dict = budget_variation.getInventoryListQueryDict(budget_line)
- # Merge group_by argument. All other arguments should not conflict
+ variation_query_dict = budget_variation.getInventoryListQueryDict(
+ budget_line)
+ # Merge group_by and select_list arguments.
+ # Other arguments should not conflict
if 'group_by' in query_dict and 'group_by' in variation_query_dict:
variation_query_dict['group_by'].extend(query_dict['group_by'])
+ if 'select_list' in query_dict \
+ and 'select_list' in variation_query_dict:
+ variation_query_dict['select_list'].extend(
+ query_dict['select_list'])
query_dict.update(variation_query_dict)
@@ -114,7 +120,8 @@ class BudgetModel(Predicate):
query_dict.setdefault('at_date', start_date_range_max.latestTime())
return query_dict
- def _getCellKeyFromInventoryListBrain(self, brain, budget_line):
+ def _getCellKeyFromInventoryListBrain(self, brain, budget_line,
+ cell_key_cache=None):
"""Compute the cell key from an inventory brain, the cell key can be used
to retrieve the budget cell in the corresponding budget line.
"""
@@ -122,8 +129,8 @@ class BudgetModel(Predicate):
for budget_variation in sorted(self.contentValues(
portal_type=self.getPortalBudgetVariationTypeList()),
key=lambda x:x.getIntIndex()):
- key = budget_variation._getCellKeyFromInventoryListBrain(brain,
- budget_line)
+ key = budget_variation._getCellKeyFromInventoryListBrain(
+ brain, budget_line, cell_key_cache=cell_key_cache)
if key:
cell_key += (key,)
return cell_key
Modified: erp5/trunk/products/ERP5/Document/BudgetVariation.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5/Document/BudgetVariation.py?rev=37282&r1=37281&r2=37282&view=diff
==============================================================================
--- erp5/trunk/products/ERP5/Document/BudgetVariation.py [utf8] (original)
+++ erp5/trunk/products/ERP5/Document/BudgetVariation.py [utf8] Tue Jul 27 14:42:41 2010
@@ -96,10 +96,12 @@ class BudgetVariation(Predicate):
"""
return {}
- def _getCellKeyFromInventoryListBrain(self, brain, budget_line):
+ def _getCellKeyFromInventoryListBrain(self, brain, budget_line,
+ cell_key_cache=None):
"""Compute the cell key from an inventory brain.
The cell key can be used to retrieve the budget cell in the corresponding
budget line using budget_line.getCell
+ A dictionnary can be passed as "cell_key_cache" to cache catalog lookups
"""
if not self.isMemberOf('budget_variation/budget_cell'):
return None
@@ -110,55 +112,30 @@ class BudgetVariation(Predicate):
base_category = self.getProperty('variation_base_category')
if not base_category:
return None
-
- movement = brain.getObject()
- # axis 'movement' is simply a category membership on movements
- if axis == 'movement':
- return movement.getDefaultAcquiredCategoryMembership(base_category,
- base=True)
-
- # is it a source brain or destination brain ?
- is_source_brain = True
- if (brain.node_uid != brain.mirror_node_uid):
- is_source_brain = (brain.node_uid == movement.getSourceUid())
- elif (brain.section_uid != brain.mirror_section_uid):
- is_source_brain = (brain.section_uid == movement.getSourceSectionUid())
- elif brain.total_quantity:
- is_source_brain = (brain.total_quantity == movement.getQuantity())
+
+ getObject = self.getPortalObject().portal_catalog.getObject
+ def getUrlFromUidNoCache(uid):
+ relative_url = getObject(uid).getRelativeUrl()
+ if relative_url.startswith('%s/' % base_category):
+ return relative_url
+ return '%s/%s' % (base_category, relative_url)
+
+ if cell_key_cache is not None:
+ def getUrlFromUidWithCache(uid):
+ try:
+ return cell_key_cache[uid]
+ except KeyError:
+ relative_url = getUrlFromUidNoCache(uid)
+ cell_key_cache[uid] = relative_url
+ return relative_url
+ getUrlFromUid = getUrlFromUidWithCache
else:
- raise NotImplementedError('Could not guess brain side')
+ getUrlFromUid = getUrlFromUidNoCache
- if axis.endswith('_category') or\
- axis.endswith('_category_strict_membership'):
- # if the axis is category, we get the node and then returns the category
- # from that node
- if axis.endswith('_category'):
- axis = axis[:-len('_category')]
- if axis.endswith('_category_strict_membership'):
- axis = axis[:-len('_category_strict_membership')]
- if is_source_brain:
- if axis == 'node':
- node = movement.getSourceValue()
- else:
- node = movement.getProperty('source_%s_value' % axis)
- else:
- if axis == 'node':
- node = movement.getDestinationValue()
- else:
- node = movement.getProperty('destination_%s_value' % axis)
- if node is not None:
- return node.getDefaultAcquiredCategoryMembership(base_category,
- base=True)
- return None
-
- # otherwise we just return the node
- if is_source_brain:
- if axis == 'node':
- return '%s/%s' % (base_category, movement.getSource())
- return '%s/%s' % (base_category,
- movement.getProperty('source_%s' % axis))
- if axis == 'node':
- return '%s/%s' % (base_category, movement.getDestination())
- return '%s/%s' % (base_category,
- movement.getProperty('destination_%s' % axis))
+ if axis == 'movement':
+ return getUrlFromUid(getattr(brain, 'default_%s_uid' % base_category))
+ elif axis == 'movement_strict_membership':
+ return getUrlFromUid(getattr(brain,
+ 'default_strict_%s_uid' % base_category))
+ return getUrlFromUid(getattr(brain, '%s_uid' % axis))
Modified: erp5/trunk/products/ERP5/Document/CategoryBudgetVariation.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5/Document/CategoryBudgetVariation.py?rev=37282&r1=37281&r2=37282&view=diff
==============================================================================
--- erp5/trunk/products/ERP5/Document/CategoryBudgetVariation.py [utf8] (original)
+++ erp5/trunk/products/ERP5/Document/CategoryBudgetVariation.py [utf8] Tue Jul 27 14:42:41 2010
@@ -95,6 +95,8 @@ class CategoryBudgetVariation(BudgetVari
# Different possible inventory axis here
if axis == 'movement':
return {'default_%s_uid' % base_category: category_uid}
+ if axis == 'movement_strict_membership':
+ return {'default_strict_%s_uid' % base_category: category_uid}
if axis in ('node', 'section', 'payment', 'function', 'project',
'mirror_section', 'mirror_node' ):
return {'%s_uid' % axis: category_uid}
@@ -117,8 +119,13 @@ class CategoryBudgetVariation(BudgetVari
query_dict = dict()
if axis == 'movement':
+ axis = 'default_%s_uid' % base_category
+ query_dict['group_by'] = [axis]
+ query_dict['select_list'] = [axis]
+ elif axis == 'movement_strict_membership':
axis = 'default_strict_%s_uid' % base_category
query_dict['group_by'] = [axis]
+ query_dict['select_list'] = [axis]
else:
query_dict['group_by_%s' % axis] = True
if axis in ('node', 'section', 'payment', 'function', 'project',
@@ -126,7 +133,7 @@ class CategoryBudgetVariation(BudgetVari
axis = '%s_uid' % axis
for category in context.getVariationCategoryList(
- base_category_list=(base_category,)):
+ base_category_list=(base_category,)):
if axis.endswith('_uid'):
category = self.getPortalObject().portal_categories\
.getCategoryUid(category)
Modified: erp5/trunk/products/ERP5/Document/NodeBudgetVariation.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5/Document/NodeBudgetVariation.py?rev=37282&r1=37281&r2=37282&view=diff
==============================================================================
--- erp5/trunk/products/ERP5/Document/NodeBudgetVariation.py [utf8] (original)
+++ erp5/trunk/products/ERP5/Document/NodeBudgetVariation.py [utf8] Tue Jul 27 14:42:41 2010
@@ -147,8 +147,11 @@ class NodeBudgetVariation(BudgetVariatio
if criterion_base_category == base_category:
if axis == 'movement':
axis = 'default_%s' % base_category
- # TODO: This is not correct if axis is a category (such as
- # section_category)
+ if axis == 'movement_strict_membership':
+ axis = 'default_strict_%s' % base_category
+ # TODO: This is not correct if axis is a category such as
+ # section_category, because getInventoryList for now does not support
+ # parameters such as section_category_uid
axis = '%s_uid' % axis
if node_url == budget_line.getRelativeUrl():
# This is the "All Other" virtual node
@@ -181,7 +184,12 @@ class NodeBudgetVariation(BudgetVariatio
query_dict = dict()
if axis == 'movement':
axis = 'default_%s_uid' % base_category
+ query_dict['select_list'] = [axis]
+ if axis == 'movement_strict_membership':
+ axis = 'default_strict_%s_uid' % base_category
+ query_dict['select_list'] = [axis]
query_dict['group_by_%s' % axis] = True
+
# TODO: This is not correct if axis is a category (such as
# section_category)
axis = '%s_uid' % axis
@@ -191,17 +199,19 @@ class NodeBudgetVariation(BudgetVariatio
return query_dict
for node_url in context.getVariationCategoryList(
- base_category_list=(base_category,)):
+ base_category_list=(base_category,)):
query_dict.setdefault(axis, []).append(
portal_categories.getCategoryValue(node_url,
base_category=base_category).getUid())
return query_dict
- def _getCellKeyFromInventoryListBrain(self, brain, budget_line):
- """Compute key from inventory brain, with support for "all others" virtual node.
+ def _getCellKeyFromInventoryListBrain(self, brain, budget_line,
+ cell_key_cache=None):
+ """Compute key from inventory brain, with support for "all others" virtual
+ node.
"""
key = BudgetVariation._getCellKeyFromInventoryListBrain(
- self, brain, budget_line)
+ self, brain, budget_line, cell_key_cache=cell_key_cache)
if self.getProperty('include_virtual_other_node'):
if key not in [x[1] for x in
self.getBudgetVariationRangeCategoryList(budget_line)]:
Modified: erp5/trunk/products/ERP5/tests/testBudget.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5/tests/testBudget.py?rev=37282&r1=37281&r2=37282&view=diff
==============================================================================
--- erp5/trunk/products/ERP5/tests/testBudget.py [utf8] (original)
+++ erp5/trunk/products/ERP5/tests/testBudget.py [utf8] Tue Jul 27 14:42:41 2010
@@ -634,11 +634,14 @@ class TestBudget(ERP5TypeTestCase):
at_date=DateTime(2000, 12, 31).latestTime(),
node_uid=[self.portal.account_module.goods_purchase.getUid(),
self.portal.account_module.fixed_assets.getUid(),],
- default_strict_product_line_uid=[product_line_1.getUid(),
+ default_product_line_uid=[product_line_1.getUid(),
product_line_1_11.getUid(),
product_line_1_12.getUid(),],
section_category=['group/demo_group'],
- group_by=['default_strict_product_line_uid'],
+ group_by=['default_product_line_uid'],
+ # select list is passed, because getInventoryList does not add
+ # group by related keys to select
+ select_list=['default_product_line_uid'],
group_by_node=True,
group_by_section_category=True,
),
@@ -668,28 +671,123 @@ class TestBudget(ERP5TypeTestCase):
self.assertEquals(
{('source/account_module/fixed_assets', 'product_line/1/1.2'): -100.0,
('source/account_module/goods_purchase', 'product_line/1/1.1'): 100.0,
- # summary line is automatically added (TODO)
-## ('source/account_module/goods_purchase', 'product_line/1'): 100.0
+ # summary lines are automatically added
+ ('source/account_module/fixed_assets', 'product_line/1'): -100.0,
+ ('source/account_module/goods_purchase', 'product_line/1'): 100.0
},
budget_line.getConsumedBudgetDict())
self.assertEquals(
{('source/account_module/fixed_assets', 'product_line/1/1.2'): -100.0,
('source/account_module/goods_purchase', 'product_line/1/1.1'): 100.0,
- # summary line is automatically added (TODO)
-## ('source/account_module/goods_purchase', 'product_line/1'): 100.0
+ ('source/account_module/fixed_assets', 'product_line/1'): -100.0,
+ ('source/account_module/goods_purchase', 'product_line/1'): 100.0
},
budget_line.getEngagedBudgetDict())
self.assertEquals(
{('source/account_module/fixed_assets', 'product_line/1/1.2'): 100.0,
('source/account_module/goods_purchase', 'product_line/1/1.1'): -98.0,
- # summary line is automatically added (TODO)
-## ('source/account_module/goods_purchase', 'product_line/1'): 98.0
- ('source/account_module/goods_purchase', 'product_line/1'): 2.0
+ ('source/account_module/fixed_assets', 'product_line/1'): 100.0,
+ ('source/account_module/goods_purchase', 'product_line/1'): -98,
},
budget_line.getAvailableBudgetDict())
+ def test_consumption_category_variation_summary(self):
+ budget_model = self.portal.budget_model_module.newContent(
+ portal_type='Budget Model')
+ budget_model.newContent(
+ portal_type='Category Budget Variation',
+ int_index=1,
+ budget_variation='budget_cell',
+ inventory_axis='section_category',
+ variation_base_category='group',)
+ budget_model.newContent(
+ portal_type='Node Budget Variation',
+ int_index=2,
+ budget_variation='budget_cell',
+ inventory_axis='node',
+ variation_base_category='source',
+ aggregate_value_list=(
+ self.portal.account_module.goods_purchase,
+ self.portal.account_module.fixed_assets,
+ ))
+ budget = self.portal.budget_module.newContent(
+ portal_type='Budget',
+ start_date_range_min=DateTime(2000, 1, 1),
+ start_date_range_max=DateTime(2000, 12, 31),
+ specialise_value=budget_model)
+
+ budget_line = budget.newContent(portal_type='Budget Line',)
+
+ # set the range, this will adjust the matrix
+ budget_line.edit(
+ variation_category_list=(
+ 'source/account_module/goods_purchase',
+ 'group/demo_group',
+ 'group/demo_group/sub1',
+ ))
+
+ form = budget_line.BudgetLine_view
+ self.portal.REQUEST.other.update(
+ dict(AUTHENTICATED_USER=getSecurityManager().getUser(),
+
+ field_membership_criterion_base_category_list=
+ form.membership_criterion_base_category_list.get_value('default'),
+ field_mapped_value_property_list=
+ form.mapped_value_property_list.get_value('default'),
+
+ field_matrixbox_quantity_cell_0_0_0="",
+ field_matrixbox_membership_criterion_category_list_cell_0_0_0=[],
+ field_matrixbox_quantity_cell_1_0_0="500",
+ field_matrixbox_membership_criterion_category_list_cell_1_0_0=[
+ 'group/demo_group/sub1',
+ 'source/account_module/goods_purchase', ],
+ ))
+ budget_line.Base_edit(form_id=form.getId())
+
+ self.assertEquals(1, len(budget_line.contentValues()))
+
+ self.assertEquals(
+ dict(from_date=DateTime(2000, 1, 1),
+ at_date=DateTime(2000, 12, 31).latestTime(),
+ node_uid=[self.portal.account_module.goods_purchase.getUid(),],
+ section_category=['group/demo_group',
+ 'group/demo_group/sub1'],
+ group_by_node=True,
+ group_by_section_category=True,
+ ),
+ budget_model.getInventoryListQueryDict(budget_line))
+
+
+ atransaction = self.portal.accounting_module.newContent(
+ portal_type='Accounting Transaction',
+ resource_value=self.portal.currency_module.euro,
+ source_section_value=self.portal.organisation_module.my_organisation,
+ start_date=DateTime(2000, 1, 2))
+ atransaction.newContent(
+ portal_type='Accounting Transaction Line',
+ source_value=self.portal.account_module.goods_purchase,
+ source_debit=100)
+ atransaction.newContent(
+ portal_type='Accounting Transaction Line',
+ source_value=self.portal.account_module.fixed_assets,
+ source_credit=100)
+ atransaction.stop()
+
+ transaction.commit()
+ self.tic()
+
+ self.assertEquals(
+ {('group/demo_group/sub1', 'source/account_module/goods_purchase'): 100.0,
+ ('group/demo_group', 'source/account_module/goods_purchase'): 100.0,},
+ budget_line.getConsumedBudgetDict())
+
+ self.assertEquals(
+ {('group/demo_group/sub1', 'source/account_module/goods_purchase'): 100.0,
+ ('group/demo_group', 'source/account_module/goods_purchase'): 100.0,},
+ budget_line.getEngagedBudgetDict())
+
def test_budget_consumption_report(self):
budget_model = self.portal.budget_model_module.newContent(
@@ -837,9 +935,316 @@ class TestBudget(ERP5TypeTestCase):
self.fail(''.join(err_list))
- # Other TODOs:
+ def test_update_summary_cell_simple(self):
+ # test the action to create or update quantity on summary cells
+ budget_model = self.portal.budget_model_module.newContent(
+ portal_type='Budget Model')
+ budget_model.newContent(
+ portal_type='Category Budget Variation',
+ int_index=1,
+ budget_variation='budget_cell',
+ inventory_axis='movement',
+ variation_base_category='product_line',)
+ budget_model.newContent(
+ portal_type='Node Budget Variation',
+ int_index=2,
+ budget_variation='budget_cell',
+ inventory_axis='node',
+ variation_base_category='source',
+ aggregate_value_list=(
+ self.portal.account_module.goods_purchase,
+ self.portal.account_module.fixed_assets,
+ ))
+ budget_model.newContent(
+ portal_type='Category Budget Variation',
+ int_index=3,
+ budget_variation='budget_cell',
+ inventory_axis='section_category',
+ variation_base_category='group',)
+
+ budget = self.portal.budget_module.newContent(
+ portal_type='Budget',
+ start_date_range_min=DateTime(2000, 1, 1),
+ start_date_range_max=DateTime(2000, 12, 31),
+ specialise_value=budget_model)
+
+ budget_line = budget.newContent(portal_type='Budget Line')
+
+ # set the range, this will adjust the matrix
+ budget_line.edit(
+ variation_category_list=(
+ 'group/demo_group',
+ 'group/demo_group/sub1',
+ 'group/demo_group/sub2',
+ 'source/account_module/goods_purchase',
+ 'source/account_module/fixed_assets',
+ 'product_line/1',
+ 'product_line/1/1.1',
+ 'product_line/1/1.2', ))
+
+ form = budget_line.BudgetLine_view
+ self.portal.REQUEST.other.update(
+ dict(AUTHENTICATED_USER=getSecurityManager().getUser(),
+
+ field_membership_criterion_base_category_list=
+ form.membership_criterion_base_category_list.get_value('default'),
+ field_mapped_value_property_list=
+ form.mapped_value_property_list.get_value('default'),
+
+ # group/demo_group
+ field_matrixbox_quantity_cell_0_0_0="",
+ field_matrixbox_membership_criterion_category_list_cell_0_0_0=[],
+ field_matrixbox_quantity_cell_1_0_0="",
+ field_matrixbox_membership_criterion_category_list_cell_1_0_0=[],
+ field_matrixbox_quantity_cell_2_0_0="",
+ field_matrixbox_membership_criterion_category_list_cell_2_0_0=[],
+ field_matrixbox_quantity_cell_0_1_0="",
+ field_matrixbox_membership_criterion_category_list_cell_0_1_0=[],
+ field_matrixbox_quantity_cell_1_1_0="",
+ field_matrixbox_membership_criterion_category_list_cell_1_1_0=[],
+ # This is a summary cell, but we set a manual value.
+ field_matrixbox_quantity_cell_2_1_0="100",
+ field_matrixbox_membership_criterion_category_list_cell_2_1_0=[
+ 'product_line/1/1.2',
+ 'source/account_module/fixed_assets',
+ 'group/demo_group',
+ ],
+
+ # group/demo_group/sub1
+ field_matrixbox_quantity_cell_0_0_1="",
+ field_matrixbox_membership_criterion_category_list_cell_0_0_1=[],
+ field_matrixbox_quantity_cell_1_0_1="1",
+ field_matrixbox_membership_criterion_category_list_cell_1_0_1=[
+ 'product_line/1/1.1',
+ 'source/account_module/goods_purchase',
+ 'group/demo_group/sub1',
+ ],
+ field_matrixbox_quantity_cell_2_0_1="2",
+ field_matrixbox_membership_criterion_category_list_cell_2_0_1=[
+ 'product_line/1/1.2',
+ 'source/account_module/goods_purchase',
+ 'group/demo_group/sub1',
+ ],
+ field_matrixbox_quantity_cell_0_1_1="",
+ field_matrixbox_membership_criterion_category_list_cell_0_1_1=[],
+ field_matrixbox_quantity_cell_1_1_1="3",
+ field_matrixbox_membership_criterion_category_list_cell_1_1_1=[
+ 'product_line/1/1.1',
+ 'source/account_module/fixed_assets',
+ 'group/demo_group/sub1',
+ ],
+ field_matrixbox_quantity_cell_2_1_1="4",
+ field_matrixbox_membership_criterion_category_list_cell_2_1_1=[
+ 'product_line/1/1.2',
+ 'source/account_module/fixed_assets',
+ 'group/demo_group/sub1',
+ ],
+
+ # group/demo_group/sub2
+ field_matrixbox_quantity_cell_0_0_2="",
+ field_matrixbox_membership_criterion_category_list_cell_0_0_2=[],
+ # we only have 1 cell here
+ field_matrixbox_quantity_cell_1_0_2="5",
+ field_matrixbox_membership_criterion_category_list_cell_1_0_2=[
+ 'product_line/1/1.1',
+ 'source/account_module/goods_purchase',
+ 'group/demo_group/sub2',
+ ],
+ field_matrixbox_quantity_cell_2_0_2="",
+ field_matrixbox_membership_criterion_category_list_cell_2_0_2=[],
+ # we have no cells here
+ field_matrixbox_quantity_cell_0_1_2="",
+ field_matrixbox_membership_criterion_category_list_cell_0_1_2=[],
+ field_matrixbox_quantity_cell_1_1_2="",
+ field_matrixbox_membership_criterion_category_list_cell_1_1_2=[],
+ field_matrixbox_quantity_cell_2_1_2="",
+ field_matrixbox_membership_criterion_category_list_cell_2_1_2=[],
+ ))
+
+ budget_line.Base_edit(form_id=form.getId())
+
+ self.assertEquals(6, len(budget_line.contentValues()))
+
+ budget_line.BudgetLine_setQuantityOnSummaryCellList()
+
+ # summary cells have been created:
+ self.assertEquals(14, len(budget_line.contentValues()))
+
+ # those cells are aggregating
+ self.assertEquals(1+2, budget_line.getCell(
+ 'product_line/1',
+ 'source/account_module/goods_purchase',
+ 'group/demo_group/sub1',).getQuantity())
+ self.assertEquals(4+3, budget_line.getCell(
+ 'product_line/1',
+ 'source/account_module/fixed_assets',
+ 'group/demo_group/sub1',).getQuantity())
+ self.assertEquals(1+5, budget_line.getCell(
+ 'product_line/1/1.1',
+ 'source/account_module/goods_purchase',
+ 'group/demo_group',).getQuantity())
+ self.assertEquals(1+2+5, budget_line.getCell(
+ 'product_line/1',
+ 'source/account_module/goods_purchase',
+ 'group/demo_group',).getQuantity())
+
+ # the cell that we have modified is erased
+ self.assertEquals(4, budget_line.getCell(
+ 'product_line/1/1.2',
+ 'source/account_module/fixed_assets',
+ 'group/demo_group',).getQuantity())
+
+ # test all cells for complete coverage
+ self.assertEquals(6, budget_line.getCell(
+ 'product_line/1/1.1',
+ 'source/account_module/goods_purchase',
+ 'group/demo_group',).getQuantity())
+ self.assertEquals(2, budget_line.getCell(
+ 'product_line/1/1.2',
+ 'source/account_module/goods_purchase',
+ 'group/demo_group',).getQuantity())
+ self.assertEquals(3+4, budget_line.getCell(
+ 'product_line/1',
+ 'source/account_module/fixed_assets',
+ 'group/demo_group',).getQuantity())
+ self.assertEquals(3, budget_line.getCell(
+ 'product_line/1/1.1',
+ 'source/account_module/fixed_assets',
+ 'group/demo_group',).getQuantity())
+ self.assertEquals(4, budget_line.getCell(
+ 'product_line/1/1.2',
+ 'source/account_module/fixed_assets',
+ 'group/demo_group',).getQuantity())
+ self.assertEquals(5, budget_line.getCell(
+ 'product_line/1',
+ 'source/account_module/goods_purchase',
+ 'group/demo_group/sub2',).getQuantity())
+
+ # change a cell quantity and call again
+ budget_cell = budget_line.getCell(
+ 'product_line/1/1.2',
+ 'source/account_module/goods_purchase',
+ 'group/demo_group/sub1')
+ self.assertNotEquals(None, budget_cell)
+ self.assertEquals(2, budget_cell.getQuantity())
+ budget_cell.setQuantity(6)
+
+ budget_line.BudgetLine_setQuantityOnSummaryCellList()
+ self.assertEquals(14, len(budget_line.contentValues()))
+
+ self.assertEquals(1+6, budget_line.getCell(
+ 'product_line/1',
+ 'source/account_module/goods_purchase',
+ 'group/demo_group/sub1',).getQuantity())
+ self.assertEquals(4+3, budget_line.getCell(
+ 'product_line/1',
+ 'source/account_module/fixed_assets',
+ 'group/demo_group/sub1',).getQuantity())
+ self.assertEquals(1+5, budget_line.getCell(
+ 'product_line/1/1.1',
+ 'source/account_module/goods_purchase',
+ 'group/demo_group',).getQuantity())
+ self.assertEquals(1+6+5, budget_line.getCell(
+ 'product_line/1',
+ 'source/account_module/goods_purchase',
+ 'group/demo_group',).getQuantity())
+
+
+ def test_update_summary_cell_non_strict_and_second_summary(self):
+ # test the action to create or update quantity on summary cells, variation
+ # which are strict are not updated, and multiple level summary does not
+ # aggregate again intermediate summaries
+ budget_model = self.portal.budget_model_module.newContent(
+ portal_type='Budget Model')
+ budget_model.newContent(
+ portal_type='Category Budget Variation',
+ int_index=1,
+ budget_variation='budget_cell',
+ inventory_axis='movement_strict_membership',
+ variation_base_category='product_line',)
+ budget_model.newContent(
+ portal_type='Node Budget Variation',
+ int_index=2,
+ budget_variation='budget_cell',
+ inventory_axis='node',
+ variation_base_category='source',
+ aggregate_value_list=(
+ self.portal.account_module.goods_purchase,
+ self.portal.account_module.fixed_assets,
+ ))
+ budget_model.newContent(
+ portal_type='Category Budget Variation',
+ int_index=3,
+ budget_variation='budget_cell',
+ inventory_axis='node_category',
+ variation_base_category='account_type',)
+
+ budget = self.portal.budget_module.newContent(
+ portal_type='Budget',
+ start_date_range_min=DateTime(2000, 1, 1),
+ start_date_range_max=DateTime(2000, 12, 31),
+ specialise_value=budget_model)
- # section_category & summary
+ budget_line = budget.newContent(portal_type='Budget Line')
+
+ # set the range, this will adjust the matrix
+ budget_line.edit(
+ variation_category_list=(
+ 'account_type/asset',
+ 'account_type/asset/cash',
+ 'account_type/asset/cash/bank',
+ 'source/account_module/goods_purchase',
+ 'product_line/1',
+ 'product_line/1/1.1', ))
+
+ form = budget_line.BudgetLine_view
+ self.portal.REQUEST.other.update(
+ dict(AUTHENTICATED_USER=getSecurityManager().getUser(),
+
+ field_membership_criterion_base_category_list=
+ form.membership_criterion_base_category_list.get_value('default'),
+ field_mapped_value_property_list=
+ form.mapped_value_property_list.get_value('default'),
+ field_matrixbox_quantity_cell_0_0_0="",
+ field_matrixbox_membership_criterion_category_list_cell_0_0_0=[],
+ field_matrixbox_quantity_cell_1_0_0="",
+ field_matrixbox_membership_criterion_category_list_cell_1_0_0=[],
+ field_matrixbox_quantity_cell_0_0_1="",
+ field_matrixbox_membership_criterion_category_list_cell_0_0_1=[],
+ field_matrixbox_quantity_cell_1_0_1="",
+ field_matrixbox_membership_criterion_category_list_cell_1_0_1=[],
+ field_matrixbox_quantity_cell_0_0_2="",
+ field_matrixbox_membership_criterion_category_list_cell_0_0_2=[],
+ field_matrixbox_quantity_cell_1_0_2="1",
+ field_matrixbox_membership_criterion_category_list_cell_1_0_2=[
+ 'product_line/1/1.1',
+ 'source/account_module/goods_purchase',
+ 'account_type/asset/cash/bank',
+ ],
+ ))
+ budget_line.Base_edit(form_id=form.getId())
+
+ self.assertEquals(1, len(budget_line.contentValues()))
+
+ budget_line.BudgetLine_setQuantityOnSummaryCellList()
+ self.assertEquals(3, len(budget_line.contentValues()))
+
+ budget_cell = budget_line.getCell(
+ 'product_line/1/1.1',
+ 'source/account_module/goods_purchase',
+ 'account_type/asset/cash')
+ self.assertNotEquals(None, budget_cell)
+ self.assertEquals(1, budget_cell.getQuantity())
+
+ budget_cell = budget_line.getCell(
+ 'product_line/1/1.1',
+ 'source/account_module/goods_purchase',
+ 'account_type/asset',)
+ self.assertNotEquals(None, budget_cell)
+ self.assertEquals(1, budget_cell.getQuantity())
+
+
+ # Other TODOs:
# budget level variation and budget cell level variation for same inventory
# axis
More information about the Erp5-report
mailing list