Commit d215f07a authored by Jean-Paul Smets's avatar Jean-Paul Smets

Initial pseudo-code

git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@30366 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent b9c74460
...@@ -33,3 +33,30 @@ class FIFO(DeliverySolver): ...@@ -33,3 +33,30 @@ class FIFO(DeliverySolver):
""" """
The FIFO solver reduces deliveted quantity by reducing the quantity of simulation movements from the last order. The FIFO solver reduces deliveted quantity by reducing the quantity of simulation movements from the last order.
""" """
def solve(self, simulation_movement_list, new_quantity):
"""
"""
result = []
def sortByOrderStartDate(a, b);
return cmp(a.getExplainationValue().getStartDate() b.getExplainationValue().getStartDate())
simulation_movement_list.sort(sortByOrderStartDate)
simulation_movement_list.reverse()
total_quantity = 0
for movement in simulation_movement_list:
total_quantity += movement.getQuantity()
remaining_quantity = total_quantity - new_quantity
for movement in simulation_movement_list:
if remaining_quantity:
if movement.getQuantity() < remaining_quantity:
result.append((movement, movement.getQuantity()))
remaining_quantity -= movement.getQuantity()
movement.setQuantity(0)
else:
result.append((movement, remaining_quantity))
movement.setQuantity(movement.getQuantity() - remaining_quantity)
remaining_quantity = 0
# Return movement, split_quantity tuples
for movement in simulation_movement_list:
movement.setDeliveryRatio(movement.getQuantity() / new_quantity)
return result
\ No newline at end of file
...@@ -53,3 +53,18 @@ class AcceptSolver(XMLObject): ...@@ -53,3 +53,18 @@ class AcceptSolver(XMLObject):
, PropertySheet.CategoryCore , PropertySheet.CategoryCore
, PropertySheet.DublinCore , PropertySheet.DublinCore
) )
# Implementation
def solve(self):
"""
"""
# Adopt new property, keep the original one recorded
solved_property = self.getPortalTypeValue().getTestedProperty()
for movement in self.getDeliveryValueList():
new_value = movement.getProperty(solved_property)
for simulation_movement in movement.getDeliveryRelatedValueList():
if not simulation_movement.isPropertyRecorded(solved_property):
simulation_movement.recordProperty(solved_property)
solved_property.setProperty(solved_property, new_value)
# Finish solving
self.succeed()
\ No newline at end of file
...@@ -55,3 +55,19 @@ class QuantitySplitSolver(XMLObject): ...@@ -55,3 +55,19 @@ class QuantitySplitSolver(XMLObject):
, PropertySheet.DublinCore , PropertySheet.DublinCore
, PropertySheet.Arrow , PropertySheet.Arrow
) )
# Implementation
def solve(self):
"""
"""
delivery_solver = self.portal_solvers.buildDeliverySolver(self.getDeliverySolver())
for delivery_line in self.getDeliveryValueList():
decision_quantity = delivery_line.getQuantity()
simulation_movement_list = self.getDeliveryRelatedValueList()
# Update the quantity using delivery solver algorithm
split_list = delivery_solver.solve(simulation_movement_list, decision_quantity)
# Create split movements
for (simulation_movement, split_quantity) in split_list:
new_movement = simulation_movement.copy() # Copy at same level
new_movement._setQuantity(split_quantity)
new_movement._setStartDate(self.getStartDate())
new_movement._setStopDate(self.getStopDate())
\ No newline at end of file
...@@ -72,3 +72,61 @@ class SolverProcess(XMLObject, ActiveProcess): ...@@ -72,3 +72,61 @@ class SolverProcess(XMLObject, ActiveProcess):
, PropertySheet.CategoryCore , PropertySheet.CategoryCore
, PropertySheet.DublinCore , PropertySheet.DublinCore
) )
def buildTargetSolverList(self):
"""
Builds target solvers from solver decisions
"""
solver_dict = {}
movement_dict = {}
types_tool = context.portal_types
# First create a mapping between delivery movements and solvers
# in order to know for each movements which solvers are needed
# and which parameters with
for decision in context.contentValues(portal_type="Solver Decision"):
solver = decision.getSolverValue()
solver_type = solver.getId() # ex. Postpone Production Solver
solver_conviguration_dict = decision.getConfigurationPropertyDict()
solver_conviguration_key = solver_conviguration_dict.items()
for movement in decision.getDeliveryValueList():
# Detect incompatibilities
movement_solver_dict = movement_dict.setdefault(movement.getRelativeUrl(), {})
movement_solver_configuration_dict = movement_solver_dict.setdefault(solver_type, {})
movement_solver_configuration_dict[solver_key] = None
# Second, make sure solvers do not conflict and configuration is valid
for movement_url, movement_solver_dict in movement_dict.items():
for solver_type, movement_solver_configuration_dict in movement_solver_dict.items():
solver = types_tool[solver_type]
for other_solver in movement_solver_dict.keys():
if solver.conflictsWithSolver(other_solver):
raise "Solver %s conflicts with solver %s on movement %s" % (solver_type, other_solver, movement_url)
# Make sure multiple configuration are possible
try:
# Solver key contains only those properties which differentiate
# solvers (ex. there should be only Production Reduction Solver)
solver_key = solver.reduceConfigurationList(movement_solver_configuration_dict.keys())
except:
raise
solver_key_dict = solver_dict.setdefault(solver_type, {})
solver_movement_dict = solver_key_dict.setdefault(solver_key, {})
solver_movement_dict[movement_url] = movement_solver_configuration_dict.keys()
# Third, build target solvers
for portal_type, solver_key_dict in solver_dict.items():
for solver_key, solver_movement_dict in solver_key_dict.items():
solver_instance = self.newContent(portal_type=solver_type)
solver_instance._setDeliveryList(solver_movement_dict.keys())
for movement_url, configuration_list:
for configuration_kw in configuration_list:
solver_instance.updateConfiguration(**configuration_kw)
# Solver Process Workflow Interface
# NOTE: how can we consider that a workflow defines or provides an interface ?
def solve(self):
"""
Start solving
"""
for solver in self.contentValues(portal_type=self.getPortalObject().getPortalTargetSolverTypeList()):
solver.activate(active_process=self).solve()
\ No newline at end of file
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