Commit b0d269b1 by Sebastien Robin

simulation: fully review the way to merge deliveries and enable merge delivery action

Fully rewrite portal_simulation.mergeDeliveryList to use builders to reconstruct new
merged delivery.

Add parameter "merge_delivery" to builder. This parameter is used when
merge should be done in such a way that movement group at delivery
level are ignored
1 parent 2ee779a4
Showing 20 changed files with 395 additions and 325 deletions
...@@ -54,7 +54,7 @@ ...@@ -54,7 +54,7 @@
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
<value> <string>Delivery_mergeDeliveryList</string> </value> <value> <string>DeliveryModule_mergeDeliveryList</string> </value>
</item> </item>
<item> <item>
<key> <string>title</string> </key> <key> <string>title</string> </key>
......
...@@ -2,11 +2,15 @@ ...@@ -2,11 +2,15 @@
<ZopeData> <ZopeData>
<record id="1" aka="AAAAAAAAAAE="> <record id="1" aka="AAAAAAAAAAE=">
<pickle> <pickle>
<global name="ERP5 Form" module="erp5.portal_type"/> <global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle> </pickle>
<pickle> <pickle>
<dictionary> <dictionary>
<item> <item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key> <key> <string>_bind_names</string> </key>
<value> <value>
<object> <object>
...@@ -19,7 +23,24 @@ ...@@ -19,7 +23,24 @@
<item> <item>
<key> <string>_asgns</string> </key> <key> <string>_asgns</string> </key>
<value> <value>
<dictionary/> <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> </value>
</item> </item>
</dictionary> </dictionary>
...@@ -28,119 +49,43 @@ ...@@ -28,119 +49,43 @@
</value> </value>
</item> </item>
<item> <item>
<key> <string>_objects</string> </key> <key> <string>_params</string> </key>
<value>
<tuple/>
</value>
</item>
<item>
<key> <string>action</string> </key>
<value> <string>Delivery_mergeDeliveryList</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value> <string></string> </value> <value> <string></string> </value>
</item> </item>
<item> <item>
<key> <string>edit_order</string> </key> <key> <string>_proxy_roles</string> </key>
<value> <value>
<list/> <tuple>
<string>Manager</string>
</tuple>
</value> </value>
</item> </item>
<item> <item>
<key> <string>encoding</string> </key> <key> <string>guard</string> </key>
<value> <string>UTF-8</string> </value>
</item>
<item>
<key> <string>enctype</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>group_list</string> </key>
<value>
<list>
<string>left</string>
<string>right</string>
<string>center</string>
<string>bottom</string>
<string>hidden</string>
</list>
</value>
</item>
<item>
<key> <string>groups</string> </key>
<value> <value>
<dictionary> <persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
<item>
<key> <string>bottom</string> </key>
<value>
<list>
<string>listbox</string>
</list>
</value>
</item>
<item>
<key> <string>center</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>hidden</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>left</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>right</string> </key>
<value>
<list/>
</value>
</item>
</dictionary>
</value> </value>
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
<value> <string>Delivery_viewMergedDeliveryList</string> </value> <value> <string>Delivery_cleanDeliveryAfterMerge</string> </value>
</item>
<item>
<key> <string>method</string> </key>
<value> <string>POST</string> </value>
</item>
<item>
<key> <string>name</string> </key>
<value> <string>Delivery_viewMergedDeliveryList</string> </value>
</item>
<item>
<key> <string>pt</string> </key>
<value> <string>form_dialog</string> </value>
</item>
<item>
<key> <string>row_length</string> </key>
<value> <int>4</int> </value>
</item>
<item>
<key> <string>stored_encoding</string> </key>
<value> <string>UTF-8</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Merge Deliveries</string> </value>
</item>
<item>
<key> <string>unicode_mode</string> </key>
<value> <int>0</int> </value>
</item> </item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="Guard" module="Products.DCWorkflow.Guard"/>
</pickle>
<pickle>
<dictionary>
<item> <item>
<key> <string>update_action</string> </key> <key> <string>permissions</string> </key>
<value> <string></string> </value> <value>
<tuple>
<string>View</string>
</tuple>
</value>
</item> </item>
</dictionary> </dictionary>
</pickle> </pickle>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ActionInformation" module="Products.CMFCore.ActionInformation"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>action</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>action_type/object_action</string>
</tuple>
</value>
</item>
<item>
<key> <string>category</string> </key>
<value> <string>object_action</string> </value>
</item>
<item>
<key> <string>condition</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>icon</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>merge_delivery_list</string> </value>
</item>
<item>
<key> <string>permissions</string> </key>
<value>
<tuple>
<string>View</string>
</tuple>
</value>
</item>
<item>
<key> <string>priority</string> </key>
<value> <float>1.0</float> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Merge Internal Packing Lists</string> </value>
</item>
<item>
<key> <string>visible</string> </key>
<value> <int>1</int> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="Expression" module="Products.CMFCore.Expression"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>text</string> </key>
<value> <string>string:${object_url}/DeliveryModule_mergeDeliveryList</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ActionInformation" module="Products.CMFCore.ActionInformation"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>action</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>action_type/object_action</string>
</tuple>
</value>
</item>
<item>
<key> <string>category</string> </key>
<value> <string>object_action</string> </value>
</item>
<item>
<key> <string>condition</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>icon</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>merge_delivery_list</string> </value>
</item>
<item>
<key> <string>permissions</string> </key>
<value>
<tuple>
<string>View</string>
</tuple>
</value>
</item>
<item>
<key> <string>priority</string> </key>
<value> <float>1.0</float> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Merge Purchase Packing Lists</string> </value>
</item>
<item>
<key> <string>visible</string> </key>
<value> <int>1</int> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="Expression" module="Products.CMFCore.Expression"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>text</string> </key>
<value> <string>string:${object_url}/DeliveryModule_mergeDeliveryList</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ActionInformation" module="Products.CMFCore.ActionInformation"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>action</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>action_type/object_action</string>
</tuple>
</value>
</item>
<item>
<key> <string>category</string> </key>
<value> <string>object_action</string> </value>
</item>
<item>
<key> <string>condition</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>icon</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>merge_delivery_list</string> </value>
</item>
<item>
<key> <string>permissions</string> </key>
<value>
<tuple>
<string>View</string>
</tuple>
</value>
</item>
<item>
<key> <string>priority</string> </key>
<value> <float>1.0</float> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Merge Sale Packing Lists</string> </value>
</item>
<item>
<key> <string>visible</string> </key>
<value> <int>1</int> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="Expression" module="Products.CMFCore.Expression"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>text</string> </key>
<value> <string>string:${object_url}/DeliveryModule_mergeDeliveryList</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>
<string>sort</string>
<string>title</string>
<string>lines</string>
<string>list_action</string>
<string>selection_name</string>
<string>columns</string>
<string>list_method</string>
</list>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>listbox</string> </value>
</item>
<item>
<key> <string>message_values</string> </key>
<value>
<dictionary>
<item>
<key> <string>external_validator_failed</string> </key>
<value> <string>The input failed the external validator.</string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>overrides</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>tales</string> </key>
<value>
<dictionary>
<item>
<key> <string>field_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>list_method</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>selection_name</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string></string> </value>
</item>
</dictionary>
</value>
</item>
<item>
<key> <string>values</string> </key>
<value>
<dictionary>
<item>
<key> <string>columns</string> </key>
<value>
<list>
<tuple>
<string>id</string>
<string>ID</string>
</tuple>
<tuple>
<string>portal_type</string>
<string>Type</string>
</tuple>
<tuple>
<string>title</string>
<string>Title</string>
</tuple>
<tuple>
<string>relative_url</string>
<string>Path</string>
</tuple>
<tuple>
<string>description</string>
<string>Description</string>
</tuple>
</list>
</value>
</item>
<item>
<key> <string>field_id</string> </key>
<value> <string>my_view_mode_listbox</string> </value>
</item>
<item>
<key> <string>form_id</string> </key>
<value> <string>Base_viewTradeFieldLibrary</string> </value>
</item>
<item>
<key> <string>lines</string> </key>
<value> <int>30</int> </value>
</item>
<item>
<key> <string>list_action</string> </key>
<value> <string>Folder_viewContentList</string> </value>
</item>
<item>
<key> <string>selection_name</string> </key>
<value> <string>delivery_selection</string> </value>
</item>
<item>
<key> <string>sort</string> </key>
<value>
<list>
<tuple>
<string>relative_url</string>
<string>relative_url</string>
</tuple>
</list>
</value>
</item>
<item>
<key> <string>target</string> </key>
<value> <string>Click to edit the target</string> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Merged Deliveries</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="TALESMethod" module="Products.Formulator.TALESField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_text</string> </key>
<value> <string>python:None</string> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="TALESMethod" module="Products.Formulator.TALESField"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_text</string> </key>
<value> <string>here/REQUEST/form/selection_name</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
erp5_core (>= 5.4.3) erp5_core (>= 5.4.3)
erp5_base erp5_base
erp5_pdm
\ No newline at end of file \ No newline at end of file
erp5_pdm
erp5_simulation
\ No newline at end of file \ No newline at end of file
...@@ -35,6 +35,7 @@ Internal Packing List Line | quantity_view ...@@ -35,6 +35,7 @@ Internal Packing List Line | quantity_view
Internal Packing List Line | view Internal Packing List Line | view
Internal Packing List Line | view_price Internal Packing List Line | view_price
Internal Packing List Module | delivery_line_report Internal Packing List Module | delivery_line_report
Internal Packing List Module | merge_delivery_list
Internal Packing List Module | view Internal Packing List Module | view
Internal Packing List Module | workflow_report Internal Packing List Module | workflow_report
Internal Packing List | details Internal Packing List | details
...@@ -105,6 +106,7 @@ Purchase Packing List Line | quantity_view ...@@ -105,6 +106,7 @@ Purchase Packing List Line | quantity_view
Purchase Packing List Line | view Purchase Packing List Line | view
Purchase Packing List Line | view_price Purchase Packing List Line | view_price
Purchase Packing List Module | delivery_line_report Purchase Packing List Module | delivery_line_report
Purchase Packing List Module | merge_delivery_list
Purchase Packing List Module | packing_list_export Purchase Packing List Module | packing_list_export
Purchase Packing List Module | packing_list_report Purchase Packing List Module | packing_list_report
Purchase Packing List Module | view Purchase Packing List Module | view
...@@ -231,6 +233,7 @@ Sale Packing List Line | profile_view ...@@ -231,6 +233,7 @@ Sale Packing List Line | profile_view
Sale Packing List Line | quantity_view Sale Packing List Line | quantity_view
Sale Packing List Line | view Sale Packing List Line | view
Sale Packing List Module | delivery_line_report Sale Packing List Module | delivery_line_report
Sale Packing List Module | merge_delivery_list
Sale Packing List Module | packing_list_export Sale Packing List Module | packing_list_export
Sale Packing List Module | packing_list_report Sale Packing List Module | packing_list_report
Sale Packing List Module | shipment_report Sale Packing List Module | shipment_report
......
...@@ -41,7 +41,7 @@ class CausalityAssignmentMovementGroup(MovementGroup): ...@@ -41,7 +41,7 @@ class CausalityAssignmentMovementGroup(MovementGroup):
def _getPropertyDict(self, movement, **kw): def _getPropertyDict(self, movement, **kw):
return self._addCausalityToEdit(movement) return self._addCausalityToEdit(movement)
def _separate(self, movement_list): def _separate(self, movement_list, **kw):
if not movement_list: if not movement_list:
return [] return []
property_dict = {} property_dict = {}
......
...@@ -81,12 +81,19 @@ class MovementGroup(XMLObject): ...@@ -81,12 +81,19 @@ class MovementGroup(XMLObject):
# This method should be defined in sub classes. # This method should be defined in sub classes.
raise NotImplementedError raise NotImplementedError
def _separate(self, movement_list): def _separate(self, movement_list, merge_delivery=False, **kw):
# By default, we separate movements by _getPropertyDict() values. # By default, we separate movements by _getPropertyDict() values.
# You can override this method in each MovementGroup class. # You can override this method in each MovementGroup class.
tmp_dict = {} tmp_dict = {}
first_property_dict = None
collect_order_group_id = self.getCollectOrderGroupId()
for movement in movement_list: for movement in movement_list:
property_dict = self._getPropertyDict(movement) # We are in the case of merging of deliveries, thus if the movement
# is configured to not split, just take properties of the first movement
if merge_delivery and collect_order_group_id == "delivery":
property_dict = {}
else:
property_dict = self._getPropertyDict(movement, **kw)
# XXX it can be wrong. we need a good way to get hash value, or # XXX it can be wrong. we need a good way to get hash value, or
# we should compare for all pairs. # we should compare for all pairs.
key = repr(property_dict) key = repr(property_dict)
...@@ -96,11 +103,11 @@ class MovementGroup(XMLObject): ...@@ -96,11 +103,11 @@ class MovementGroup(XMLObject):
tmp_dict[key] = [[movement], property_dict] tmp_dict[key] = [[movement], property_dict]
return tmp_dict.values() return tmp_dict.values()
def separate(self, movement_list): def separate(self, movement_list, **kw):
# We sort group of simulation movements by their IDs. # We sort group of simulation movements by their IDs.
# DO NOT OVERRIDE THIS METHOD. Override _separate() instead. # DO NOT OVERRIDE THIS METHOD. Override _separate() instead.
return sorted([[sorted(x[0], key=lambda x: x.getId()), x[1]] \ return sorted([[sorted(x[0], key=lambda x: x.getId()), x[1]] \
for x in self._separate(movement_list)], for x in self._separate(movement_list, **kw)],
key=lambda x: x[0][0].getId()) key=lambda x: x[0][0].getId())
def isBranch(self): def isBranch(self):
......
...@@ -51,7 +51,7 @@ class PropertyAssignmentMovementGroup(MovementGroup): ...@@ -51,7 +51,7 @@ class PropertyAssignmentMovementGroup(MovementGroup):
# We can always update. # We can always update.
return True, property_dict return True, property_dict
def _separate(self, movement_list): def _separate(self, movement_list, **kw):
if not movement_list: if not movement_list:
return [] return []
......
...@@ -44,7 +44,7 @@ class PropertyGroupingMovementGroup(MovementGroup): ...@@ -44,7 +44,7 @@ class PropertyGroupingMovementGroup(MovementGroup):
return True, {} return True, {}
return False, {} return False, {}
def _separate(self, movement_list): def _separate(self, movement_list, **kw):
if not movement_list: if not movement_list:
return [] return []
......
...@@ -61,7 +61,7 @@ class QuantitySignMovementGroup(MovementGroup): ...@@ -61,7 +61,7 @@ class QuantitySignMovementGroup(MovementGroup):
property_dict['quantity_sign'] = cmp(quantity, 0) property_dict['quantity_sign'] = cmp(quantity, 0)
return property_dict return property_dict
def _separate(self, movement_list): def _separate(self, movement_list, **kw):
if not movement_list: if not movement_list:
return [] return []
......
...@@ -57,5 +57,5 @@ class SplitMovementGroup(MovementGroup): ...@@ -57,5 +57,5 @@ class SplitMovementGroup(MovementGroup):
def test(self, document, property_dict, **kw): def test(self, document, property_dict, **kw):