Commit b0d269b1 authored by Sebastien Robin's avatar 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
parent 2ee779a4
......@@ -54,7 +54,7 @@
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Delivery_mergeDeliveryList</string> </value>
<value> <string>DeliveryModule_mergeDeliveryList</string> </value>
</item>
<item>
<key> <string>title</string> </key>
......
<?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></string> </value>
</item>
<item>
<key> <string>_proxy_roles</string> </key>
<value>
<tuple>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>guard</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Delivery_cleanDeliveryAfterMerge</string> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="Guard" module="Products.DCWorkflow.Guard"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>permissions</string> </key>
<value>
<tuple>
<string>View</string>
</tuple>
</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 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="ERP5 Form" module="erp5.portal_type"/>
</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/>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_objects</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>
</item>
<item>
<key> <string>edit_order</string> </key>
<value>
<list/>
</value>
</item>
<item>
<key> <string>encoding</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>
<dictionary>
<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>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>Delivery_viewMergedDeliveryList</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>
<key> <string>update_action</string> </key>
<value> <string></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_base
erp5_pdm
\ No newline at end of file
erp5_pdm
erp5_simulation
\ No newline at end of file
......@@ -35,6 +35,7 @@ Internal Packing List Line | quantity_view
Internal Packing List Line | view
Internal Packing List Line | view_price
Internal Packing List Module | delivery_line_report
Internal Packing List Module | merge_delivery_list
Internal Packing List Module | view
Internal Packing List Module | workflow_report
Internal Packing List | details
......@@ -105,6 +106,7 @@ Purchase Packing List Line | quantity_view
Purchase Packing List Line | view
Purchase Packing List Line | view_price
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_report
Purchase Packing List Module | view
......@@ -231,6 +233,7 @@ Sale Packing List Line | profile_view
Sale Packing List Line | quantity_view
Sale Packing List Line | view
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_report
Sale Packing List Module | shipment_report
......
......@@ -41,7 +41,7 @@ class CausalityAssignmentMovementGroup(MovementGroup):
def _getPropertyDict(self, movement, **kw):
return self._addCausalityToEdit(movement)
def _separate(self, movement_list):
def _separate(self, movement_list, **kw):
if not movement_list:
return []
property_dict = {}
......
......@@ -81,12 +81,19 @@ class MovementGroup(XMLObject):
# This method should be defined in sub classes.
raise NotImplementedError
def _separate(self, movement_list):
def _separate(self, movement_list, merge_delivery=False, **kw):
# By default, we separate movements by _getPropertyDict() values.
# You can override this method in each MovementGroup class.
tmp_dict = {}
first_property_dict = None
collect_order_group_id = self.getCollectOrderGroupId()
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
# we should compare for all pairs.
key = repr(property_dict)
......@@ -96,11 +103,11 @@ class MovementGroup(XMLObject):
tmp_dict[key] = [[movement], property_dict]
return tmp_dict.values()
def separate(self, movement_list):
def separate(self, movement_list, **kw):
# We sort group of simulation movements by their IDs.
# DO NOT OVERRIDE THIS METHOD. Override _separate() instead.
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())
def isBranch(self):
......
......@@ -51,7 +51,7 @@ class PropertyAssignmentMovementGroup(MovementGroup):
# We can always update.
return True, property_dict
def _separate(self, movement_list):
def _separate(self, movement_list, **kw):
if not movement_list:
return []
......
......@@ -44,7 +44,7 @@ class PropertyGroupingMovementGroup(MovementGroup):
return True, {}
return False, {}
def _separate(self, movement_list):
def _separate(self, movement_list, **kw):
if not movement_list:
return []
......
......@@ -61,7 +61,7 @@ class QuantitySignMovementGroup(MovementGroup):
property_dict['quantity_sign'] = cmp(quantity, 0)
return property_dict
def _separate(self, movement_list):
def _separate(self, movement_list, **kw):
if not movement_list:
return []
......
......@@ -57,5 +57,5 @@ class SplitMovementGroup(MovementGroup):
def test(self, document, property_dict, **kw):
return True, property_dict
def _separate(self, movement_list):
def _separate(self, movement_list, **kw):
return [[[movement], {}] for movement in movement_list]
......@@ -41,13 +41,15 @@ class MovementGroupNode:
# a separate method requests separating movements.
def __init__(self, movement_group_list=None, movement_list=None,
last_line_movement_group=None,
separate_method_name_list=[], movement_group=None):
separate_method_name_list=[], movement_group=None,
merge_delivery=None):
self._movement_list = []
self._group_list = []
self._movement_group = movement_group
self._movement_group_list = movement_group_list
self._last_line_movement_group = last_line_movement_group
self._separate_method_name_list = separate_method_name_list
self._merge_delivery = merge_delivery
if movement_list is not None :
self.append(movement_list)
......@@ -56,22 +58,24 @@ class MovementGroupNode:
movement_group=self._movement_group_list[0],
movement_group_list=self._movement_group_list[1:],
last_line_movement_group=self._last_line_movement_group,
separate_method_name_list=self._separate_method_name_list)
separate_method_name_list=self._separate_method_name_list,
merge_delivery=self._merge_delivery)
nested_instance.setGroupEdit(**property_dict)
split_movement_list = nested_instance.append(movement_list)
self._group_list.append(nested_instance)
return split_movement_list
def append(self, movement_list):
def append(self, movement_list, **kw):
all_split_movement_list = []
if len(self._movement_group_list):
for separate_movement_list, property_dict in \
self._movement_group_list[0].separate(movement_list):
self._movement_group_list[0].separate(movement_list,
merge_delivery=self._merge_delivery):
split_movement_list = self._appendGroup(separate_movement_list,
property_dict)
if len(split_movement_list):
if self._movement_group == self._last_line_movement_group:
self.append(split_movement_list)
self.append(split_movement_list, **kw)
else:
all_split_movement_list.extend(split_movement_list)
else:
......
This diff is collapsed.
......@@ -101,7 +101,8 @@ class BuilderMixin(XMLObject, Amount, Predicate):
security.declarePublic('build')
def build(self, applied_rule_uid=None, movement_relative_url_list=None,
delivery_relative_url_list=None, movement_list=None,
explanation=None, business_link=None, activate_kw=None, **kw):
explanation=None, business_link=None, activate_kw=None,
merge_delivery=None, **kw):
"""
Build deliveries from a list of movements
......@@ -136,13 +137,13 @@ class BuilderMixin(XMLObject, Amount, Predicate):
if not movement_list:
return []
# Collect
root_group_node = self.collectMovement(movement_list)
root_group_node = self.collectMovement(movement_list, merge_delivery=merge_delivery)
# Build
delivery_list = self.buildDeliveryList(
root_group_node,
delivery_relative_url_list=delivery_relative_url_list,
movement_list=movement_list, activate_kw=activate_kw,
**kw)
merge_delivery=merge_delivery, **kw)
# Call a script after building
self.callAfterBuildingScript(delivery_list, movement_list, **kw)
return delivery_list
......@@ -297,7 +298,7 @@ class BuilderMixin(XMLObject, Amount, Predicate):
searchMovementList = UnrestrictedMethod(_searchMovementList)
security.declarePrivate('collectMovement')
def collectMovement(self, movement_list):
def collectMovement(self, movement_list, merge_delivery=False):
"""
group movements in the way we want. Thanks to this method, we are able
to retrieve movement classed by order, resource, criterion,....
......@@ -314,7 +315,8 @@ class BuilderMixin(XMLObject, Amount, Predicate):
root_group_node = MovementGroupNode(
separate_method_name_list=separate_method_name_list,
movement_group_list=movement_group_list,
last_line_movement_group=last_line_movement_group)
last_line_movement_group=last_line_movement_group,
merge_delivery=merge_delivery)
root_group_node.append(movement_list)
return root_group_node
......@@ -396,14 +398,16 @@ class BuilderMixin(XMLObject, Amount, Predicate):
if update:
delivery_to_update_list = [portal.restrictedTraverse(relative_url) for \
relative_url in delivery_relative_url_list]
# Deliveries we are trying to update
delivery_select_method_id = self.getDeliverySelectMethodId()
if delivery_select_method_id not in ["", None]:
to_update_delivery_sql_list = getattr(self, delivery_select_method_id) \
(movement_list=movement_list)
delivery_to_update_list.extend([sql_delivery.getObject() \
for sql_delivery \
in to_update_delivery_sql_list])
# Only use select method when the list of delivery is not already provided
if len(delivery_to_update_list) == 0:
# Deliveries we are trying to update
delivery_select_method_id = self.getDeliverySelectMethodId()
if delivery_select_method_id not in ["", None]:
to_update_delivery_sql_list = getattr(self, delivery_select_method_id) \
(movement_list=movement_list)
delivery_to_update_list.extend([sql_delivery.getObject() \
for sql_delivery \
in to_update_delivery_sql_list])
else:
delivery_to_update_list = []
# We do not want to update the same object more than twice in one
......@@ -431,7 +435,8 @@ class BuilderMixin(XMLObject, Amount, Predicate):
collect_order_list, movement_group_node_list=None,
delivery_to_update_list=None,
divergence_list=None,
activate_kw=None, force_update=0, **kw):
activate_kw=None, force_update=0,
merge_delivery=None, **kw):
"""
Build delivery from a list of movement
"""
......@@ -457,7 +462,8 @@ class BuilderMixin(XMLObject, Amount, Predicate):
delivery_to_update_list=delivery_to_update_list,
divergence_list=divergence_list,
activate_kw=activate_kw,
force_update=force_update)
force_update=force_update,
merge_delivery=merge_delivery)
delivery_list.extend(new_delivery_list)
force_update = 0
else:
......@@ -467,9 +473,14 @@ class BuilderMixin(XMLObject, Amount, Predicate):
x for x in delivery_to_update_list \
if x.getPortalType() == self.getDeliveryPortalType() and \
not self._isUpdated(x, 'delivery')]
delivery, property_dict = self._findUpdatableObject(
delivery_to_update_list, movement_group_node_list,
divergence_list)
if merge_delivery:
# We must have only one delivery to update in the case of merge
delivery, = delivery_to_update_list
property_dict = {}
else:
delivery, property_dict = self._findUpdatableObject(
delivery_to_update_list, movement_group_node_list,
divergence_list)
# if all deliveries are rejected in case of update, we update the
# first one.
......
......@@ -1010,6 +1010,48 @@ class TestPackingListMixin(TestOrderMixin):
after_tag=after_tag,
).build(explanation_uid=packing_list.getCausalityValue().getUid())
def stepMergeSplittedPackingList(self, sequence=None):
"""
Invoke the merge of the two sales packing list and check the merged packing list
Then also try to create a packing list not coming from order, and then
tro to merge it with the merged packing list
"""
# Merge the two existing packing list
packing_list1 = sequence.get('packing_list')
packing_list2 = sequence.get('new_packing_list')
self.portal.portal_simulation.mergeDeliveryList([packing_list1, packing_list2])
self.tic()
self.assertEqual('confirmed', packing_list1.getSimulationState())
self.assertEqual('cancelled', packing_list2.getSimulationState())
line, = packing_list1.objectValues(
portal_type= self.packing_list_line_portal_type)
self.assertEqual(self.default_quantity,line.getQuantity())
self.assertTrue(packing_list1.getStartDate() is not None)
self.assertTrue(packing_list1.getStopDate() is not None)
# Now clone the merged packing list, so that we will have :
# - one packing list coming from order (merged_packing_list)
# - one not coming from order (the cloned one)
cloned_packing_list = packing_list1.Base_createCloneDocument(batch_mode=True)
cloned_packing_list.setStartDate(cloned_packing_list.getStartDate() + 1)
cloned_packing_list.setStopDate(cloned_packing_list.getStopDate() + 1)
cloned_line, = cloned_packing_list.objectValues()
cloned_line.setQuantity(self.default_quantity+1)
self.portal.portal_workflow.doActionFor(cloned_packing_list, "confirm_action")
self.tic()
self.portal.portal_simulation.mergeDeliveryList([packing_list1, cloned_packing_list])
self.tic()
self.assertEqual('confirmed', packing_list1.getSimulationState())
self.assertEqual('cancelled', cloned_packing_list.getSimulationState())
resource = sequence.get('resource').getRelativeUrl()
def checkLineSet(delivery, expected_set):
line_list = delivery.getMovementList()
self.assertEqual(len(line_list), len(expected_set))
found_set = set([(x.getResource(), x.getQuantity(), x.getPrice()) for x in line_list])
expected_set = set([(resource, self.default_quantity, 555),
(resource, self.default_quantity+1, 555)])
checkLineSet(packing_list1, expected_set)
class TestPackingList(TestPackingListMixin, ERP5TypeTestCase) :
run_all_test = 1
......@@ -1020,6 +1062,8 @@ class TestPackingList(TestPackingListMixin, ERP5TypeTestCase) :
Change the quantity on an delivery line, then
see if the packing list is divergent and then
split and defer the packing list
Finally, check we can merge if needed
"""
if not run: return
sequence_list = SequenceList()
......@@ -1033,6 +1077,7 @@ class TestPackingList(TestPackingListMixin, ERP5TypeTestCase) :
Tic
CheckPackingListIsSolved
CheckPackingListSplitted
MergeSplittedPackingList
"""
sequence_list.addSequenceString(sequence_string)
......
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