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

Refactoring of movement_generator to match context-less API and share more code

git-svn-id: https://svn.erp5.org/repos/public/erp5/sandbox/amount_generator@34976 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent 83f4af93
...@@ -29,17 +29,25 @@ ...@@ -29,17 +29,25 @@
from Products.ERP5.MovementCollectionDiff import _getPropertyAndCategoryList from Products.ERP5.MovementCollectionDiff import _getPropertyAndCategoryList
class MovementGeneratorMixin: class MovementGeneratorMixin:
"""Movement Generator interface specification """
This class provides a generic implementation of IMovementGenerator.
It is used by rules to generate a collection of movements from
the context of an applied rule.
Documents which implement IMovementGenerator TODO:
can be used to generate an IMovementList from Deliveries ? Movements ? Items ?
an existing IMovementCollection, IMovementList or Does it depend by default on IAmountGeneratorMixin
IMovement. Typical IMovementGenerator are Rules
and Trade Conditions.
""" """
def __init__(self, applied_rule=None, rule=None, trade_phase_list=None):
self._trade_phase_list = trade_phase_list # XXX
self._applied_rule = applied_rule
if rule is None and applied_rule is not None:
self._rule = applied_rule.getSpecialiseValue()
else:
self._rule = rule # for rule specific stuff
# Implementation of IMovementGenerator # Implementation of IMovementGenerator
def getGeneratedMovementList(context, movement_list=None, rounding=False): def getGeneratedMovementList(movement_list=None, rounding=False):
""" """
Returns an IMovementList generated by a model applied to the context Returns an IMovementList generated by a model applied to the context
...@@ -56,31 +64,86 @@ class MovementGeneratorMixin: ...@@ -56,31 +64,86 @@ class MovementGeneratorMixin:
- implement rounding appropriately (True or False seems - implement rounding appropriately (True or False seems
simplistic) simplistic)
""" """
raise NotImplementedError # Default implementation bellow can be overriden by subclasses
# however it should be generic enough not to be overriden
def _getInputMovementAndPathTupleList(self, context): # by most classes
"""Returns list of tuples (movement, business_path)""" # Results will be appended to result, objects created inside folder
input_movement_list = self._getInputMovementList(context) result = []
business_process = context.getBusinessProcessValue() if self._applied_rule is None:
trade_phase_list = context.getSpecialiseValue().getTradePhaseList() folder = self
else:
# In non-BPM case, we have no business path. folder = self._applied_rule
if business_process is None or len(trade_phase_list) == 0: # Build a list of movement and business path
return [(input_movement, None) for input_movement in input_movement_list] for input_movement, business_path in self \
._getInputMovementAndPathTupleList(movement_list=movement_list,
input_movement_and_path_list = [] rounding=rounding):
# Merge movement and business path properties (core implementation)
kw = self._getPropertyAndCategoryDict(input_movement, business_path)
# Update movement properties (class overridable)
kw.update(self._getUpdatePropertyDict(input_movement))
# And build temp movement of appropriate type
simulation_movement = folder.newContent(
temp_object=True,
**kw)
result.append(simulation_movement)
return result
def _getUpdatePropertyDict(self, input_movement):
# Default implementation bellow can be overriden by subclasses
return {'delivery': input_movement.getRelativeUrl(),
'portal_type': RuleMixin.movement_type}
def _getTradePhaseList(self, input_movement, business_process):
if self._trade_phase_list:
return self._trade_phase_list
if self._rule:
self._rule.getTradePhaseList()
return business_process.getTradePhaseList()
def _getInputMovementAndPathTupleList(self, movement_list=None, rounding=None):
"""
Returns list of tuples (movement, business_path)
"""
# Init result
result = []
# First generate a list of movements with any appropriate method
input_movement_list = self._getInputMovementList(movement_list=movement_list, rounding=rounding)
# For each input movement
for input_movement in input_movement_list: for input_movement in input_movement_list:
for business_path in business_process.getPathValueList( # Find its business process, if any
business_process = input_movement.asComposedDocument() # This produces a business process ideally
# Initialise trade phase list for a movement and business process
trade_phase_list = self._getTradePhaseList(input_movement, business_process)
if business_process is None or len(trade_phase_list) == 0:
result.append((input_movement, None))
else:
for business_path in business_process.getPathValueList(
trade_phase_list, trade_phase_list,
input_movement) or [None]: input_movement) or [None]:
input_movement_and_path_list.append((input_movement, business_path)) result.append((input_movement, business_path))
return input_movement_and_path_list return result
def _getInputMovementList(self, context): def _getInputMovementList(self, movement_list=None, rounding=None):
raise NotImplementedError raise NotImplementedError
# Default implementation takes amounts ?
# Use TradeModelRuleMovementGenerator._getInputMovementList as default implementation
# and potentially use trade phase for that.... as a way to filter out
def _getPropertyAndCategoryDict(self, movement, business_path):
"""
Merge a movement and a business_path and return a dict of
properties and categories whch can be used to create a new movement.
movement -- an IMovement instance
business_path -- an IBusinessPath instance
def _getPropertyAndCategoryList(self, movement, business_path, rule=None): rule -- optional rule parameter which can be used to
narrow down properties to be copied
"""
rule = self._rule
if rule is None: if rule is None:
property_dict = _getPropertyAndCategoryList(movement) property_dict = _getPropertyAndCategoryList(movement)
else: else:
......
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