Commit 05f913a0 authored by Nicolas Wavrant's avatar Nicolas Wavrant

Price per quantity per slice

This MR introduces a second way of calculating the base price of a resource using "Base Price Quantity Step".

Currently, for a resource, we could define on a Supply Line "Quantity Steps",  and set a price for each of these steps. Then, depending on the quantity of the resource, the price of the unique matching step would apply.

For exemple : 

| Quantity Step Range | Price for the step|
|------------|---------|
| 0 -> 10 | 10€ |
| 11 -> 20 | 9€ |
| 21 -> inf | 8€ |

With the current method, for an Order of 15 products, the 2 range "11 -> 20" would apply, the unit price for the products would be 9€, and the total price would be 15*9 = 135€.

The new method of calculating would apply the _Price for the step_ __to, and only to, all items of this step__. Which means, for an order of 15 products, the 10 first products would have a unit price of 10€, and the 5 next products would have a unit price of 9€, which makes in the end a total price of 145€, and a base price of 9.66€.

/reviewed-on nexedi/erp5!896
parents db0ee9b5 334b21a7
......@@ -7,6 +7,10 @@
<type>Internal Supply</type>
<workflow>edit_workflow, validation_workflow</workflow>
</chain>
<chain>
<type>Internal Supply Cell</type>
<workflow>supply_cell_interaction_workflow</workflow>
</chain>
<chain>
<type>Internal Supply Line</type>
<workflow>edit_workflow, reindex_object_interaction_workflow, supply_line_interaction_workflow</workflow>
......@@ -23,6 +27,10 @@
<type>Purchase Supply</type>
<workflow>edit_workflow, validation_workflow</workflow>
</chain>
<chain>
<type>Purchase Supply Cell</type>
<workflow>supply_cell_interaction_workflow</workflow>
</chain>
<chain>
<type>Purchase Supply Line</type>
<workflow>edit_workflow, reindex_object_interaction_workflow, supply_line_interaction_workflow</workflow>
......@@ -43,6 +51,10 @@
<type>Sale Supply</type>
<workflow>edit_workflow, validation_workflow</workflow>
</chain>
<chain>
<type>Sale Supply Cell</type>
<workflow>supply_cell_interaction_workflow</workflow>
</chain>
<chain>
<type>Sale Supply Line</type>
<workflow>edit_workflow, reindex_object_interaction_workflow, supply_line_interaction_workflow</workflow>
......@@ -51,6 +63,10 @@
<type>Service</type>
<workflow>edit_workflow, validation_workflow</workflow>
</chain>
<chain>
<type>Supply Cell</type>
<workflow>supply_cell_interaction_workflow</workflow>
</chain>
<chain>
<type>Supply Line</type>
<workflow>edit_workflow, reindex_object_interaction_workflow, supply_line_interaction_workflow</workflow>
......
......@@ -226,6 +226,7 @@
<string>my_max_order_quantity_variation_base_category_list</string>
<string>matrixbox_for_max_order_quantity</string>
<string>my_view_mode_target_delivery</string>
<string>my_base_price_per_slice</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>title</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>my_base_price_per_slice</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>
</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>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_checkbox</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewFieldLibrary</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Base Price Applies to Items in Slice</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -11,7 +11,6 @@
<value>
<list>
<string>css_class</string>
<string>default</string>
<string>external_validator</string>
<string>title</string>
<string>width</string>
......@@ -57,10 +56,12 @@
<value>
<dictionary>
<item>
<key> <string>default</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
<key> <string>css_class</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>external_validator</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>field_id</string> </key>
......@@ -74,6 +75,14 @@
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>width</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
......@@ -85,16 +94,10 @@
<key> <string>css_class</string> </key>
<value> <string>figure</string> </value>
</item>
<item>
<key> <string>default</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>external_validator</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
......@@ -124,19 +127,6 @@
</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>python:[str(x) for x in here.getQuantityStepList()]</string> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="Method" module="Products.Formulator.MethodField"/>
</pickle>
......
......@@ -106,6 +106,7 @@
<string>my_price_currency</string>
<string>my_start_date_range_min</string>
<string>my_start_date_range_max</string>
<string>my_base_price_per_slice</string>
</list>
</value>
</item>
......
......@@ -9,7 +9,9 @@
<item>
<key> <string>delegated_list</string> </key>
<value>
<list/>
<list>
<string>default</string>
</list>
</value>
</item>
<item>
......@@ -50,6 +52,12 @@
<key> <string>tales</string> </key>
<value>
<dictionary>
<item>
<key> <string>default</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
......@@ -69,6 +77,14 @@
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>default</string> </key>
<value>
<list>
<string>base_price</string>
</list>
</value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_mapped_value_property_list</string> </value>
......@@ -87,4 +103,17 @@
</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>python: [\'base_price\', \'base_unit_price\', \'slice_base_price\', \'slice_quantity_range\']</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?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/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>my_base_price_per_slice</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>
</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>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_base_price_per_slice</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewPDMFieldLibrary</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -106,6 +106,7 @@
<string>my_price_currency</string>
<string>my_start_date_range_min</string>
<string>my_start_date_range_max</string>
<string>my_base_price_per_slice</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/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>my_base_price_per_slice</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>
</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>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_base_price_per_slice</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewPDMFieldLibrary</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
from math import log
result = context.getPriceParameterDict(context=movement, **kw)
# Calculate
# If slice_base_price:
# base_price = SUM(number_of_items_in_slice * slice_base_price) for each slice
# Then
# ((base_price + SUM(additional_price) +
# variable_value * SUM(variable_additional_price)) *
# (1 - MIN(1, MAX(SUM(discount_ratio) , exclusive_discount_ratio ))) +
......@@ -17,6 +22,23 @@ result = context.getPriceParameterDict(context=movement, **kw)
# depends on discrete variations, but also on a continuous property
# of the object
if result["slice_base_price"]:
total_price = 0.
quantity = movement.getQuantity()
sliced_base_price_list = zip(result["slice_base_price"], result["slice_quantity_range"])
for slice_price, slice_range in sliced_base_price_list:
slice_min, slice_max = slice_range
if slice_max is None:
slice_max = quantity + 1
if slice_min is None:
slice_min = 1
priced_quantity = min(slice_max - 1, quantity) - (slice_min - 1)
total_price += priced_quantity * slice_price
if result.get('base_unit_price', None) is None:
result["base_price"] = total_price / quantity
else:
result["base_price"] = round(total_price / quantity, int(round(- log(result['base_unit_price'], 10),0)))
base_price = result["base_price"]
if base_price in (None, ""):
# XXX Compatibility
......
......@@ -116,6 +116,7 @@
<string>my_internal_supply_line_max_flow</string>
<string>my_internal_supply_line_min_stock</string>
<string>my_internal_supply_line_max_stock</string>
<string>my_internal_supply_line_base_price_per_slice</string>
</list>
</value>
</item>
......
......@@ -9,7 +9,9 @@
<item>
<key> <string>delegated_list</string> </key>
<value>
<list/>
<list>
<string>default</string>
</list>
</value>
</item>
<item>
......@@ -69,6 +71,17 @@
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>default</string> </key>
<value>
<list>
<string>base_price</string>
<string>base_unit_price</string>
<string>slice_base_price</string>
<string>slice_quantity_range</string>
</list>
</value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_mapped_value_property_list</string> </value>
......
<?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/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>my_internal_supply_line_base_price_per_slice</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>
</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>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_base_price_per_slice</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewPDMFieldLibrary</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -116,6 +116,7 @@
<string>my_purchase_supply_line_max_flow</string>
<string>my_purchase_supply_line_min_stock</string>
<string>my_purchase_supply_line_max_stock</string>
<string>my_purchase_supply_line_base_price_per_slice</string>
</list>
</value>
</item>
......
......@@ -9,7 +9,9 @@
<item>
<key> <string>delegated_list</string> </key>
<value>
<list/>
<list>
<string>default</string>
</list>
</value>
</item>
<item>
......@@ -69,6 +71,17 @@
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>default</string> </key>
<value>
<list>
<string>base_price</string>
<string>base_unit_price</string>
<string>slice_base_price</string>
<string>slice_quantity_range</string>
</list>
</value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_mapped_value_property_list</string> </value>
......
<?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/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>my_purchase_supply_line_base_price_per_slice</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>
</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>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_base_price_per_slice</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewPDMFieldLibrary</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -116,6 +116,7 @@
<string>my_sale_supply_line_max_flow</string>
<string>my_sale_supply_line_min_stock</string>
<string>my_sale_supply_line_max_stock</string>
<string>my_sale_supply_line_base_price_per_slice</string>
</list>
</value>
</item>
......
......@@ -9,7 +9,9 @@
<item>
<key> <string>delegated_list</string> </key>
<value>
<list/>
<list>
<string>default</string>
</list>
</value>
</item>
<item>
......@@ -69,6 +71,17 @@
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>default</string> </key>
<value>
<list>
<string>base_price</string>
<string>base_unit_price</string>
<string>slice_base_price</string>
<string>slice_quantity_range</string>
</list>
</value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_mapped_value_property_list</string> </value>
......
<?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/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>my_sale_supply_line_base_price_per_slice</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>
</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>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_base_price_per_slice</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewPDMFieldLibrary</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -106,6 +106,7 @@
<string>my_price_currency</string>
<string>my_start_date_range_min</string>
<string>my_start_date_range_max</string>
<string>my_base_price_per_slice</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/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>my_base_price_per_slice</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>
</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>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_base_price_per_slice</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewPDMFieldLibrary</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -307,7 +307,7 @@
<dictionary>
<item>
<key> <string>_text</string> </key>
<value> <string>python:[str(x) for x in here.getQuantityStepList()]</string> </value>
<value> <string>python:[str(x) for x in context.getQuantityStepList([])]</string> </value>
</item>
</dictionary>
</pickle>
......
......@@ -95,6 +95,7 @@
<string>my_quantity_unit</string>
<string>my_price_currency</string>
<string>my_start_date_range_max</string>
<string>my_base_price_per_slice</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/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>my_base_price_per_slice</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>
</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>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_base_price_per_slice</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewPDMFieldLibrary</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -134,9 +134,7 @@
</item>
<item>
<key> <string>default</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
<value> <string></string> </value>
</item>
<item>
<key> <string>description</string> </key>
......@@ -238,7 +236,7 @@
<item>
<key> <string>external_validator</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
......@@ -300,19 +298,6 @@
</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>python:[str(x) for x in here.getQuantityStepList()]</string> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="Method" module="Products.Formulator.MethodField"/>
</pickle>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="InteractionWorkflowDefinition" module="Products.ERP5.InteractionWorkflow"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_objects</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>creation_guard</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>groups</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>supply_cell_interaction_workflow</string> </value>
</item>
<item>
<key> <string>manager_bypass</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Supply Cell Interaction Workflow</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Interaction" module="Products.ERP5.Interaction"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_mapping</string> </key>
<value>
<dictionary/>
</value>
</item>
<item>
<key> <string>_objects</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>interactions</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="InteractionDefinition" module="Products.ERP5.Interaction"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>actbox_category</string> </key>
<value> <string>workflow</string> </value>
</item>
<item>
<key> <string>actbox_name</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>actbox_url</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>activate_script_name</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>after_script_name</string> </key>
<value>
<list>
<string>SupplyCell_updateSliceBasePrice</string>
</list>
</value>
</item>
<item>
<key> <string>before_commit_script_name</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>guard</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>SupplyCell_updateBasePrice</string> </value>
</item>
<item>
<key> <string>method_id</string> </key>
<value>
<list>
<string>_setBasePrice</string>
</list>
</value>
</item>
<item>
<key> <string>once_per_transaction</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>portal_type_filter</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>portal_type_group_filter</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>script_name</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>temporary_document_disallowed</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>trigger_type</string> </key>
<value> <int>2</int> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Scripts" module="Products.DCWorkflow.Scripts"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_mapping</string> </key>
<value>
<dictionary/>
</value>
</item>
<item>
<key> <string>_objects</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>scripts</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
supply_cell = state_change['object']
supply_line = supply_cell.getParentValue()
quantity_criterion_list = [
criterion for criterion in supply_cell.getCriterionList()
if criterion.property == 'quantity'
]
if len(quantity_criterion_list) == 1:
quantity_criterion = quantity_criterion_list[0]
else:
return
if supply_cell.getParentValue().isBasePricePerSlice():
quantity_step_list = [None] + supply_line.getQuantityStepList(base_id='path') + [None]
try:
index = quantity_step_list.index(quantity_criterion.min)
except KeyError:
# _range_criterion is set to {} if criterion is None
index = 0
min_quantity = quantity_step_list[index]
max_quantity = quantity_step_list[index+1]
supply_cell.setSliceQuantityRange((min_quantity, max_quantity))
supply_cell.setSliceBasePrice(supply_cell.getBasePrice())
else:
supply_cell.setSliceQuantityRange(None)
supply_cell.setSliceBasePrice(None)
<?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>_params</string> </key>
<value> <string>state_change</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>SupplyCell_updateSliceBasePrice</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Variables" module="Products.DCWorkflow.Variables"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_mapping</string> </key>
<value>
<dictionary/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>variables</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Worklists" module="Products.DCWorkflow.Worklists"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_mapping</string> </key>
<value>
<dictionary/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>worklists</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="InteractionDefinition" module="Products.ERP5.Interaction"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>actbox_category</string> </key>
<value> <string>workflow</string> </value>
</item>
<item>
<key> <string>actbox_name</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>actbox_url</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>activate_script_name</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>after_script_name</string> </key>
<value>
<list>
<string>SupplyLine_updateBasePricePerSlice</string>
</list>
</value>
</item>
<item>
<key> <string>before_commit_script_name</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>guard</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>SupplyLine_changeBasePricePerSlice</string> </value>
</item>
<item>
<key> <string>method_id</string> </key>
<value>
<list>
<string>_setBasePricePerSlice</string>
</list>
</value>
</item>
<item>
<key> <string>once_per_transaction</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>portal_type_filter</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>portal_type_group_filter</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>script_name</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>temporary_document_disallowed</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>trigger_type</string> </key>
<value> <int>2</int> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
supply_line = state_change['object']
price_parameter = 'base_price'
if supply_line.isBasePricePerSlice():
price_parameter = 'slice_base_price'
else:
price_parameter = 'base_price'
base_id = 'path'
supply_line.updateQuantityPredicate(price_parameter)
supply_line.updateCellRange(base_id=base_id)
supply_line = state_change['object']
to_delete_cell_list = [
cell for cell in supply_line.getCellIdList(base_id='path')
if hasattr(supply_line, cell)
]
supply_line.manage_delObjects(ids=to_delete_cell_list)
if state_change.kwargs['workflow_method_args'][0]:
price_parameter = 'slice_base_price'
else:
price_parameter = 'base_price'
supply_line.updateQuantityPredicate(price_parameter)
supply_line.updateCellRange(base_id='path')
<?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>_params</string> </key>
<value> <string>state_change</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>SupplyLine_updateBasePricePerSlice</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
Component | edit_workflow
Component | validation_workflow
Internal Supply Cell | supply_cell_interaction_workflow
Internal Supply Line | edit_workflow
Internal Supply Line | reindex_object_interaction_workflow
Internal Supply Line | supply_line_interaction_workflow
......@@ -9,6 +10,7 @@ Measure | conversion_interaction_workflow
Measure | edit_workflow
Product | edit_workflow
Product | validation_workflow
Purchase Supply Cell | supply_cell_interaction_workflow
Purchase Supply Line | edit_workflow
Purchase Supply Line | reindex_object_interaction_workflow
Purchase Supply Line | supply_line_interaction_workflow
......@@ -21,6 +23,7 @@ Quantity Unit Conversion Group | conversion_interaction_workflow
Quantity Unit Conversion Group | edit_workflow
Quantity Unit Conversion Group | validation_workflow
Resource Measures Consistency Constraint | dynamic_class_generation_interaction_workflow
Sale Supply Cell | supply_cell_interaction_workflow
Sale Supply Line | edit_workflow
Sale Supply Line | reindex_object_interaction_workflow
Sale Supply Line | supply_line_interaction_workflow
......@@ -28,6 +31,7 @@ Sale Supply | edit_workflow
Sale Supply | validation_workflow
Service | edit_workflow
Service | validation_workflow
Supply Cell | supply_cell_interaction_workflow
Supply Line | edit_workflow
Supply Line | reindex_object_interaction_workflow
Supply Line | supply_line_interaction_workflow
......
conversion_interaction_workflow
supply_cell_interaction_workflow
supply_line_interaction_workflow
transformation_interaction_workflow
\ No newline at end of file
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ZopePageTemplate" module="Products.PageTemplates.ZopePageTemplate"/>
</pickle>
<pickle>
<dictionary>
<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_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>content_type</string> </key>
<value> <string>text/html</string> </value>
</item>
<item>
<key> <string>expand</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>resource_default_internal_supply_line_price_per_slice</string> </value>
</item>
<item>
<key> <string>output_encoding</string> </key>
<value> <string>utf-8</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <unicode></unicode> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<html>
<head><title>Test toggling price per slice updates internal supply cells correctly</title></head>
<body>
<table cellpadding="1" cellspacing="1" border="1">
<thead>
<tr><td rowspan="1" colspan="4">
Test toggling price per slice updates internal supply cells correctly
</td></tr>
</thead>
<tbody tal:define="init_method string:PdmZuite_createDelivery?state=draft&delivery_type=Internal">
<!-- Setup {{{ -->
<tal:block metal:use-macro="here/PdmZuite_CommonTemplate/macros/init" />
<!-- }}} -->
<tr>
<td>clickAndWait</td>
<td>link=Internal</td>
<td></td>
</tr>
<tr>
<td>type</td>
<td>field_my_internal_supply_line_base_unit_price</td>
<td>0.00001</td>
<!-- Enter quantity step list and check -->
<tr>
<td>type</td>
<td>field_my_internal_supply_line_quantity_step_list</td>
<td>11<br />21</td>
</tr>
<tr>
<td>clickAndWait</td>
<td>Base_edit:method</td>
<td></td>
</tr>
<tr>
<td>assertText</td>
<td>field_my_internal_supply_line_quantity_step_list</td>
<td>11.0
21.0</td>
<tr>
<td>assertText</td>
<td>//input[@name="field_matrixbox_base_price_cell_0_0_0"]/../../../td[1]</td>
<td>Quantity &lt; 11.0</td>
</tr>
<tr>
<td>assertText</td>
<td>//input[@name="field_matrixbox_base_price_cell_1_0_0"]/../../../td[1]</td>
<td>11.0 &lt;= Quantity &lt; 21.0</td>
</tr>
<tr>
<td>assertText</td>
<td>//input[@name="field_matrixbox_base_price_cell_2_0_0"]/../../../td[1]</td>
<td>21.0 &lt;= Quantity</td>
</tr>
<tr>
<!-- Enter price per quantity step and check-->
<tal:block metal:use-macro="here/PdmZuite_CommonTemplate/macros/enterAndCheckPricePerSliceInSupplyLine" />
<!-- Open Delivery Line with the product and check price is correct -->
<tr>
<td>open</td>
<td tal:content="string:$${base_url}/internal_packing_list_module/erp5_pdm_ui_test_delivery/1" />
<td></td>
</tr>
<tr>
<td>type</td>
<td>//input[@name="field_my_quantity"]</td>
<td>15</td>
</tr>
<tr>
<td>type</td>
<td>//input[@name="field_my_price"]</td>
<td></td>
</tr>
<tr>
<td>clickAndWait</td>
<td>Base_edit:method</td>
<td></td>
</tr>
<tr>
<td>assertFloatValue</td>
<td>//input[@name="field_my_price"]</td>
<td>9</td>
</tr>
<!-- Select the new method "Price per slice" on the Internal Supply
and enter the prices again-->
<tr>
<td>open</td>
<td>${base_url}/product_module/erp5_pdm_ui_test_product</td>
<td></td>
</tr>
<tr>
<td>clickAndWait</td>
<td>link=Internal</td>
<td></td>
</tr>
<tal:block metal:use-macro="here/PdmZuite_CommonTemplate/macros/toggleInternalSupplyLineBasePricePerSlice" />
<tal:block metal:use-macro="here/PdmZuite_CommonTemplate/macros/enterAndCheckPricePerSliceInSupplyLine" />
<!-- Open Delivery Line with the product and check price is correct -->
<tr>
<td>open</td>
<td tal:content="string:$${base_url}/internal_packing_list_module/erp5_pdm_ui_test_delivery/1" />
<td></td>
</tr>
<tr>
<td>type</td>
<td>//input[@name="field_my_quantity"]</td>
<td>15</td>
</tr>
<tr>
<td>type</td>
<td>//input[@name="field_my_price"]</td>
<td></td>
</tr>
<tr>
<td>clickAndWait</td>
<td>Base_edit:method</td>
<td></td>
</tr>
<tr>
<td>assertFloatValue</td>
<td>//input[@name="field_my_price"]</td>
<td>9.66667</td>
</tr>
<!-- Unselect the new method "Price per slice" on the Internal Supply
and enter the prices again-->
<tr>
<td>open</td>
<td>${base_url}/product_module/erp5_pdm_ui_test_product</td>
<td></td>
</tr>
<tr>
<td>clickAndWait</td>
<td>link=Internal</td>
<td></td>
</tr>
<tal:block metal:use-macro="here/PdmZuite_CommonTemplate/macros/toggleInternalSupplyLineBasePricePerSlice" />
<tal:block metal:use-macro="here/PdmZuite_CommonTemplate/macros/enterAndCheckPricePerSliceInSupplyLine" />
<!-- Open Delivery Line with the product and check price is correct -->
<tr>
<td>open</td>
<td tal:content="string:$${base_url}/internal_packing_list_module/erp5_pdm_ui_test_delivery/1" />
<td></td>
</tr>
<tr>
<td>type</td>
<td>//input[@name="field_my_quantity"]</td>
<td>15</td>
</tr>
<tr>
<td>type</td>
<td>//input[@name="field_my_price"]</td>
<td></td>
</tr>
<tr>
<td>clickAndWait</td>
<td>Base_edit:method</td>
<td></td>
</tr>
<tr>
<td>assertFloatValue</td>
<td>//input[@name="field_my_price"]</td>
<td>9</td>
</tr>
</tbody></table>
</body>
</html>
\ No newline at end of file
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ZopePageTemplate" module="Products.PageTemplates.ZopePageTemplate"/>
</pickle>
<pickle>
<dictionary>
<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_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>content_type</string> </key>
<value> <string>text/html</string> </value>
</item>
<item>
<key> <string>expand</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>resource_default_purchase_supply_line_price_per_slice</string> </value>
</item>
<item>
<key> <string>output_encoding</string> </key>
<value> <string>utf-8</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <unicode></unicode> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<html>
<head><title>Test toggling price per slice updates purchase supply cells correctly</title></head>
<body>
<table cellpadding="1" cellspacing="1" border="1">
<thead>
<tr><td rowspan="1" colspan="4">
Test toggling price per slice updates purchase supply cells correctly
</td></tr>
</thead>
<tbody tal:define="init_method string:PdmZuite_createDelivery?state=draft&delivery_type=Purchase">
<!-- Setup {{{ -->
<tal:block metal:use-macro="here/PdmZuite_CommonTemplate/macros/init" />
<!-- }}} -->
<tr>
<td>clickAndWait</td>
<td>link=Purchase</td>
<td></td>
</tr>
<tr>
<td>type</td>
<td>field_my_purchase_supply_line_base_unit_price</td>
<td>0.00001</td>
<!-- Enter quantity step list and check -->
<tr>
<td>type</td>
<td>field_my_purchase_supply_line_quantity_step_list</td>
<td>11<br />21</td>
</tr>
<tr>
<td>clickAndWait</td>
<td>Base_edit:method</td>
<td></td>
</tr>
<tr>
<td>assertText</td>
<td>field_my_purchase_supply_line_quantity_step_list</td>
<td>11.0
21.0</td>
<tr>
<td>assertText</td>
<td>//input[@name="field_matrixbox_base_price_cell_0_0_0"]/../../../td[1]</td>
<td>Quantity &lt; 11.0</td>
</tr>
<tr>
<td>assertText</td>
<td>//input[@name="field_matrixbox_base_price_cell_1_0_0"]/../../../td[1]</td>
<td>11.0 &lt;= Quantity &lt; 21.0</td>
</tr>
<tr>
<td>assertText</td>
<td>//input[@name="field_matrixbox_base_price_cell_2_0_0"]/../../../td[1]</td>
<td>21.0 &lt;= Quantity</td>
</tr>
<tr>
<!-- Enter price per quantity step and check-->
<tal:block metal:use-macro="here/PdmZuite_CommonTemplate/macros/enterAndCheckPricePerSliceInSupplyLine" />
<!-- Open Delivery Line with the product and check price is correct -->
<tr>
<td>open</td>
<td tal:content="string:$${base_url}/purchase_packing_list_module/erp5_pdm_ui_test_delivery/1" />
<td></td>
</tr>
<tr>
<td>type</td>
<td>//input[@name="field_my_quantity"]</td>
<td>15</td>
</tr>
<tr>
<td>type</td>
<td>//input[@name="field_my_price"]</td>
<td></td>
</tr>
<tr>
<td>clickAndWait</td>
<td>Base_edit:method</td>
<td></td>
</tr>
<tr>
<td>assertFloatValue</td>
<td>//input[@name="field_my_price"]</td>
<td>9</td>
</tr>
<!-- Select the new method "Price per slice" on the Purchase Supply
and enter the prices again-->
<tr>
<td>open</td>
<td>${base_url}/product_module/erp5_pdm_ui_test_product</td>
<td></td>
</tr>
<tr>
<td>clickAndWait</td>
<td>link=Purchase</td>
<td></td>
</tr>
<tal:block metal:use-macro="here/PdmZuite_CommonTemplate/macros/togglePurchaseSupplyLineBasePricePerSlice" />
<tal:block metal:use-macro="here/PdmZuite_CommonTemplate/macros/enterAndCheckPricePerSliceInSupplyLine" />
<!-- Open Delivery Line with the product and check price is correct -->
<tr>
<td>open</td>
<td tal:content="string:$${base_url}/purchase_packing_list_module/erp5_pdm_ui_test_delivery/1" />
<td></td>
</tr>
<tr>
<td>type</td>
<td>//input[@name="field_my_quantity"]</td>
<td>15</td>
</tr>
<tr>
<td>type</td>
<td>//input[@name="field_my_price"]</td>
<td></td>
</tr>
<tr>
<td>clickAndWait</td>
<td>Base_edit:method</td>
<td></td>
</tr>
<tr>
<td>assertFloatValue</td>
<td>//input[@name="field_my_price"]</td>
<td>9.66667</td>
</tr>
<!-- Unselect the new method "Price per slice" on the Purchase Supply
and enter the prices again-->
<tr>
<td>open</td>
<td>${base_url}/product_module/erp5_pdm_ui_test_product</td>
<td></td>
</tr>
<tr>
<td>clickAndWait</td>
<td>link=Purchase</td>
<td></td>
</tr>
<tal:block metal:use-macro="here/PdmZuite_CommonTemplate/macros/togglePurchaseSupplyLineBasePricePerSlice" />
<tal:block metal:use-macro="here/PdmZuite_CommonTemplate/macros/enterAndCheckPricePerSliceInSupplyLine" />
<!-- Open Delivery Line with the product and check price is correct -->
<tr>
<td>open</td>
<td tal:content="string:$${base_url}/purchase_packing_list_module/erp5_pdm_ui_test_delivery/1" />
<td></td>
</tr>
<tr>
<td>type</td>
<td>//input[@name="field_my_quantity"]</td>
<td>15</td>
</tr>
<tr>
<td>type</td>
<td>//input[@name="field_my_price"]</td>
<td></td>
</tr>
<tr>
<td>clickAndWait</td>
<td>Base_edit:method</td>
<td></td>
</tr>
<tr>
<td>assertFloatValue</td>
<td>//input[@name="field_my_price"]</td>
<td>9</td>
</tr>
</tbody></table>
</body>
</html>
\ No newline at end of file
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ZopePageTemplate" module="Products.PageTemplates.ZopePageTemplate"/>
</pickle>
<pickle>
<dictionary>
<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_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>content_type</string> </key>
<value> <string>text/html</string> </value>
</item>
<item>
<key> <string>expand</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>resource_default_sale_supply_line_price_per_slice</string> </value>
</item>
<item>
<key> <string>output_encoding</string> </key>
<value> <string>utf-8</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <unicode></unicode> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<html>
<head><title>Test toggling price per slice updates sale supply cells correctly</title></head>
<body>
<table cellpadding="1" cellspacing="1" border="1">
<thead>
<tr><td rowspan="1" colspan="4">
Test toggling price per slice updates sale supply cells correctly
</td></tr>
</thead>
<tbody tal:define="init_method string:PdmZuite_createDelivery?state=draft">
<!-- Setup {{{ -->
<tal:block metal:use-macro="here/PdmZuite_CommonTemplate/macros/init" />
<!-- }}} -->
<tr>
<td>clickAndWait</td>
<td>link=Sale</td>
<td></td>
</tr>
<tr>
<td>type</td>
<td>field_my_sale_supply_line_base_unit_price</td>
<td>0.00001</td>
<!-- Enter quantity step list and check -->
<tr>
<td>type</td>
<td>field_my_sale_supply_line_quantity_step_list</td>
<td>11<br />21</td>
</tr>
<tr>
<td>clickAndWait</td>
<td>Base_edit:method</td>
<td></td>
</tr>
<tr>
<td>assertText</td>
<td>field_my_sale_supply_line_quantity_step_list</td>
<td>11.0
21.0</td>
<tr>
<td>assertText</td>
<td>//input[@name="field_matrixbox_base_price_cell_0_0_0"]/../../../td[1]</td>
<td>Quantity &lt; 11.0</td>
</tr>
<tr>
<td>assertText</td>
<td>//input[@name="field_matrixbox_base_price_cell_1_0_0"]/../../../td[1]</td>
<td>11.0 &lt;= Quantity &lt; 21.0</td>
</tr>
<tr>
<td>assertText</td>
<td>//input[@name="field_matrixbox_base_price_cell_2_0_0"]/../../../td[1]</td>
<td>21.0 &lt;= Quantity</td>
</tr>
<tr>
<!-- Enter price per quantity step and check-->
<tal:block metal:use-macro="here/PdmZuite_CommonTemplate/macros/enterAndCheckPricePerSliceInSupplyLine" />
<!-- Open Delivery Line with the product and check price is correct -->
<tr>
<td>open</td>
<td tal:content="string:$${base_url}/sale_packing_list_module/erp5_pdm_ui_test_delivery/1" />
<td></td>
</tr>
<tr>
<td>type</td>
<td>//input[@name="field_my_quantity"]</td>
<td>15</td>
</tr>
<tr>
<td>type</td>
<td>//input[@name="field_my_price"]</td>
<td></td>
</tr>
<tr>
<td>clickAndWait</td>
<td>Base_edit:method</td>
<td></td>
</tr>
<tr>
<td>assertFloatValue</td>
<td>//input[@name="field_my_price"]</td>
<td>9</td>
</tr>
<!-- Select the new method "Price per slice" on the Sale Supply
and enter the prices again-->
<tr>
<td>open</td>
<td>${base_url}/product_module/erp5_pdm_ui_test_product</td>
<td></td>
</tr>
<tr>
<td>clickAndWait</td>
<td>link=Sale</td>
<td></td>
</tr>
<tal:block metal:use-macro="here/PdmZuite_CommonTemplate/macros/toggleSaleSupplyLineBasePricePerSlice" />
<tal:block metal:use-macro="here/PdmZuite_CommonTemplate/macros/enterAndCheckPricePerSliceInSupplyLine" />
<!-- Open Delivery Line with the product and check price is correct -->
<tr>
<td>open</td>
<td tal:content="string:$${base_url}/sale_packing_list_module/erp5_pdm_ui_test_delivery/1" />
<td></td>
</tr>
<tr>
<td>type</td>
<td>//input[@name="field_my_quantity"]</td>
<td>15</td>
</tr>
<tr>
<td>type</td>
<td>//input[@name="field_my_price"]</td>
<td></td>
</tr>
<tr>
<td>clickAndWait</td>
<td>Base_edit:method</td>
<td></td>
</tr>
<tr>
<td>assertFloatValue</td>
<td>//input[@name="field_my_price"]</td>
<td>9.66667</td>
</tr>
<!-- Unselect the new method "Price per slice" on the Sale Supply
and enter the prices again-->
<tr>
<td>open</td>
<td>${base_url}/product_module/erp5_pdm_ui_test_product</td>
<td></td>
</tr>
<tr>
<td>clickAndWait</td>
<td>link=Sale</td>
<td></td>
</tr>
<tal:block metal:use-macro="here/PdmZuite_CommonTemplate/macros/toggleSaleSupplyLineBasePricePerSlice" />
<tal:block metal:use-macro="here/PdmZuite_CommonTemplate/macros/enterAndCheckPricePerSliceInSupplyLine" />
<!-- Open Delivery Line with the product and check price is correct -->
<tr>
<td>open</td>
<td tal:content="string:$${base_url}/sale_packing_list_module/erp5_pdm_ui_test_delivery/1" />
<td></td>
</tr>
<tr>
<td>type</td>
<td>//input[@name="field_my_quantity"]</td>
<td>15</td>
</tr>
<tr>
<td>type</td>
<td>//input[@name="field_my_price"]</td>
<td></td>
</tr>
<tr>
<td>clickAndWait</td>
<td>Base_edit:method</td>
<td></td>
</tr>
<tr>
<td>assertFloatValue</td>
<td>//input[@name="field_my_price"]</td>
<td>9</td>
</tr>
</tbody></table>
</body>
</html>
\ No newline at end of file
......@@ -71,4 +71,82 @@
<td></td>
</tr>
</tal:block>
<tal:block metal:define-macro="toggleSaleSupplyLineBasePricePerSlice">
<tr>
<td>click</td>
<td>//input[@name="field_my_sale_supply_line_base_price_per_slice"]</td>
<td></td>
</tr>
<tr>
<td>clickAndWait</td>
<td>Base_edit:method</td>
<td></td>
</tr>
</tal:block>
<tal:block metal:define-macro="togglePurchaseSupplyLineBasePricePerSlice">
<tr>
<td>click</td>
<td>//input[@name="field_my_purchase_supply_line_base_price_per_slice"]</td>
<td></td>
</tr>
<tr>
<td>clickAndWait</td>
<td>Base_edit:method</td>
<td></td>
</tr>
</tal:block>
<tal:block metal:define-macro="toggleInternalSupplyLineBasePricePerSlice">
<tr>
<td>click</td>
<td>//input[@name="field_my_internal_supply_line_base_price_per_slice"]</td>
<td></td>
</tr>
<tr>
<td>clickAndWait</td>
<td>Base_edit:method</td>
<td></td>
</tr>
</tal:block>
<tal:block metal:define-macro="enterAndCheckPricePerSliceInSupplyLine">
<tr>
<td>type</td>
<td>//input[@name="field_matrixbox_base_price_cell_0_0_0"]</td>
<td>10</td>
</tr>
<tr>
<td>type</td>
<td>//input[@name="field_matrixbox_base_price_cell_1_0_0"]</td>
<td>9</td>
</tr>
<tr>
<td>type</td>
<td>//input[@name="field_matrixbox_base_price_cell_2_0_0"]</td>
<td>8</td>
</tr>
<tr>
<td>clickAndWait</td>
<td>Base_edit:method</td>
<td></td>
</tr>
<tr>
<td>assertFloatValue</td>
<td>//input[@name="field_matrixbox_base_price_cell_0_0_0"]</td>
<td>10</td>
</tr>
<tr>
<td>assertFloatValue</td>
<td>//input[@name="field_matrixbox_base_price_cell_1_0_0"]</td>
<td>9</td>
</tr>
<tr>
<td>assertFloatValue</td>
<td>//input[@name="field_matrixbox_base_price_cell_2_0_0"]</td>
<td>8</td>
</tr>
<tr>
<td>open</td>
<td>${base_url}/Zuite_waitForActivities</td>
<td></td>
</tr>
</tal:block>
</tal:block>
\ No newline at end of file
from DateTime import DateTime
portal = context.getPortalObject()
order_portal_type = "Sale Order"
order_line_portal_type = "Sale Order Line"
delivery_portal_type = "Sale Packing List"
delivery_line_portal_type = "Sale Packing List Line"
order_portal_type = "%s Order" % delivery_type
order_line_portal_type = "%s Order Line" % delivery_type
delivery_portal_type = "%s Packing List" % delivery_type
delivery_line_portal_type = "%s Packing List Line" % delivery_type
delivery_id = "erp5_pdm_ui_test_delivery"
delivery_title = "erp5_pdm_ui_test_delivery_title"
......@@ -13,10 +13,19 @@ source_node_id = "erp5_pdm_ui_test_source_node"
destination_node_id = "erp5_pdm_ui_test_destination_node"
resource_id = "erp5_pdm_ui_test_product"
business_process = 'business_process_module/erp5_default_business_process'
business_process_id = 'erp5_default_business_process'
quantity = 1
business_process_module = portal.getDefaultModule("Business Process")
business_process = getattr(business_process_module, business_process_id, None)
if business_process is None:
business_process = business_process_module.newContent(
portal_type="Business Process",
id=business_process_id,
reference=business_process_id,
)
# Create an order or a packing list
if state in ['planned', 'ordered']:
module = portal.getDefaultModule(order_portal_type)
......@@ -28,7 +37,7 @@ if state in ['planned', 'ordered']:
source_section='organisation_module/%s' % source_node_id,
destination='organisation_module/%s' % destination_node_id,
destination_section='organisation_module/%s' % destination_node_id,
specialise=business_process,
specialise_value=business_process,
start_date=DateTime(),
)
order_line = order.newContent(
......@@ -51,7 +60,7 @@ else:
source_section='organisation_module/%s' % source_node_id,
destination='organisation_module/%s' % destination_node_id,
destination_section='organisation_module/%s' % destination_node_id,
specialise=business_process,
specialise_value=business_process,
start_date=DateTime(),
)
delivery_line = delivery.newContent(
......
......@@ -50,7 +50,7 @@
</item>
<item>
<key> <string>_params</string> </key>
<value> <string>state</string> </value>
<value> <string>state, delivery_type="Sale"</string> </value>
</item>
<item>
<key> <string>id</string> </key>
......
......@@ -4,9 +4,6 @@ resource_portal_type = "Product"
node_portal_type = "Organisation"
site_portal_type = "Category"
order_portal_type = "Sale Order"
delivery_portal_type = "Sale Packing List"
resource_id = "erp5_pdm_ui_test_product"
source_node_id = "erp5_pdm_ui_test_source_node"
......@@ -35,18 +32,22 @@ for site_id in (source_site_id, destination_site_id):
base_category.manage_delObjects([site_id])
stool = portal.portal_simulation
# Delete order
module = portal.getDefaultModule(order_portal_type)
if getattr(module, delivery_id, None) is not None:
delivery = getattr(module, delivery_id)
stool.manage_delObjects(delivery.getCausalityRelatedIdList(portal_type='Applied Rule'))
module.manage_delObjects([delivery_id])
# Delete delivery
module = portal.getDefaultModule(delivery_portal_type)
if getattr(module, delivery_id, None) is not None:
delivery = getattr(module, delivery_id)
stool.manage_delObjects(delivery.getCausalityRelatedIdList(portal_type='Applied Rule'))
module.manage_delObjects([delivery_id])
for delivery_type in ("Internal", "Purchase", "Sale"):
order_portal_type = delivery_type + " Order"
delivery_portal_type = delivery_type + " Packing List"
# Delete order
module = portal.getDefaultModule(order_portal_type)
if getattr(module, delivery_id, None) is not None:
delivery = getattr(module, delivery_id)
stool.manage_delObjects(delivery.getCausalityRelatedIdList(portal_type='Applied Rule'))
module.manage_delObjects([delivery_id])
# Delete delivery
module = portal.getDefaultModule(delivery_portal_type)
if getattr(module, delivery_id, None) is not None:
delivery = getattr(module, delivery_id)
stool.manage_delObjects(delivery.getCausalityRelatedIdList(portal_type='Applied Rule'))
module.manage_delObjects([delivery_id])
return "Deleted Successfully."
......@@ -15,18 +15,28 @@ source_site_title = "erp5_pdm_ui_test_source_site_title"
destination_site_id = "erp5_pdm_ui_test_destination_site"
destination_site_title = "erp5_pdm_ui_test_destination_site_title"
quantity_unit_category = portal.portal_categories.quantity_unit
# validate rules
for rule in portal.portal_rules.objectValues():
if rule.getValidationState() != 'validated':
rule.validate()
# Create resource
if getattr(quantity_unit_category, "unit", None) is None:
quantity_unit_category.newContent(
portal_type="Category",
id="unit"
)
module = portal.getDefaultModule(resource_portal_type)
resource = module.newContent(
portal_type=resource_portal_type,
id=resource_id,
title=resource_title
title=resource_title,
quantity_unit='unit',
)
resource.validate()
# Create site categories
base_category = portal.restrictedTraverse('portal_categories/site')
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ZopePageTemplate" module="Products.PageTemplates.ZopePageTemplate"/>
</pickle>
<pickle>
<dictionary>
<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_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>content_type</string> </key>
<value> <string>text/html</string> </value>
</item>
<item>
<key> <string>expand</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>testInternalSupplyLinePricePerSlice</string> </value>
</item>
<item>
<key> <string>output_encoding</string> </key>
<value> <string>utf-8</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <unicode></unicode> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<html>
<head><title>Test toggling price per slice updates internal supply cells correctly</title></head>
<body>
<table cellpadding="1" cellspacing="1" border="1">
<thead>
<tr><td rowspan="1" colspan="4">
Test quantity steps for price on internal supply line
</td></tr>
</thead>
<tbody tal:define="init_method string:PdmZuite_createDelivery?state=draft&delivery_type=Internal">
<!-- Setup {{{ -->
<tal:block metal:use-macro="here/PdmZuite_CommonTemplate/macros/init" />
<tr>
<td>open</td>
<td>${base_url}/Zuite_deleteDataForTradeZuite</td>
<td></td>
</tr>
<tr>
<td>assertTextPresent</td>
<td>Deleted Successfully.</td>
<td></td>
</tr>
<tr>
<td>open</td>
<td>${base_url}/Zuite_waitForActivities</td>
<td></td>
</tr>
<tr>
<td>assertTextPresent</td>
<td>Done.</td>
<td></td>
</tr>
<tr>
<td>open</td>
<td>${base_url}/Zuite_resetForTradeZuite</td>
<td></td>
</tr>
<tr>
<td>assertTextPresent</td>
<td>Reset Successfully.</td>
<td></td>
</tr>
<tr>
<td>open</td>
<td tal:content="string:$${base_url}/Zuite_createTradeConditionForTradeZuite?delivery_type=Internal" />
<td></td>
</tr>
<tr>
<td>assertTextPresent</td>
<td>Internal Trade Condition Created.</td>
<td></td>
</tr>
<tr>
<td>open</td>
<td>${base_url}/Zuite_waitForActivities</td>
<td></td>
</tr>
<tr>
<td>assertTextPresent</td>
<td>Done.</td>
<td></td>
</tr>
<!-- }}} -->
<tr>
<td>open</td>
<td tal:content="string:$${base_url}/internal_trade_condition_module/erp5_trade_ui_test_trade_condition/1" />
<td></td>
</tr>
<tr>
<td>type</td>
<td>field_my_base_unit_price</td>
<td>0.00001</td>
</tr>
<tr>
<td>clickAndWait</td>
<td>Base_edit:method</td>
<td></td>
</tr>
<tr>
<td>clickAndWait</td>
<td>link=Base Price</td>
<td></td>
</tr>
<!-- Enter quantity step list and check -->
<tr>
<td>type</td>
<td>field_my_quantity_step_list</td>
<td>11<br />21</td>
</tr>
<tr>
<td>clickAndWait</td>
<td>Base_edit:method</td>
<td></td>
</tr>
<tr>
<td>assertText</td>
<td>field_my_quantity_step_list</td>
<td>11.0 21.0</td>
<tr>
<td>assertText</td>
<td>//input[@name="field_matrixbox_base_price_cell_0_0_0"]/../../../td[1]</td>
<td>Quantity &lt; 11.0</td>
</tr>
<tr>
<td>assertText</td>
<td>//input[@name="field_matrixbox_base_price_cell_1_0_0"]/../../../td[1]</td>
<td>11.0 &lt;= Quantity &lt; 21.0</td>
</tr>
<tr>
<td>assertText</td>
<td>//input[@name="field_matrixbox_base_price_cell_2_0_0"]/../../../td[1]</td>
<td>21.0 &lt;= Quantity</td>
</tr>
<tr>
<!-- Enter price per quantity step and check-->
<tal:block metal:use-macro="here/PdmZuite_CommonTemplate/macros/enterAndCheckPricePerSliceInSupplyLine" />
<!-- Open Delivery Line with the product and check price is correct -->
<tr>
<td>open</td>
<td tal:content="string:$${base_url}/internal_packing_list_module/erp5_pdm_ui_test_delivery/1" />
<td></td>
</tr>
<tr>
<td>type</td>
<td>//input[@name="field_my_quantity"]</td>
<td>15</td>
</tr>
<tr>
<td>type</td>
<td>//input[@name="field_my_price"]</td>
<td></td>
</tr>
<tr>
<td>clickAndWait</td>
<td>Base_edit:method</td>
<td></td>
</tr>
<tr>
<td>assertFloatValue</td>
<td>//input[@name="field_my_price"]</td>
<td>9</td>
</tr>
<!-- Select the new method "Price per slice" on the Internal Supply
and enter the prices again-->
<tr>
<td>open</td>
<td>${base_url}/internal_trade_condition_module/erp5_trade_ui_test_trade_condition/1/InternalSupplyLine_viewBasePrice</td>
<td></td>
</tr>
<tal:block metal:use-macro="here/Zuite_CommonTemplateForTradeZuite/macros/toggleSupplyLineBasePricePerSlice" />
<tal:block metal:use-macro="here/PdmZuite_CommonTemplate/macros/enterAndCheckPricePerSliceInSupplyLine" />
<!-- Open Delivery Line with the product and check price is correct -->
<tr>
<td>open</td>
<td tal:content="string:$${base_url}/internal_packing_list_module/erp5_pdm_ui_test_delivery/1" />
<td></td>
</tr>
<tr>
<td>type</td>
<td>//input[@name="field_my_quantity"]</td>
<td>15</td>
</tr>
<tr>
<td>type</td>
<td>//input[@name="field_my_price"]</td>
<td></td>
</tr>
<tr>
<td>clickAndWait</td>
<td>Base_edit:method</td>
<td></td>
</tr>
<tr>
<td>assertFloatValue</td>
<td>//input[@name="field_my_price"]</td>
<td>9.66667</td>
</tr>
<!-- Unselect the new method "Price per slice" on the Internal Supply
and enter the prices again-->
<tr>
<td>open</td>
<td>${base_url}/internal_trade_condition_module/erp5_trade_ui_test_trade_condition/1/InternalSupplyLine_viewBasePrice</td>
<td></td>
</tr>
<tal:block metal:use-macro="here/Zuite_CommonTemplateForTradeZuite/macros/toggleSupplyLineBasePricePerSlice" />
<tal:block metal:use-macro="here/PdmZuite_CommonTemplate/macros/enterAndCheckPricePerSliceInSupplyLine" />
<!-- Open Delivery Line with the product and check price is correct -->
<tr>
<td>open</td>
<td tal:content="string:$${base_url}/internal_packing_list_module/erp5_pdm_ui_test_delivery/1" />
<td></td>
</tr>
<tr>
<td>type</td>
<td>//input[@name="field_my_quantity"]</td>
<td>15</td>
</tr>
<tr>
<td>type</td>
<td>//input[@name="field_my_price"]</td>
<td></td>
</tr>
<tr>
<td>clickAndWait</td>
<td>Base_edit:method</td>
<td></td>
</tr>
<tr>
<td>assertFloatValue</td>
<td>//input[@name="field_my_price"]</td>
<td>9</td>
</tr>
</tbody></table>
</body>
</html>
\ No newline at end of file
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ZopePageTemplate" module="Products.PageTemplates.ZopePageTemplate"/>
</pickle>
<pickle>
<dictionary>
<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_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>content_type</string> </key>
<value> <string>text/html</string> </value>
</item>
<item>
<key> <string>expand</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>testPurchaseSupplyLinePricePerSlice</string> </value>
</item>
<item>
<key> <string>output_encoding</string> </key>
<value> <string>utf-8</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <unicode></unicode> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<html>
<head><title>Test toggling price per slice updates purchase supply cells correctly</title></head>
<body>
<table cellpadding="1" cellspacing="1" border="1">
<thead>
<tr><td rowspan="1" colspan="4">
Test quantity steps for price on purchase supply line
</td></tr>
</thead>
<tbody tal:define="init_method string:PdmZuite_createDelivery?state=draft&delivery_type=Purchase">
<!-- Setup {{{ -->
<tal:block metal:use-macro="here/PdmZuite_CommonTemplate/macros/init" />
<tr>
<td>open</td>
<td>${base_url}/Zuite_deleteDataForTradeZuite</td>
<td></td>
</tr>
<tr>
<td>assertTextPresent</td>
<td>Deleted Successfully.</td>
<td></td>
</tr>
<tr>
<td>open</td>
<td>${base_url}/Zuite_waitForActivities</td>
<td></td>
</tr>
<tr>
<td>assertTextPresent</td>
<td>Done.</td>
<td></td>
</tr>
<tr>
<td>open</td>
<td>${base_url}/Zuite_resetForTradeZuite</td>
<td></td>
</tr>
<tr>
<td>assertTextPresent</td>
<td>Reset Successfully.</td>
<td></td>
</tr>
<tr>
<td>open</td>
<td tal:content="string:$${base_url}/Zuite_createTradeConditionForTradeZuite?delivery_type=Purchase" />
<td></td>
</tr>
<tr>
<td>assertTextPresent</td>
<td>Purchase Trade Condition Created.</td>
<td></td>
</tr>
<tr>
<td>open</td>
<td>${base_url}/Zuite_waitForActivities</td>
<td></td>
</tr>
<tr>
<td>assertTextPresent</td>
<td>Done.</td>
<td></td>
</tr>
<!-- }}} -->
<tr>
<td>open</td>
<td tal:content="string:$${base_url}/purchase_trade_condition_module/erp5_trade_ui_test_trade_condition/1" />
<td></td>
</tr>
<tr>
<td>type</td>
<td>field_my_base_unit_price</td>
<td>0.00001</td>
</tr>
<tr>
<td>clickAndWait</td>
<td>Base_edit:method</td>
<td></td>
</tr>
<tr>
<td>clickAndWait</td>
<td>link=Base Price</td>
<td></td>
</tr>
<!-- Enter quantity step list and check -->
<tr>
<td>type</td>
<td>field_my_quantity_step_list</td>
<td>11<br />21</td>
</tr>
<tr>
<td>clickAndWait</td>
<td>Base_edit:method</td>
<td></td>
</tr>
<tr>
<td>assertText</td>
<td>field_my_quantity_step_list</td>
<td>11.0 21.0</td>
<tr>
<td>assertText</td>
<td>//input[@name="field_matrixbox_base_price_cell_0_0_0"]/../../../td[1]</td>
<td>Quantity &lt; 11.0</td>
</tr>
<tr>
<td>assertText</td>
<td>//input[@name="field_matrixbox_base_price_cell_1_0_0"]/../../../td[1]</td>
<td>11.0 &lt;= Quantity &lt; 21.0</td>
</tr>
<tr>
<td>assertText</td>
<td>//input[@name="field_matrixbox_base_price_cell_2_0_0"]/../../../td[1]</td>
<td>21.0 &lt;= Quantity</td>
</tr>
<tr>
<!-- Enter price per quantity step and check-->
<tal:block metal:use-macro="here/PdmZuite_CommonTemplate/macros/enterAndCheckPricePerSliceInSupplyLine" />
<!-- Open Delivery Line with the product and check price is correct -->
<tr>
<td>open</td>
<td tal:content="string:$${base_url}/purchase_packing_list_module/erp5_pdm_ui_test_delivery/1" />
<td></td>
</tr>
<tr>
<td>type</td>
<td>//input[@name="field_my_quantity"]</td>
<td>15</td>
</tr>
<tr>
<td>type</td>
<td>//input[@name="field_my_price"]</td>
<td></td>
</tr>
<tr>
<td>clickAndWait</td>
<td>Base_edit:method</td>
<td></td>
</tr>
<tr>
<td>assertFloatValue</td>
<td>//input[@name="field_my_price"]</td>
<td>9</td>
</tr>
<!-- Select the new method "Price per slice" on the Purchase Supply
and enter the prices again-->
<tr>
<td>open</td>
<td>${base_url}/purchase_trade_condition_module/erp5_trade_ui_test_trade_condition/1/PurchaseSupplyLine_viewBasePrice</td>
<td></td>
</tr>
<tal:block metal:use-macro="here/Zuite_CommonTemplateForTradeZuite/macros/toggleSupplyLineBasePricePerSlice" />
<tal:block metal:use-macro="here/PdmZuite_CommonTemplate/macros/enterAndCheckPricePerSliceInSupplyLine" />
<!-- Open Delivery Line with the product and check price is correct -->
<tr>
<td>open</td>
<td tal:content="string:$${base_url}/purchase_packing_list_module/erp5_pdm_ui_test_delivery/1" />
<td></td>
</tr>
<tr>
<td>type</td>
<td>//input[@name="field_my_quantity"]</td>
<td>15</td>
</tr>
<tr>
<td>type</td>
<td>//input[@name="field_my_price"]</td>
<td></td>
</tr>
<tr>
<td>clickAndWait</td>
<td>Base_edit:method</td>
<td></td>
</tr>
<tr>
<td>assertFloatValue</td>
<td>//input[@name="field_my_price"]</td>
<td>9.66667</td>
</tr>
<!-- Unselect the new method "Price per slice" on the Purchase Supply
and enter the prices again-->
<tr>
<td>open</td>
<td>${base_url}/purchase_trade_condition_module/erp5_trade_ui_test_trade_condition/1/PurchaseSupplyLine_viewBasePrice</td>
<td></td>
</tr>
<tal:block metal:use-macro="here/Zuite_CommonTemplateForTradeZuite/macros/toggleSupplyLineBasePricePerSlice" />
<tal:block metal:use-macro="here/PdmZuite_CommonTemplate/macros/enterAndCheckPricePerSliceInSupplyLine" />
<!-- Open Delivery Line with the product and check price is correct -->
<tr>
<td>open</td>
<td tal:content="string:$${base_url}/purchase_packing_list_module/erp5_pdm_ui_test_delivery/1" />
<td></td>
</tr>
<tr>
<td>type</td>
<td>//input[@name="field_my_quantity"]</td>
<td>15</td>
</tr>
<tr>
<td>type</td>
<td>//input[@name="field_my_price"]</td>
<td></td>
</tr>
<tr>
<td>clickAndWait</td>
<td>Base_edit:method</td>
<td></td>
</tr>
<tr>
<td>assertFloatValue</td>
<td>//input[@name="field_my_price"]</td>
<td>9</td>
</tr>
</tbody></table>
</body>
</html>
\ No newline at end of file
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ZopePageTemplate" module="Products.PageTemplates.ZopePageTemplate"/>
</pickle>
<pickle>
<dictionary>
<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_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>content_type</string> </key>
<value> <string>text/html</string> </value>
</item>
<item>
<key> <string>expand</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>testSaleSupplyLinePricePerSlice</string> </value>
</item>
<item>
<key> <string>output_encoding</string> </key>
<value> <string>utf-8</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <unicode></unicode> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<html>
<head><title>Test toggling price per slice updates sale supply cells correctly</title></head>
<body>
<table cellpadding="1" cellspacing="1" border="1">
<thead>
<tr><td rowspan="1" colspan="4">
Test quantity steps for price on sale supply line
</td></tr>
</thead>
<tbody tal:define="init_method string:PdmZuite_createDelivery?state=draft">
<!-- Setup {{{ -->
<tal:block metal:use-macro="here/PdmZuite_CommonTemplate/macros/init" />
<tr>
<td>open</td>
<td>${base_url}/Zuite_deleteDataForTradeZuite</td>
<td></td>
</tr>
<tr>
<td>assertTextPresent</td>
<td>Deleted Successfully.</td>
<td></td>
</tr>
<tr>
<td>open</td>
<td>${base_url}/Zuite_waitForActivities</td>
<td></td>
</tr>
<tr>
<td>assertTextPresent</td>
<td>Done.</td>
<td></td>
</tr>
<tr>
<td>open</td>
<td>${base_url}/Zuite_resetForTradeZuite</td>
<td></td>
</tr>
<tr>
<td>assertTextPresent</td>
<td>Reset Successfully.</td>
<td></td>
</tr>
<tr>
<td>open</td>
<td tal:content="string:$${base_url}/Zuite_createTradeConditionForTradeZuite" />
<td></td>
</tr>
<tr>
<td>assertTextPresent</td>
<td>Sale Trade Condition Created.</td>
<td></td>
</tr>
<tr>
<td>open</td>
<td>${base_url}/Zuite_waitForActivities</td>
<td></td>
</tr>
<tr>
<td>assertTextPresent</td>
<td>Done.</td>
<td></td>
</tr>
<!-- }}} -->
<tr>
<td>open</td>
<td tal:content="string:$${base_url}/sale_trade_condition_module/erp5_trade_ui_test_trade_condition/1" />
<td></td>
</tr>
<tr>
<td>type</td>
<td>field_my_base_unit_price</td>
<td>0.00001</td>
</tr>
<tr>
<td>clickAndWait</td>
<td>Base_edit:method</td>
<td></td>
</tr>
<tr>
<td>clickAndWait</td>
<td>link=Base Price</td>
<td></td>
</tr>
<!-- Enter quantity step list and check -->
<tr>
<td>type</td>
<td>field_my_quantity_step_list</td>
<td>11<br />21</td>
</tr>
<tr>
<td>clickAndWait</td>
<td>Base_edit:method</td>
<td></td>
</tr>
<tr>
<td>assertText</td>
<td>field_my_quantity_step_list</td>
<td>11.0 21.0</td>
<tr>
<td>assertText</td>
<td>//input[@name="field_matrixbox_base_price_cell_0_0_0"]/../../../td[1]</td>
<td>Quantity &lt; 11.0</td>
</tr>
<tr>
<td>assertText</td>
<td>//input[@name="field_matrixbox_base_price_cell_1_0_0"]/../../../td[1]</td>
<td>11.0 &lt;= Quantity &lt; 21.0</td>
</tr>
<tr>
<td>assertText</td>
<td>//input[@name="field_matrixbox_base_price_cell_2_0_0"]/../../../td[1]</td>
<td>21.0 &lt;= Quantity</td>
</tr>
<tr>
<!-- Enter price per quantity step and check-->
<tal:block metal:use-macro="here/PdmZuite_CommonTemplate/macros/enterAndCheckPricePerSliceInSupplyLine" />
<!-- Open Delivery Line with the product and check price is correct -->
<tr>
<td>open</td>
<td tal:content="string:$${base_url}/sale_packing_list_module/erp5_pdm_ui_test_delivery/1" />
<td></td>
</tr>
<tr>
<td>type</td>
<td>//input[@name="field_my_quantity"]</td>
<td>15</td>
</tr>
<tr>
<td>type</td>
<td>//input[@name="field_my_price"]</td>
<td></td>
</tr>
<tr>
<td>clickAndWait</td>
<td>Base_edit:method</td>
<td></td>
</tr>
<tr>
<td>assertFloatValue</td>
<td>//input[@name="field_my_price"]</td>
<td>9</td>
</tr>
<!-- Select the new method "Price per slice" on the Sale Supply
and enter the prices again-->
<tr>
<td>open</td>
<td>${base_url}/sale_trade_condition_module/erp5_trade_ui_test_trade_condition/1/SaleSupplyLine_viewBasePrice</td>
<td></td>
</tr>
<tal:block metal:use-macro="here/Zuite_CommonTemplateForTradeZuite/macros/toggleSupplyLineBasePricePerSlice" />
<tal:block metal:use-macro="here/PdmZuite_CommonTemplate/macros/enterAndCheckPricePerSliceInSupplyLine" />
<!-- Open Delivery Line with the product and check price is correct -->
<tr>
<td>open</td>
<td tal:content="string:$${base_url}/sale_packing_list_module/erp5_pdm_ui_test_delivery/1" />
<td></td>
</tr>
<tr>
<td>type</td>
<td>//input[@name="field_my_quantity"]</td>
<td>15</td>
</tr>
<tr>
<td>type</td>
<td>//input[@name="field_my_price"]</td>
<td></td>
</tr>
<tr>
<td>clickAndWait</td>
<td>Base_edit:method</td>
<td></td>
</tr>
<tr>
<td>assertFloatValue</td>
<td>//input[@name="field_my_price"]</td>
<td>9.66667</td>
</tr>
<!-- Unselect the new method "Price per slice" on the Sale Supply
and enter the prices again-->
<tr>
<td>open</td>
<td>${base_url}/sale_trade_condition_module/erp5_trade_ui_test_trade_condition/1/SaleSupplyLine_viewBasePrice</td>
<td></td>
</tr>
<tal:block metal:use-macro="here/Zuite_CommonTemplateForTradeZuite/macros/toggleSupplyLineBasePricePerSlice" />
<tal:block metal:use-macro="here/PdmZuite_CommonTemplate/macros/enterAndCheckPricePerSliceInSupplyLine" />
<!-- Open Delivery Line with the product and check price is correct -->
<tr>
<td>open</td>
<td tal:content="string:$${base_url}/sale_packing_list_module/erp5_pdm_ui_test_delivery/1" />
<td></td>
</tr>
<tr>
<td>type</td>
<td>//input[@name="field_my_quantity"]</td>
<td>15</td>
</tr>
<tr>
<td>type</td>
<td>//input[@name="field_my_price"]</td>
<td></td>
</tr>
<tr>
<td>clickAndWait</td>
<td>Base_edit:method</td>
<td></td>
</tr>
<tr>
<td>assertFloatValue</td>
<td>//input[@name="field_my_price"]</td>
<td>9</td>
</tr>
</tbody></table>
</body>
</html>
\ No newline at end of file
......@@ -66,4 +66,16 @@
<td></td>
</tr>
</tal:block>
<tal:block metal:define-macro="toggleSupplyLineBasePricePerSlice">
<tr>
<td>click</td>
<td>//input[@name="field_my_base_price_per_slice"]</td>
<td></td>
</tr>
<tr>
<td>clickAndWait</td>
<td>Base_edit:method</td>
<td></td>
</tr>
</tal:block>
</tal:block>
\ No newline at end of file
from DateTime import DateTime
portal = context.getPortalObject()
trade_condition_portal_type = "%s Trade Condition" % delivery_type
supply_line_portal_type = "%s Supply Line" % delivery_type
trade_condition_id = "erp5_trade_ui_test_trade_condition"
trade_condition_title = "erp5_trade_ui_test_trade_condition_title"
resource_id = "erp5_pdm_ui_test_product"
delivery_portal_type = "%s Packing List" % delivery_type
# Create Trade Condition
module = portal.getDefaultModule(trade_condition_portal_type)
trade_condition = module.newContent(
portal_type=trade_condition_portal_type,
id=trade_condition_id,
title=trade_condition_title,
)
trade_condition.newContent(
portal_type=supply_line_portal_type,
resource="product_module/" + resource_id
)
trade_condition.validate()
# Set it as specialise to the Delivery created by PdmZuite_createDelivery
module = portal.getDefaultModule(delivery_portal_type)
delivery = getattr(module, "erp5_pdm_ui_test_delivery", None)
if delivery is not None:
delivery.setSpecialiseValue(trade_condition)
else:
raise ValueError('Delivery not found')
return trade_condition_portal_type + " Created."
<?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>_params</string> </key>
<value> <string>delivery_type="Sale"</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Zuite_createTradeConditionForTradeZuite</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
try:
context.sale_order_module.manage_delObjects(ids=['erp5_trade_ui_test_sale_order_1'])
except:
pass
portal = context.getPortalObject()
object_value_list = [
getattr(context.sale_order_module, 'erp5_trade_ui_test_sale_order_1', None)
] + [
getattr(portal.getDefaultModule(portal_type), "erp5_trade_ui_test_trade_condition", None)
for portal_type in ("Internal Trade Condition", "Purchase Trade Condition", "Sale Trade Condition")
]
for object_value in object_value_list:
if object_value is None:
continue
object_value.getParentValue().manage_delObjects(ids=[object_value.getId()])
return "Deleted Successfully."
##############################################################################
#
# Copyright (c) 2017 Nexedi SARL and Contributors. All Rights Reserved.
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
import unittest
from Products.ERP5Type.tests.ERP5TypeFunctionalTestCase import ERP5TypeFunctionalTestCase
class TestFunctionalPDM(ERP5TypeFunctionalTestCase):
foreground = 0
run_only = "trade_zuite"
def test_suite():
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(TestFunctionalPDM))
return suite
\ No newline at end of file
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Test Component" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_recorded_property_dict</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>default_reference</string> </key>
<value> <string>testFunctionalTrade</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>Run UI tests for Trade</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>test.erp5.testFunctionalTrade</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Test Component</string> </value>
</item>
<item>
<key> <string>sid</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>text_content_error_message</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>text_content_warning_message</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>version</string> </key>
<value> <string>erp5</string> </value>
</item>
<item>
<key> <string>workflow_history</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary/>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary>
<item>
<key> <string>component_validation_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="4" aka="AAAAAAAAAAQ=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.patches.WorkflowTool"/>
</pickle>
<pickle>
<tuple>
<none/>
<list>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>validate</string> </value>
</item>
<item>
<key> <string>validation_state</string> </key>
<value> <string>validated</string> </value>
</item>
</dictionary>
</list>
</tuple>
</pickle>
</record>
</ZopeData>
erp5_pdm_ui_test
erp5_trade
erp5_ui_test
\ No newline at end of file
test.erp5.testFunctionalTrade
\ No newline at end of file
erp5_full_text_mroonga_catalog
\ No newline at end of file
......@@ -712,6 +712,8 @@ class Resource(XMLObject, XMLMatrix, VariatedMixin):
'non_discountable_additional_price': [],
'priced_quantity': None,
'base_unit_price': None,
'slice_base_price': [],
'slice_quantity_range': [],
}
if mapped_value is None:
return price_parameter_dict
......
......@@ -153,7 +153,7 @@ class SupplyLine(Path, Amount, XMLMatrix):
Return predicate id related to a price parameter.
"""
predicate_id_start_with = "quantity_range_"
if price_parameter != "base_price":
if price_parameter not in ("base_price", "slice_base_price"):
predicate_id_start_with = "%s_%s" % \
(price_parameter, predicate_id_start_with)
# XXX Hardcoded portal type name
......@@ -183,12 +183,12 @@ class SupplyLine(Path, Amount, XMLMatrix):
"""
# We need to keep compatibility with generated accessor
price_parameter = kw.get('price_parameter', "base_price")
if price_parameter == "base_price":
if price_parameter in ("base_price", "slice_base_price"):
method_name = "_baseGetQuantityStepList"
else:
method_name = 'get%sList' % \
convertToUpperCase("%s_quantity_step" % price_parameter)
return getattr(self, method_name)()
return getattr(self, method_name)() or []
security.declareProtected(Permissions.ModifyPortalContent,
'updateQuantityPredicate')
......@@ -208,7 +208,7 @@ class SupplyLine(Path, Amount, XMLMatrix):
# With this script, we can change the title of the predicate
script = getattr(self, 'SupplyLine_getTitle', None)
predicate_id_start_with = "quantity_range"
if price_parameter != "base_price":
if price_parameter not in ("base_price", "slice_base_price"):
predicate_id_start_with = "%s_%s" % \
(price_parameter, predicate_id_start_with)
for i in range(0, len(quantity_step_list)-1):
......@@ -218,7 +218,11 @@ class SupplyLine(Path, Amount, XMLMatrix):
p = self.newContent(id='%s_%s' % (predicate_id_start_with, str(i)),
portal_type='Predicate', int_index=i+1)
p.setCriterionPropertyList(('quantity', ))
p.setCriterion('quantity', min=min_quantity, max=max_quantity)
p.setCriterion(
'quantity',
min=min_quantity,
max=(None if price_parameter == 'slice_base_price' else max_quantity)
)
if script is not None:
title = script(min=min_quantity, max=max_quantity)
p.setTitle(title)
......
......@@ -303,7 +303,7 @@ class DomainTool(BaseTool):
# (some users are not able to see resource's price)
security.declarePublic('generateMultivaluedMappedValue')
def generateMultivaluedMappedValue(self, context, test=1,
predicate_list=None, explanation_only=0, **kw):
predicate_list=None, **kw):
"""
We will generate a mapped value with the list of all predicates
found.
......@@ -320,22 +320,13 @@ class DomainTool(BaseTool):
if predicate_list:
from Products.ERP5Type.Document import newTempSupplyCell
mapped_value_property_dict = defaultdict(list)
explanation_dict = defaultdict(dict)
# Look for each property the first predicate with unique criterion
# categories which defines the property
for predicate in predicate_list:
full_prop_dict = explanation_dict[
tuple(predicate.getMembershipCriterionCategoryList())]
for mapped_value_property in predicate.getMappedValuePropertyList():
if mapped_value_property in full_prop_dict:
# we already have one value for this (categories, property)
continue
value = predicate.getProperty(mapped_value_property)
if value is not None:
full_prop_dict[mapped_value_property] = value
mapped_value_property_dict[mapped_value_property].append(value)
if explanation_only:
return dict(explanation_dict)
mapped_value = newTempSupplyCell(self.getPortalObject(),
'multivalued_mapped_value')
mapped_value._setMappedValuePropertyList(
......
......@@ -54,6 +54,7 @@
<value>
<tuple>
<string>base_price</string>
<string>base_price_per_slice</string>
<string>id</string>
<string>priced_quantity</string>
<string>price_currency</string>
......
......@@ -54,6 +54,7 @@
<value>
<tuple>
<string>base_price</string>
<string>base_price_per_slice</string>
<string>id</string>
<string>priced_quantity</string>
<string>price_currency</string>
......
......@@ -54,6 +54,7 @@
<value>
<tuple>
<string>base_price</string>
<string>base_price_per_slice</string>
<string>id</string>
<string>priced_quantity</string>
<string>price_currency</string>
......
......@@ -36,6 +36,7 @@
<value>
<tuple>
<string>base_price</string>
<string>base_price_per_slice</string>
<string>id</string>
<string>priced_quantity</string>
<string>price_currency</string>
......
<?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>categories</string> </key>
<value>
<tuple>
<string>elementary_type/boolean</string>
</tuple>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string encoding="cdata"><![CDATA[
Defines if the base_price of maching quantity step should be used as unit price for all items (value is False), or if it applies only to items of the range (value is True).\n
\n
If this property is set to True, the base_price will be calculated as such :\n
if 0->10 products cost 10$, and 11->infinity products cost 9$, in a order of 15 products, the unit base price is 9.6667$, as the 10 first products cost 10$, and the 5 others cost 9$ (and (10*10+5*9)/15 = 9.6667)
]]></string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>base_price_per_slice_property</string> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Standard Property</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?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/object</string>
</tuple>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>A per unit base price applying to the products whose quantity is in slice. This per unit base price will be weighted with the per unit base price of other slices.\n
\n
This property is useful for the following case :\n
0-10 products cost 10$, and 11-inf products cost 9$. Thus in a order of 15 products, the unit base price is 9.6667$, as 10 * 10 + 5 * 9 = 145, and 145 / 15 = 9.6667</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>slice_base_price_property</string> </value>
</item>
<item>
<key> <string>mode</string> </key>
<value> <string>w</string> </value>
</item>
<item>
<key> <string>multivalued</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Standard Property</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?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/object</string>
</tuple>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string>quantiy range of the items for which the slice_base_price will be applied if base_price_per_slice is True.\n
\n
slice_quantity_range is a 2-tuple : (min_bound, max_bound)</string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>slice_quantity_range_property</string> </value>
</item>
<item>
<key> <string>mode</string> </key>
<value> <string>w</string> </value>
</item>
<item>
<key> <string>multivalued</string> </key>
<value> <int>0</int> </value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Standard Property</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -1127,6 +1127,115 @@ class TestResource(ERP5TypeTestCase):
# resource_b is member of product_line/b, so our supply line does not apply.
self.assertEqual(None, sale_order_line.getPrice())
def testGetPriceWithBasePriceDefinedPerSlice(self):
"""
Slices allow to apply a different price per item given the quantity of this
item ordered. See exemple
[unit quantity] [price defined for the units of this slice]
0 -> 10 = 10 currency/unit
11 -> 20 = 9 currency/unit
21 -> inf = 8 currency/unit
So the price for an order of X unit is :
unit -> total order price -> price / unit
9 -> 90 currency -> 10 currency/unit
15 -> 10*10+5*9 = 145 currency -> 9.66667 currency/unit
25 -> 20*10+10*9+5*8 = 230 currency -> 9.2 currency/unit
"""
product_module = self.portal.getDefaultModule(self.product_portal_type)
product = product_module.newContent(
portal_type=self.product_portal_type,
title='FakeProduct'
)
product.validate()
sale_supply = self.portal.getDefaultModule(
self.sale_supply_portal_type
).newContent(
self.sale_supply_portal_type,
base_price_per_slice=True,
)
supply_line = sale_supply.newContent(
portal_type=self.sale_supply_line_portal_type,
resource_value=product,
base_unit_price=0.00001,
)
supply_line.setQuantityStepList((11, 21))
supply_line.updateCellRange()
cell0 = supply_line.newContent(
portal_type=self.sale_supply_cell_portal_type,
id='path_0',
slice_base_price=10.,
slice_quantity_range=(1, 11),
)
cell0.setCriterionPropertyList(('quantity', ))
cell0.setCriterion('quantity', min=1, max=None)
cell0.setMappedValuePropertyList(
["slice_base_price", "slice_quantity_range", "base_price", "base_unit_price"]
)
cell1 = supply_line.newContent(
portal_type=self.sale_supply_cell_portal_type,
id='path_1',
slice_base_price=9.,
slice_quantity_range=(11, 21),
)
cell1.setCriterionPropertyList(('quantity', ))
cell1.setCriterion('quantity', min=11, max=None)
cell1.setMappedValuePropertyList(
["slice_base_price", "slice_quantity_range", "base_price", "base_unit_price"]
)
cell2 = supply_line.newContent(
portal_type=self.sale_supply_cell_portal_type,
id='path_2',
slice_base_price=8.,
slice_quantity_range=(21, None),
)
cell2.setCriterionPropertyList(('quantity', ))
cell2.setCriterion('quantity', min=21, max=None)
cell2.setMappedValuePropertyList(
["slice_base_price", "slice_quantity_range", "base_price", "base_unit_price"]
)
sale_supply.validate()
self.tic()
currency_module = self.portal.getDefaultModule("Currency")
currency = currency_module.newContent(
portal_type="Currency",
title='Euro',
base_unit_quantity=0.01,
)
sale_order = self.portal.getDefaultModule("Sale Order").newContent(
portal_type='Sale Order',
specialise_value=sale_supply,
resource_value=currency,
)
def _test(quantity, price, total_price):
sale_order_line = sale_order.newContent(
portal_type=self.sale_order_line_portal_type,
resource_value=product,
quantity=quantity,
)
self.assertEqual(price, sale_order_line.getPrice())
self.assertEqual(
total_price,
round(sale_order_line.getTotalPrice(), currency.getQuantityPrecision())
)
for case in [
{'quantity': 9, 'price': 10., 'total_price': 90.},
{'quantity': 11, 'price': 9.90909, 'total_price': 109.},
{'quantity': 15, 'price': 9.66667, 'total_price': 145.},
{'quantity': 19, 'price': 9.52632, 'total_price': 181.},
{'quantity': 25, 'price': 9.2, 'total_price': 230.},
]:
_test(**case)
def testQuantityPrecision(self):
"""test how to define quantity precision on resources.
......
......@@ -56,8 +56,6 @@ class TestZeleniumCore(ERP5TypeFunctionalTestCase):
'erp5_configurator_standard_invoicing_template',
'erp5_simulation_test',
'erp5_accounting_ui_test',
'erp5_pdm_ui_test',
'erp5_trade_ui_test',
'erp5_project_ui_test',
'erp5_ingestion_mysql_innodb_catalog', 'erp5_ingestion',
'erp5_web', 'erp5_dms', 'erp5_dms_ui_test',
......
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