diff --git a/bt5/erp5_pdm/SkinTemplateItem/portal_skins/erp5_pdm/InternalSupplyLine_view.xml b/bt5/erp5_pdm/SkinTemplateItem/portal_skins/erp5_pdm/InternalSupplyLine_view.xml index 1d5113b3a458c500d23ba4506eb3d0e8c326d7f6..718bc83d217e64b6d076fd6db1ef2581bfd6f562 100644 --- a/bt5/erp5_pdm/SkinTemplateItem/portal_skins/erp5_pdm/InternalSupplyLine_view.xml +++ b/bt5/erp5_pdm/SkinTemplateItem/portal_skins/erp5_pdm/InternalSupplyLine_view.xml @@ -95,6 +95,7 @@ <list> <string>my_destination_title</string> <string>my_resource_title</string> + <string>my_product_line</string> <string>my_priced_quantity</string> <string>my_base_unit_price</string> <string>my_quantity_unit</string> diff --git a/bt5/erp5_pdm/SkinTemplateItem/portal_skins/erp5_pdm/InternalSupplyLine_view/my_product_line.xml b/bt5/erp5_pdm/SkinTemplateItem/portal_skins/erp5_pdm/InternalSupplyLine_view/my_product_line.xml new file mode 100644 index 0000000000000000000000000000000000000000..d8c278399abc916966a849f99db0de7c7d7237bf --- /dev/null +++ b/bt5/erp5_pdm/SkinTemplateItem/portal_skins/erp5_pdm/InternalSupplyLine_view/my_product_line.xml @@ -0,0 +1,115 @@ +<?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>editable</string> + </list> + </value> + </item> + <item> + <key> <string>id</string> </key> + <value> <string>my_product_line</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>editable</string> </key> + <value> + <persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent> + </value> + </item> + <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>editable</string> </key> + <value> <int>1</int> </value> + </item> + <item> + <key> <string>field_id</string> </key> + <value> <string>my_product_line</string> </value> + </item> + <item> + <key> <string>form_id</string> </key> + <value> <string>Base_viewPDMFieldLibrary</string> </value> + </item> + <item> + <key> <string>target</string> </key> + <value> <string>Click to edit the target</string> </value> + </item> + </dictionary> + </value> + </item> + </dictionary> + </pickle> + </record> + <record id="2" aka="AAAAAAAAAAI="> + <pickle> + <global name="TALESMethod" module="Products.Formulator.TALESField"/> + </pickle> + <pickle> + <dictionary> + <item> + <key> <string>_text</string> </key> + <value> <string>not: context/hasResource</string> </value> + </item> + </dictionary> + </pickle> + </record> +</ZopeData> diff --git a/bt5/erp5_pdm/SkinTemplateItem/portal_skins/erp5_pdm/PurchaseSupplyLine_view.xml b/bt5/erp5_pdm/SkinTemplateItem/portal_skins/erp5_pdm/PurchaseSupplyLine_view.xml index d94249070fc477b289c7e91890716a1bcae5e710..789ec0fbe5b722e3f059d70c5d83442197818c01 100644 --- a/bt5/erp5_pdm/SkinTemplateItem/portal_skins/erp5_pdm/PurchaseSupplyLine_view.xml +++ b/bt5/erp5_pdm/SkinTemplateItem/portal_skins/erp5_pdm/PurchaseSupplyLine_view.xml @@ -84,6 +84,7 @@ <value> <list> <string>my_resource_title</string> + <string>my_product_line</string> <string>my_source_title</string> <string>my_source_reference</string> <string>my_priced_quantity</string> diff --git a/bt5/erp5_pdm/SkinTemplateItem/portal_skins/erp5_pdm/PurchaseSupplyLine_view/my_product_line.xml b/bt5/erp5_pdm/SkinTemplateItem/portal_skins/erp5_pdm/PurchaseSupplyLine_view/my_product_line.xml new file mode 100644 index 0000000000000000000000000000000000000000..d8c278399abc916966a849f99db0de7c7d7237bf --- /dev/null +++ b/bt5/erp5_pdm/SkinTemplateItem/portal_skins/erp5_pdm/PurchaseSupplyLine_view/my_product_line.xml @@ -0,0 +1,115 @@ +<?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>editable</string> + </list> + </value> + </item> + <item> + <key> <string>id</string> </key> + <value> <string>my_product_line</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>editable</string> </key> + <value> + <persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent> + </value> + </item> + <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>editable</string> </key> + <value> <int>1</int> </value> + </item> + <item> + <key> <string>field_id</string> </key> + <value> <string>my_product_line</string> </value> + </item> + <item> + <key> <string>form_id</string> </key> + <value> <string>Base_viewPDMFieldLibrary</string> </value> + </item> + <item> + <key> <string>target</string> </key> + <value> <string>Click to edit the target</string> </value> + </item> + </dictionary> + </value> + </item> + </dictionary> + </pickle> + </record> + <record id="2" aka="AAAAAAAAAAI="> + <pickle> + <global name="TALESMethod" module="Products.Formulator.TALESField"/> + </pickle> + <pickle> + <dictionary> + <item> + <key> <string>_text</string> </key> + <value> <string>not: context/hasResource</string> </value> + </item> + </dictionary> + </pickle> + </record> +</ZopeData> diff --git a/bt5/erp5_pdm/SkinTemplateItem/portal_skins/erp5_pdm/SaleSupplyLine_view.xml b/bt5/erp5_pdm/SkinTemplateItem/portal_skins/erp5_pdm/SaleSupplyLine_view.xml index e5f391d2313053443e266f07d5928b57365b3e6e..6a8a25d0b33c272cbcb0db299d8da64885795be8 100644 --- a/bt5/erp5_pdm/SkinTemplateItem/portal_skins/erp5_pdm/SaleSupplyLine_view.xml +++ b/bt5/erp5_pdm/SkinTemplateItem/portal_skins/erp5_pdm/SaleSupplyLine_view.xml @@ -95,6 +95,7 @@ <list> <string>my_destination_title</string> <string>my_resource_title</string> + <string>my_product_line</string> <string>my_destination_reference</string> <string>my_priced_quantity</string> <string>your_quantity_unit</string> diff --git a/bt5/erp5_pdm/SkinTemplateItem/portal_skins/erp5_pdm/SaleSupplyLine_view/my_product_line.xml b/bt5/erp5_pdm/SkinTemplateItem/portal_skins/erp5_pdm/SaleSupplyLine_view/my_product_line.xml new file mode 100644 index 0000000000000000000000000000000000000000..d8c278399abc916966a849f99db0de7c7d7237bf --- /dev/null +++ b/bt5/erp5_pdm/SkinTemplateItem/portal_skins/erp5_pdm/SaleSupplyLine_view/my_product_line.xml @@ -0,0 +1,115 @@ +<?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>editable</string> + </list> + </value> + </item> + <item> + <key> <string>id</string> </key> + <value> <string>my_product_line</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>editable</string> </key> + <value> + <persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent> + </value> + </item> + <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>editable</string> </key> + <value> <int>1</int> </value> + </item> + <item> + <key> <string>field_id</string> </key> + <value> <string>my_product_line</string> </value> + </item> + <item> + <key> <string>form_id</string> </key> + <value> <string>Base_viewPDMFieldLibrary</string> </value> + </item> + <item> + <key> <string>target</string> </key> + <value> <string>Click to edit the target</string> </value> + </item> + </dictionary> + </value> + </item> + </dictionary> + </pickle> + </record> + <record id="2" aka="AAAAAAAAAAI="> + <pickle> + <global name="TALESMethod" module="Products.Formulator.TALESField"/> + </pickle> + <pickle> + <dictionary> + <item> + <key> <string>_text</string> </key> + <value> <string>not: context/hasResource</string> </value> + </item> + </dictionary> + </pickle> + </record> +</ZopeData> diff --git a/bt5/erp5_pdm/SkinTemplateItem/portal_skins/erp5_pdm/SupplyCell_asPredicate.xml b/bt5/erp5_pdm/SkinTemplateItem/portal_skins/erp5_pdm/SupplyCell_asPredicate.xml index 6b7c35478a34d5ddc20619d404ec471157e5e880..06de56c40a42f708d895bba80aeeec436548774e 100644 --- a/bt5/erp5_pdm/SkinTemplateItem/portal_skins/erp5_pdm/SupplyCell_asPredicate.xml +++ b/bt5/erp5_pdm/SkinTemplateItem/portal_skins/erp5_pdm/SupplyCell_asPredicate.xml @@ -66,6 +66,9 @@ if context.getSource():\n if context.getDestination():\n base_category_tuple += (\'destination\',)\n \n +if context.hasProductLine():\n + base_category_tuple += (\'product_line\', )\n +\n if context.getParentValue().getParentValue().getPortalType() in (\n ## XXX There is no portal type group for trade conditions.\n \'Sale Trade Condition\',\n diff --git a/bt5/erp5_pdm/SkinTemplateItem/portal_skins/erp5_pdm/SupplyLine_asPredicate.xml b/bt5/erp5_pdm/SkinTemplateItem/portal_skins/erp5_pdm/SupplyLine_asPredicate.xml index 1e67230533355bc1e89acecf46b0089b0f24a2cc..b8e68144379dd6dc4daae43744703e578e4478a6 100644 --- a/bt5/erp5_pdm/SkinTemplateItem/portal_skins/erp5_pdm/SupplyLine_asPredicate.xml +++ b/bt5/erp5_pdm/SkinTemplateItem/portal_skins/erp5_pdm/SupplyLine_asPredicate.xml @@ -68,6 +68,9 @@ if context.getSource():\n if context.getDestination():\n base_category_tuple += (\'destination\',)\n \n +if context.hasProductLine():\n + base_category_tuple += (\'product_line\', )\n +\n if context.getParentValue().getPortalType() in (\n ## XXX There is no portal type group for trade conditions.\n \'Sale Trade Condition\',\n diff --git a/product/ERP5/bootstrap/erp5_core/SkinTemplateItem/portal_skins/erp5_core/Movement_getPriceCalculationOperandDict.xml b/product/ERP5/bootstrap/erp5_core/SkinTemplateItem/portal_skins/erp5_core/Movement_getPriceCalculationOperandDict.xml index 1edd28f0ff7c218fadcade06d2c282c1bbb09aa4..68dfc9000822df2d0ddb3dc810dde0cec344620d 100644 --- a/product/ERP5/bootstrap/erp5_core/SkinTemplateItem/portal_skins/erp5_core/Movement_getPriceCalculationOperandDict.xml +++ b/product/ERP5/bootstrap/erp5_core/SkinTemplateItem/portal_skins/erp5_core/Movement_getPriceCalculationOperandDict.xml @@ -178,6 +178,10 @@ if specialise_set:\n kw[\'categories\'] = kw.get(\'categories\', []) + [\'specialise/%s\' % x for x in specialise_set]\n \n if resource is not None:\n + product_line = resource.getProductLine()\n + if product_line:\n + kw[\'categories\'] = kw.get(\'categories\', []) + [\'product_line/%s\' % product_line]\n +\n if isPricingOptimise():\n return getOptimisedPriceCalculationOperandDict(default=default, context=context, **kw)\n else:\n diff --git a/product/ERP5/tests/testResource.py b/product/ERP5/tests/testResource.py index 2a19b6b016fe2f78b8ed1d6f3b9595918ffea32e..644611b1fdbb8d5f92d5fb80f7e1b0cf981b79ea 100644 --- a/product/ERP5/tests/testResource.py +++ b/product/ERP5/tests/testResource.py @@ -186,6 +186,16 @@ class TestResource(ERP5TypeTestCase): quantity=0.001) gram_definition.validate() + # create some product line categories + product_line = self.portal.portal_categories.product_line + if product_line._getOb('a', None) is None: + product_line.newContent( + id='a', + portal_type='Category') + if product_line._getOb('b', None) is None: + product_line.newContent( + id='b', + portal_type='Category') def stepCreateResource(self, sequence=None, sequence_list=None, **kw): """ @@ -1067,6 +1077,43 @@ class TestResource(ERP5TypeTestCase): self.assertEqual(1000, sale_order_line.getPrice()) self.assertEqual(5000, sale_order_line.getTotalPrice()) + def testGetPriceProductLine(self): + """Test supply line set for a product line. + """ + # This supply line defines a price applicable for all resources member + # of product line a + supply = self.portal.getDefaultModule(self.sale_supply_portal_type).newContent( + portal_type=self.sale_supply_portal_type) + supply_line = supply.newContent(portal_type=self.sale_supply_line_portal_type) + supply_line.setProductLineValue(self.portal.portal_categories.product_line.a) + supply_line.setBasePrice(1000) + supply.validate() + + resource_a = self.portal.getDefaultModule(self.product_portal_type)\ + .newContent(portal_type=self.product_portal_type) + resource_a.setProductLineValue(self.portal.portal_categories.product_line.a) + resource_b = self.portal.getDefaultModule(self.product_portal_type)\ + .newContent(portal_type=self.product_portal_type) + resource_b.setProductLineValue(self.portal.portal_categories.product_line.b) + + self.tic() + sale_order_line = self.portal.getDefaultModule("Sale Order").newContent( + portal_type='Sale Order').newContent( + portal_type=self.sale_order_line_portal_type, + resource_value=resource_a, + quantity=1) + # resource_a is member of product_line/a, so our supply line applies. + self.assertEqual(1000, sale_order_line.getPrice()) + + sale_order_line = self.portal.getDefaultModule("Sale Order").newContent( + portal_type='Sale Order').newContent( + portal_type=self.sale_order_line_portal_type, + resource_value=resource_b, + quantity=1) + # resource_b is member of product_line/b, so our supply line does not apply. + self.assertEqual(None, sale_order_line.getPrice()) + + def testQuantityPrecision(self): """test how to define quantity precision on resources. """