From 99dc1c05e0445d692ca8a14b62379c6b72d1a419 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=A9rome=20Perrin?= <jerome@nexedi.com>
Date: Tue, 24 Aug 2010 08:11:39 +0000
Subject: [PATCH] fix a bug with consomption when a dimension was no selected

git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@37966 20353a03-c40f-0410-a6d1-a30d3c3de9de
---
 product/ERP5/Document/BudgetVariation.py      |   4 +
 .../ERP5/Document/CategoryBudgetVariation.py  |   7 +-
 product/ERP5/Document/NodeBudgetVariation.py  |   7 +-
 product/ERP5/tests/testBudget.py              | 179 +++++++++++++++++-
 4 files changed, 192 insertions(+), 5 deletions(-)

diff --git a/product/ERP5/Document/BudgetVariation.py b/product/ERP5/Document/BudgetVariation.py
index 99d9a87d49..0f5bd8a74a 100644
--- a/product/ERP5/Document/BudgetVariation.py
+++ b/product/ERP5/Document/BudgetVariation.py
@@ -113,6 +113,10 @@ class BudgetVariation(Predicate):
     if not base_category:
       return None
     
+    if not budget_line.getVariationCategoryList(
+                          base_category_list=(base_category,)):
+      return None
+
     getObject = self.getPortalObject().portal_catalog.getObject
     def getUrlFromUidNoCache(uid):
       relative_url = getObject(uid).getRelativeUrl()
diff --git a/product/ERP5/Document/CategoryBudgetVariation.py b/product/ERP5/Document/CategoryBudgetVariation.py
index 6d2b13f9bf..57a381df31 100644
--- a/product/ERP5/Document/CategoryBudgetVariation.py
+++ b/product/ERP5/Document/CategoryBudgetVariation.py
@@ -132,14 +132,17 @@ class CategoryBudgetVariation(BudgetVariation):
                   'mirror_section', 'mirror_node' ):
         axis = '%s_uid' % axis
 
+    found = False
     for category in context.getVariationCategoryList(
                                base_category_list=(base_category,)):
       if axis.endswith('_uid'):
         category = self.getPortalObject().portal_categories\
                                 .getCategoryUid(category)
       query_dict.setdefault(axis, []).append(category)
-
-    return query_dict
+      found = True
+    if found:
+      return query_dict
+    return dict()
   
   def getBudgetVariationRangeCategoryList(self, context):
     """Returns the Variation Range Category List that can be applied to this
diff --git a/product/ERP5/Document/NodeBudgetVariation.py b/product/ERP5/Document/NodeBudgetVariation.py
index 1d8813d4db..5084122359 100644
--- a/product/ERP5/Document/NodeBudgetVariation.py
+++ b/product/ERP5/Document/NodeBudgetVariation.py
@@ -200,13 +200,16 @@ class NodeBudgetVariation(BudgetVariation):
     # if we have a virtual "all others" node, we don't set a criterion here.
     if self.getProperty('include_virtual_other_node'):
       return query_dict
-
+    found = False
     for node_url in context.getVariationCategoryList(
                           base_category_list=(base_category,)):
       query_dict.setdefault(axis, []).append(
                 portal_categories.getCategoryValue(node_url,
                       base_category=base_category).getUid())
-    return query_dict
+      found = True
+    if found:
+      return query_dict
+    return dict()
   
   def _getCellKeyFromInventoryListBrain(self, brain, budget_line,
                                          cell_key_cache=None):
diff --git a/product/ERP5/tests/testBudget.py b/product/ERP5/tests/testBudget.py
index 3f83ae79d9..aac5763e96 100644
--- a/product/ERP5/tests/testBudget.py
+++ b/product/ERP5/tests/testBudget.py
@@ -62,6 +62,7 @@ class TestBudget(ERP5TypeTestCase):
             'erp5_invoicing', 'erp5_simplified_invoicing',
             'erp5_accounting_ui_test', 'erp5_budget')
 
+  # creation and basic functionalities
   def test_simple_create_budget_model(self):
     budget_model = self.portal.budget_model_module.newContent(
                             portal_type='Budget Model')
@@ -284,6 +285,7 @@ class TestBudget(ERP5TypeTestCase):
     self.assertEquals('demo_group', budget.getGroup())
     self.assertEquals('Demo Group', budget.getGroupTitle())
 
+  # consumptions
   def test_simple_consumption(self):
     budget_model = self.portal.budget_model_module.newContent(
                             portal_type='Budget Model')
@@ -788,7 +790,182 @@ class TestBudget(ERP5TypeTestCase):
        ('group/demo_group', 'source/account_module/goods_purchase'): 100.0,},
        budget_line.getEngagedBudgetDict())
 
+  def test_consumption_node_budget_variation_not_set(self):
+    # test consumption calculation when a node budget variation is used, but
+    # this variation category is not set
+    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',)
+
+    # we don't set 
+    budget_line.edit(
+        variation_category_list=(
+          '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="500",
+             field_matrixbox_membership_criterion_category_list_cell_0_0_0=[
+               'group/demo_group/sub1', ],
+        ))
+    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(),
+             section_category=['group/demo_group/sub1',],
+             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', ): 0.0, },
+       budget_line.getConsumedBudgetDict())
+
+    self.assertEquals(
+      {('group/demo_group/sub1', ): 0.0, },
+       budget_line.getEngagedBudgetDict())
 
+  def test_consumption_category_budget_variation_not_set(self):
+    # test consumption calculation when a category budget variation is used, but
+    # this variation category is not set
+    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',)
+
+    # we don't set 
+    budget_line.edit(
+        variation_category_list=(
+          'source/account_module/goods_purchase',
+          ))
+    
+    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="500",
+             field_matrixbox_membership_criterion_category_list_cell_0_0_0=[
+               '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(),],
+             group_by_node=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(
+      {('source/account_module/goods_purchase', ): 100.0, },
+       budget_line.getConsumedBudgetDict())
+
+    self.assertEquals(
+      {('source/account_module/goods_purchase', ): 100.0, },
+       budget_line.getEngagedBudgetDict())
+
+
+  # Report
   def test_budget_consumption_report(self):
     budget_model = self.portal.budget_model_module.newContent(
                             portal_type='Budget Model')
@@ -934,7 +1111,7 @@ class TestBudget(ERP5TypeTestCase):
     if err_list:
       self.fail(''.join(err_list))
 
-    
+  # "update summary cells" feature
   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(
-- 
2.30.9