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 @@
from Products.ERP5.MovementCollectionDiff import _getPropertyAndCategoryList
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
can be used to generate an IMovementList from
an existing IMovementCollection, IMovementList or
IMovement. Typical IMovementGenerator are Rules
and Trade Conditions.
TODO:
Deliveries ? Movements ? Items ?
Does it depend by default on IAmountGeneratorMixin
"""
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
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
......@@ -56,31 +64,86 @@ class MovementGeneratorMixin:
- implement rounding appropriately (True or False seems
simplistic)
"""
raise NotImplementedError
def _getInputMovementAndPathTupleList(self, context):
"""Returns list of tuples (movement, business_path)"""
input_movement_list = self._getInputMovementList(context)
business_process = context.getBusinessProcessValue()
trade_phase_list = context.getSpecialiseValue().getTradePhaseList()
# In non-BPM case, we have no business path.
if business_process is None or len(trade_phase_list) == 0:
return [(input_movement, None) for input_movement in input_movement_list]
input_movement_and_path_list = []
# Default implementation bellow can be overriden by subclasses
# however it should be generic enough not to be overriden
# by most classes
# Results will be appended to result, objects created inside folder
result = []
if self._applied_rule is None:
folder = self
else:
folder = self._applied_rule
# Build a list of movement and business path
for input_movement, business_path in self \
._getInputMovementAndPathTupleList(movement_list=movement_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 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,
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
# 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:
property_dict = _getPropertyAndCategoryList(movement)
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