Commit eb1b5f80 authored by Romain Courteaud's avatar Romain Courteaud

DeliveryBuilder is now able to update an existing delivery with new simulation

movements.


git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@3195 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent 20e1e5ef
...@@ -34,6 +34,7 @@ from Products.ERP5.Document.Predicate import Predicate ...@@ -34,6 +34,7 @@ from Products.ERP5.Document.Predicate import Predicate
from Products.ERP5.Document.Amount import Amount from Products.ERP5.Document.Amount import Amount
from Acquisition import aq_base, aq_parent, aq_inner, aq_acquire from Acquisition import aq_base, aq_parent, aq_inner, aq_acquire
from Products.ERP5 import MovementGroup from Products.ERP5 import MovementGroup
from Products.ERP5Type.Utils import convertToUpperCase
from zLOG import LOG from zLOG import LOG
...@@ -112,8 +113,10 @@ class DeliveryBuilder(XMLObject, Amount, Predicate): ...@@ -112,8 +113,10 @@ class DeliveryBuilder(XMLObject, Amount, Predicate):
in movement_relative_url_list] in movement_relative_url_list]
# Collect # Collect
root_group = self.collectMovement(movement_list) root_group = self.collectMovement(movement_list)
# Build # Build
delivery_list = self.buildDeliveryList(root_group) delivery_list = self.buildDeliveryList(root_group)
delivery_after_generation_script_id =\ delivery_after_generation_script_id =\
self.getDeliveryAfterGenerationScriptId() self.getDeliveryAfterGenerationScriptId()
...@@ -196,22 +199,57 @@ class DeliveryBuilder(XMLObject, Amount, Predicate): ...@@ -196,22 +199,57 @@ class DeliveryBuilder(XMLObject, Amount, Predicate):
return my_root_group return my_root_group
def testObjectProperties(self, object, property_dict):
"""
Test object properties.
"""
result = 1
for key in property_dict:
# XXX FIXME (or not)
# Relation is not coherent
# You set it with set...Value
# And get it with get...
new_key = key
if key.endswith("_value"):
new_key = key[:-len("_value")]
getter_name = 'get%s' % convertToUpperCase(new_key)
if hasattr(object, getter_name):
value = getattr(object, getter_name)()
if value != property_dict[key]:
result = 0
break
else:
result = 0
break
return result
def buildDeliveryList(self, movement_group): def buildDeliveryList(self, movement_group):
""" """
Build deliveries from a list of movements Build deliveries from a list of movements
""" """
# Module where we can create new deliveries
delivery_module = getattr(self, self.getDeliveryModule()) delivery_module = getattr(self, self.getDeliveryModule())
# Deliveries we are trying to update
to_update_delivery_list = []
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)()
to_update_delivery_list = [x.getObject() for x\
in to_update_delivery_sql_list]
delivery_list = self._deliveryGroupProcessing( delivery_list = self._deliveryGroupProcessing(
delivery_module, delivery_module,
movement_group, movement_group,
self.getDeliveryCollectOrderList(), self.getDeliveryCollectOrderList(),
{}) {},
delivery_to_update_list=to_update_delivery_list)
return delivery_list return delivery_list
def _deliveryGroupProcessing(self, delivery_module, movement_group, def _deliveryGroupProcessing(self, delivery_module, movement_group,
collect_order_list, property_dict): collect_order_list, property_dict,
delivery_to_update_list=[]):
""" """
Build empty delivery from a list of movement Build empty delivery from a list of movement
""" """
...@@ -233,6 +271,18 @@ class DeliveryBuilder(XMLObject, Amount, Predicate): ...@@ -233,6 +271,18 @@ class DeliveryBuilder(XMLObject, Amount, Predicate):
delivery_list.extend(new_delivery_list) delivery_list.extend(new_delivery_list)
else: else:
# Test if we can update a existing delivery, or if we need to create
# a new one
delivery = None
for delivery_to_update in delivery_to_update_list:
if self.testObjectProperties(delivery_to_update, property_dict):
# Check if delivery has the correct portal_type
if delivery_to_update.getPortalType() ==\
self.getDeliveryPortalType():
delivery = delivery_to_update
break
if delivery == None:
# Create delivery # Create delivery
new_delivery_id = str(delivery_module.generateNewId()) new_delivery_id = str(delivery_module.generateNewId())
delivery = delivery_module.newContent( delivery = delivery_module.newContent(
...@@ -268,16 +318,27 @@ class DeliveryBuilder(XMLObject, Amount, Predicate): ...@@ -268,16 +318,27 @@ class DeliveryBuilder(XMLObject, Amount, Predicate):
self._deliveryLineGroupProcessing( self._deliveryLineGroupProcessing(
delivery, group, collect_order_list[1:], property_dict.copy()) delivery, group, collect_order_list[1:], property_dict.copy())
else: else:
# Test if we can update an existing line, or if we need to create a new
# one
delivery_line = None
for delivery_line_to_update in delivery.contentValues(
filter={'portal_type':self.getDeliveryLinePortalType()}):
if self.testObjectProperties(delivery_line_to_update, property_dict):
delivery_line = delivery_line_to_update
break
if delivery_line == None:
# Create delivery line # Create delivery line
new_delivery_line_id = str(delivery.generateNewId()) new_delivery_line_id = str(delivery.generateNewId())
delivery_line = delivery.newContent( delivery_line = delivery.newContent(
portal_type=self.getDeliveryLinePortalType(), portal_type=self.getDeliveryLinePortalType(),
id=new_delivery_line_id) id=new_delivery_line_id,
variation_category_list=[])
# Put properties on delivery line # Put properties on delivery line
delivery_line.edit(**property_dict) delivery_line.edit(**property_dict)
# Set variation category list on line # Update variation category list on line
line_variation_category_list = [] line_variation_category_list = delivery_line.getVariationCategoryList()
for movement in movement_group.getMovementList(): for movement in movement_group.getMovementList():
line_variation_category_list.extend( line_variation_category_list.extend(
movement.getVariationCategoryList()) movement.getVariationCategoryList())
...@@ -316,42 +377,87 @@ class DeliveryBuilder(XMLObject, Amount, Predicate): ...@@ -316,42 +377,87 @@ class DeliveryBuilder(XMLObject, Amount, Predicate):
raise "CollectError", "DeliveryBuilder: %s unable to distinct those\ raise "CollectError", "DeliveryBuilder: %s unable to distinct those\
movements: %s" % (self.getId(), str(movement_list)) movements: %s" % (self.getId(), str(movement_list))
else: else:
# decide if we create a cell or if we update the line # XXX Hardcoded value
# Decision can only be made with variation_category_list base_id = 'movement'
object_to_update = None
# We need to initialize the cell
update_existing_movement=0
movement = movement_list[0] movement = movement_list[0]
movement_variation_category_list = movement.getVariationCategoryList() # decide if we create a cell or if we update the line
if movement_variation_category_list == []: # Decision can only be made with line matrix range:
# because matrix range can be empty even if line variation category
# list is not empty
if delivery_line.getCellKeyList(base_id=base_id) == []:
# update line # update line
object_to_update = delivery_line object_to_update = delivery_line
if self.testObjectProperties(delivery_line, property_dict):
# We update a initialized line
update_existing_movement=1
else: else:
for cell in delivery_line.contentValues(
filter={'portal_type':self.getDeliveryCellPortalType()}):
if self.testObjectProperties(cell, property_dict):
# We update a existing cell
# delivery_ratio of new related movement to this cell
# must be updated to 0.
update_existing_movement=1
object_to_update = cell
break
if object_to_update is None:
# create a new cell # create a new cell
base_id = 'movement' cell_key = movement.getVariationCategoryList()
cell_key = movement_variation_category_list
if not delivery_line.hasCell(base_id=base_id, *cell_key): if not delivery_line.hasCell(base_id=base_id, *cell_key):
cell = delivery_line.newCell(base_id=base_id,\ cell = delivery_line.newCell(base_id=base_id,\
portal_type=self.getDeliveryCellPortalType(), *cell_key) portal_type=self.getDeliveryCellPortalType(), *cell_key)
# XXX hardcoded value
cell._edit(category_list=cell_key, cell._edit(category_list=cell_key,
# XXX hardcoded value
mapped_value_property_list=['quantity', 'price'], mapped_value_property_list=['quantity', 'price'],
membership_criterion_category_list=cell_key, membership_criterion_category_list=cell_key,
membership_criterion_base_category_list=movement.\ membership_criterion_base_category_list=movement.\
getVariationBaseCategoryList()) getVariationBaseCategoryList())
object_to_update = cell object_to_update = cell
else: else:
raise 'MatrixError', 'Cell: %s already exists on %s' %\ raise 'MatrixError', 'Cell: %s already exists on %s' %\
(str(cell_key), str(delivery_line)) (str(cell_key), str(delivery_line))
# XXX hardcoded value self._setDeliveryMovementProperties(
object_to_update, movement, property_dict,
update_existing_movement=update_existing_movement)
def _setDeliveryMovementProperties(self, delivery_movement,
simulation_movement, property_dict,
update_existing_movement=0):
"""
Initialize or update delivery movement properties.
Set delivery ratio on simulation movement.
Create the relation between simulation movement
and delivery movement.
"""
if update_existing_movement == 1:
# Important.
# Attributes of object_to_update must not be modified here.
# Because we can not change values that user modified.
# Delivery will probably diverge now, but this is not the job of
# DeliveryBuilder to resolve such problem.
# Use Solver instead.
simulation_movement.setDeliveryRatio(0)
else:
# Now, only 1 movement is possible, so copy from this movement # Now, only 1 movement is possible, so copy from this movement
property_dict['quantity'] = movement.getQuantity() # XXX hardcoded value
property_dict['price'] = movement.getPrice() property_dict['quantity'] = simulation_movement.getQuantity()
property_dict['price'] = simulation_movement.getPrice()
# Update properties on object (quantity, price...) # Update properties on object (quantity, price...)
object_to_update.edit(**property_dict) delivery_movement.edit(**property_dict)
simulation_movement.setDeliveryRatio(1)
# Update simulation movement # Update simulation movement
movement.setDeliveryValue(object_to_update) simulation_movement.setDeliveryValue(delivery_movement)
# Simulation consistency propagation # Simulation consistency propagation
security.declareProtected(Permissions.ModifyPortalContent, security.declareProtected(Permissions.ModifyPortalContent,
...@@ -369,19 +475,12 @@ class DeliveryBuilder(XMLObject, Amount, Predicate): ...@@ -369,19 +475,12 @@ class DeliveryBuilder(XMLObject, Amount, Predicate):
# Select # Select
simulation_movement_list = [] simulation_movement_list = []
for movement in delivery.getMovementList(): for movement in delivery.getMovementList():
movement.setQuantity(0) movement.edit(quantity=0)
for simulation_movement in movement.getDeliveryRelatedValueList( for simulation_movement in movement.getDeliveryRelatedValueList(
portal_type="Simulation Movement"): portal_type="Simulation Movement"):
simulation_movement.setDelivery(None) simulation_movement.setDelivery(None)
simulation_movement_list.append(simulation_movement) simulation_movement_list.append(simulation_movement)
# XXX FIXME: 1st implementation, delete all delivery lines
# It is better to only update properties on movement
# because when deleting lines we lose information
# And finally, it is BAD to delete object in ERP5 !!!
delivery.deleteContent(delivery.contentIds(
filter = {'portal_type': self.getDeliveryLinePortalType()}))
# Collect # Collect
root_group = self.collectMovement(simulation_movement_list) root_group = self.collectMovement(simulation_movement_list)
...@@ -389,6 +488,24 @@ class DeliveryBuilder(XMLObject, Amount, Predicate): ...@@ -389,6 +488,24 @@ class DeliveryBuilder(XMLObject, Amount, Predicate):
rejected_movement_list = self._deliveryUpdateGroupProcessing( rejected_movement_list = self._deliveryUpdateGroupProcessing(
delivery, delivery,
root_group) root_group)
for sim_mvt in root_group.getMovementList():
sim_mvt.immediateReindexObject()
# Store the good quantity value on delivery line
for movement in delivery.getMovementList():
total_quantity = 0
for simulation_movement in movement.getDeliveryRelatedValueList(
portal_type="Simulation Movement"):
total_quantity += simulation_movement.getQuantity()
for simulation_movement in movement.getDeliveryRelatedValueList(
portal_type="Simulation Movement"):
simulation_movement.setDeliveryRatio(
simulation_movement.getQuantity()/total_quantity)
movement.edit(quantity=total_quantity)
# Launch delivery creation # Launch delivery creation
if (create_new_delivery == 1) and\ if (create_new_delivery == 1) and\
(rejected_movement_list != []): (rejected_movement_list != []):
...@@ -414,16 +531,11 @@ class DeliveryBuilder(XMLObject, Amount, Predicate): ...@@ -414,16 +531,11 @@ class DeliveryBuilder(XMLObject, Amount, Predicate):
# Put properties on delivery # Put properties on delivery
delivery.edit(**property_dict) delivery.edit(**property_dict)
# Then, create delivery line # Then, reconnect simulation to delivery line
for group in movement_group.getGroupList(): for group in movement_group.getGroupList():
self._deliveryLineGroupProcessing( self._deliveryLineGroupProcessing(
delivery, delivery,
group, group,
self.getDeliveryLineCollectOrderList()[1:], self.getDeliveryLineCollectOrderList()[1:],
{}) {})
# Reindex all
for movement in movement_group.getMovementList():
movement.immediateReindexObject()
return rejected_movement_list return rejected_movement_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