Commit d58b2364 authored by Xiaowu Zhang's avatar Xiaowu Zhang

SimulationTool: it's necessairy to check delivery line to get correct

builder

A delivery may have several delivery line
like:
Purchase Invoice Transaction has Purchase Invoice Transaction Line and
Invoice Line
parent f588d64e
...@@ -2654,7 +2654,7 @@ class SimulationTool(BaseTool): ...@@ -2654,7 +2654,7 @@ class SimulationTool(BaseTool):
return result return result
def _findBuilderForDelivery(self, delivery): def _findBuilderForDelivery(self, delivery, movement_portal_type):
""" """
Find out the builder corresponding to a delivery by looking at the business process Find out the builder corresponding to a delivery by looking at the business process
""" """
...@@ -2662,7 +2662,8 @@ class SimulationTool(BaseTool): ...@@ -2662,7 +2662,8 @@ class SimulationTool(BaseTool):
portal_type = delivery.getPortalType() portal_type = delivery.getPortalType()
for business_link in delivery.asComposedDocument().objectValues(portal_type="Business Link"): for business_link in delivery.asComposedDocument().objectValues(portal_type="Business Link"):
for business_link_builder in business_link.getDeliveryBuilderValueList(): for business_link_builder in business_link.getDeliveryBuilderValueList():
if business_link_builder.getDeliveryPortalType() == portal_type: if business_link_builder.getDeliveryPortalType() == portal_type \
and business_link_builder.getDeliveryLinePortalType() == movement_portal_type:
builder = business_link_builder builder = business_link_builder
break break
if builder is not None: if builder is not None:
...@@ -2688,87 +2689,93 @@ class SimulationTool(BaseTool): ...@@ -2688,87 +2689,93 @@ class SimulationTool(BaseTool):
if len(portal_type_set) != 1: if len(portal_type_set) != 1:
error_list.append(translateString("Please select only deliveries of same type")) error_list.append(translateString("Please select only deliveries of same type"))
else: else:
portal_type, = portal_type_set
allowed_state_set = set(portal.getPortalReservedInventoryStateList() + \ allowed_state_set = set(portal.getPortalReservedInventoryStateList() + \
portal.getPortalFutureInventoryStateList()) portal.getPortalFutureInventoryStateList())
found_state_set = set([x.getSimulationState() for x in delivery_list]) found_state_set = set([x.getSimulationState() for x in delivery_list])
if found_state_set.difference(allowed_state_set): if found_state_set.difference(allowed_state_set):
error_list.append(translateString("Found delivery having unexpected status for merge")) error_list.append(translateString("Found delivery having unexpected status for merge"))
else: else:
# Allow to call a script to do custom checking conditions before merge movement_portal_type_set = set()
main_delivery = delivery_list[0] for delivery in delivery_list:
check_merge_condition_method = main_delivery._getTypeBasedMethod("checkMergeConditionOnDeliveryList") movement_portal_type_set.update([x.getPortalType() for x in delivery.getMovementList()])
if check_merge_condition_method is not None: if len(movement_portal_type_set) != 1:
error_list.extend(check_merge_condition_method(delivery_list=delivery_list)) error_list.append(translateString("Please Select only movement of same type"))
if len(error_list) == 0: else:
# so far so good # Allow to call a script to do custom checking conditions before merge
# in delivery_list we have list of delivery to merge main_delivery = delivery_list[0]
simulation_movement_list = [] check_merge_condition_method = main_delivery._getTypeBasedMethod("checkMergeConditionOnDeliveryList")
to_copy_delivery_line_list = [] # for lines not coming from upper simulation, thus if check_merge_condition_method is not None:
# created by hand should be manually added to main error_list.extend(check_merge_condition_method(delivery_list=delivery_list))
# delivery since they are not coming from builder if len(error_list) == 0:
for delivery in delivery_list: # so far so good
line_id_to_delete_list = [] # in delivery_list we have list of delivery to merge
for movement in delivery.getMovementList(): simulation_movement_list = []
related_simulation_movement_list = movement.getDeliveryRelatedValueList() to_copy_delivery_line_list = [] # for lines not coming from upper simulation, thus
for simulation_movement in related_simulation_movement_list: # created by hand should be manually added to main
# if we are on a root applied rule directly, so in the case of # delivery since they are not coming from builder
# a manually added line, we have to copy for delivery in delivery_list:
# the simulation movement into to main delivery line_id_to_delete_list = []
if simulation_movement.getParentValue().getParentValue().getId() == "portal_simulation": for movement in delivery.getMovementList():
# For manually added lines, make sure we have only one simulation movement related_simulation_movement_list = movement.getDeliveryRelatedValueList()
assert len(related_simulation_movement_list) == 1 for simulation_movement in related_simulation_movement_list:
if not(delivery is main_delivery): # if we are on a root applied rule directly, so in the case of
to_copy_delivery_line_list.append(movement) # a manually added line, we have to copy
else: # the simulation movement into to main delivery
simulation_movement.setDeliveryValue(None) if simulation_movement.getParentValue().getParentValue().getId() == "portal_simulation":
simulation_movement_list.append(simulation_movement) # For manually added lines, make sure we have only one simulation movement
# Since we keep the main delivery, we remove existing lines already assert len(related_simulation_movement_list) == 1
# coming from builder to let builder recreate them in the same time if not(delivery is main_delivery):
# as other ones (to possibly merge lines also) to_copy_delivery_line_list.append(movement)
movement_id = movement.getId() else:
if delivery is main_delivery and not(movement_id in line_id_to_delete_list): simulation_movement.setDeliveryValue(None)
line_id_to_delete_list.append(movement.getId()) simulation_movement_list.append(simulation_movement)
if line_id_to_delete_list: # Since we keep the main delivery, we remove existing lines already
delivery.manage_delObjects(ids=line_id_to_delete_list) # coming from builder to let builder recreate them in the same time
# It is required to expand again simulation movement, because # as other ones (to possibly merge lines also)
# we unlinked them from delivery, so it is possible that some movement_id = movement.getId()
# properties will change on simulation movement (mostly categories). if delivery is main_delivery and not(movement_id in line_id_to_delete_list):
# By expanding again, we will avoid having many deliveries instead line_id_to_delete_list.append(movement.getId())
# of one when doing "merge" if line_id_to_delete_list:
for simulation_movement in simulation_movement_list: delivery.manage_delObjects(ids=line_id_to_delete_list)
simulation_movement.expand(expand_policy='immediate') # It is required to expand again simulation movement, because
# we unlinked them from delivery, so it is possible that some
# activate builder # properties will change on simulation movement (mostly categories).
merged_builder = self._findBuilderForDelivery(main_delivery) # By expanding again, we will avoid having many deliveries instead
if merged_builder is None: # of one when doing "merge"
error_list.append(translateString("Unable to find builder")) for simulation_movement in simulation_movement_list:
else: simulation_movement.expand(expand_policy='immediate')
merged_builder.build(movement_relative_url_list=[q.getRelativeUrl() for q in \
simulation_movement_list], merge_delivery=True, # activate builder
delivery_relative_url_list=[main_delivery.getRelativeUrl()]) movement_portal_type, = movement_portal_type_set
# Finally, copy all lines that were created manually on all deliveries except merged_builder = self._findBuilderForDelivery(main_delivery, movement_portal_type)
# the main one if merged_builder is None:
@UnrestrictedMethod error_list.append(translateString("Unable to find builder"))
def setMainDeliveryModifiable(delivery): else:
# set causality state in such way we can modify delivery merged_builder.build(movement_relative_url_list=[q.getRelativeUrl() for q in \
delivery.diverge() simulation_movement_list], merge_delivery=True,
setMainDeliveryModifiable(main_delivery) delivery_relative_url_list=[main_delivery.getRelativeUrl()])
delivery_type_list = portal.getPortalDeliveryTypeList() # Finally, copy all lines that were created manually on all deliveries except
for delivery_line in to_copy_delivery_line_list: # the main one
delivery = delivery_line.getParentValue() @UnrestrictedMethod
if not(delivery.getPortalType() in delivery_type_list): def setMainDeliveryModifiable(delivery):
raise NotImplementedError("Merge of deliveries doe not yet handle case of cells") # set causality state in such way we can modify delivery
copy_data = delivery.manage_copyObjects(ids=[delivery_line.getId()]) delivery.diverge()
main_delivery.manage_pasteObjects(copy_data) setMainDeliveryModifiable(main_delivery)
main_delivery.updateCausalityState() delivery_type_list = portal.getPortalDeliveryTypeList()
for delivery_line in to_copy_delivery_line_list:
# Finally do cleanup delivery = delivery_line.getParentValue()
for delivery in delivery_list[1:]: if not(delivery.getPortalType() in delivery_type_list):
# cancel, delete - to disallow any user related operations on those deliveries raise NotImplementedError("Merge of deliveries doe not yet handle case of cells")
after_merge_method = delivery._getTypeBasedMethod('cleanDeliveryAfterMerge') copy_data = delivery.manage_copyObjects(ids=[delivery_line.getId()])
if after_merge_method is not None: main_delivery.manage_pasteObjects(copy_data)
after_merge_method() main_delivery.updateCausalityState()
# Finally do cleanup
for delivery in delivery_list[1:]:
# cancel, delete - to disallow any user related operations on those deliveries
after_merge_method = delivery._getTypeBasedMethod('cleanDeliveryAfterMerge')
if after_merge_method is not None:
after_merge_method()
else: else:
error_list.append(translateString("Please select at least two deliveries")) error_list.append(translateString("Please select at least two deliveries"))
return error_list return error_list
......
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