Commit f7a33d0a authored by Jérome Perrin's avatar Jérome Perrin

simulation: introduce Rule.getSimulationMovementSimulationState

and move the implementation of SimulationMovement.getSimulationState
here. This makes it possible for rules to generate simulation movements
that are not necessary planned.
parent 348d5be5
Pipeline #37616 failed with stage
in 0 seconds
...@@ -128,13 +128,8 @@ class SimulationMovement(PropertyRecordableMixin, Movement, ExplainableMixin): ...@@ -128,13 +128,8 @@ class SimulationMovement(PropertyRecordableMixin, Movement, ExplainableMixin):
def getSimulationState(self, id_only=1): def getSimulationState(self, id_only=1):
"""Returns the current state in simulation """Returns the current state in simulation
Inherit from delivery or parent (using a conversion table to make orders Inherit from delivery when built, otherwise, let the rule decide.
planned when parent is confirmed).
In the case of simulation coming from an item, the simulation state is
delegated to the item.
XXX: movements in zero stock rule can not acquire simulation state
""" """
delivery = self.getDeliveryValue() delivery = self.getDeliveryValue()
if delivery is not None: if delivery is not None:
...@@ -145,18 +140,8 @@ class SimulationMovement(PropertyRecordableMixin, Movement, ExplainableMixin): ...@@ -145,18 +140,8 @@ class SimulationMovement(PropertyRecordableMixin, Movement, ExplainableMixin):
return order.getSimulationState() return order.getSimulationState()
applied_rule = self.getParentValue() applied_rule = self.getParentValue()
parent = applied_rule.getParentValue() rule = applied_rule.getSpecialiseValue()
try: return rule.getSimulationMovementSimulationState(self)
if isinstance(parent, SimulationMovement):
return parent_to_movement_simulation_state[parent.getSimulationState()]
getState = applied_rule.getCausalityValue() \
.aq_explicit.getSimulationMovementSimulationState
except (AttributeError, KeyError):
LOG('SimulationMovement.getSimulationState', WARNING,
'Could not acquire simulation state from %s'
% self.getRelativeUrl(), error=True)
else:
return getState(self)
security.declareProtected( Permissions.AccessContentsInformation, security.declareProtected( Permissions.AccessContentsInformation,
'getTranslatedSimulationStateTitle') 'getTranslatedSimulationStateTitle')
......
...@@ -73,3 +73,8 @@ class IRule(IMovementCollectionUpdater): ...@@ -73,3 +73,8 @@ class IRule(IMovementCollectionUpdater):
Available policies: immediate, deferred, vertical_time_bound Available policies: immediate, deferred, vertical_time_bound
""" """
def getSimulationMovementSimulationState(simulation_movement):
"""
Compute the simulation state of this simulation movement.
"""
...@@ -26,16 +26,22 @@ ...@@ -26,16 +26,22 @@
# #
############################################################################## ##############################################################################
import logging
import zope.interface import zope.interface
from AccessControl import ClassSecurityInfo from AccessControl import ClassSecurityInfo
from Products.ERP5Type.Globals import InitializeClass from Products.ERP5Type.Globals import InitializeClass
from Products.ERP5Type import Permissions from Products.ERP5Type import Permissions
from Products.ERP5Type.Core.Predicate import Predicate from Products.ERP5Type.Core.Predicate import Predicate
from erp5.component.module.ExpandPolicy import policy_dict from erp5.component.module.ExpandPolicy import policy_dict
from erp5.component.document.SimulationMovement import SimulationMovement, parent_to_movement_simulation_state
from erp5.component.interface.IRule import IRule from erp5.component.interface.IRule import IRule
from erp5.component.interface.IDivergenceController import IDivergenceController from erp5.component.interface.IDivergenceController import IDivergenceController
from erp5.component.interface.IMovementCollectionUpdater import IMovementCollectionUpdater from erp5.component.interface.IMovementCollectionUpdater import IMovementCollectionUpdater
logger = logging.getLogger(__name__)
def _compare(tester_list, prevision_movement, decision_movement): def _compare(tester_list, prevision_movement, decision_movement):
for tester in tester_list: for tester in tester_list:
if not tester.compare(prevision_movement, decision_movement): if not tester.compare(prevision_movement, decision_movement):
...@@ -127,6 +133,36 @@ class RuleMixin(Predicate): ...@@ -127,6 +133,36 @@ class RuleMixin(Predicate):
""" """
return not movement.getDelivery() return not movement.getDelivery()
security.declareProtected(Permissions.AccessContentsInformation,
'getSimulationMovementSimulationState')
def getSimulationMovementSimulationState(self, simulation_movement):
"""
Compute the simulation state of this simulation movement.
Inherit from parent movement, using a conversion table to make
orders planned when parent is confirmed.
In the case of simulation coming from an item, the simulation state is
delegated to the item.
This method can be overridden in custom rule class to generate movements
with a different simulation state.
"""
applied_rule = simulation_movement.getParentValue()
parent_simulation_movement = applied_rule.getParentValue()
try:
if isinstance(parent_simulation_movement, SimulationMovement):
return parent_to_movement_simulation_state[parent_simulation_movement.getSimulationState()]
getSimulationMovementSimulationState = applied_rule.getCausalityValue() \
.aq_explicit.getSimulationMovementSimulationState
except (AttributeError, KeyError):
logger.warning(
'getSimulationState: Could not acquire simulation state from %s',
simulation_movement,
error=True)
else:
return getSimulationMovementSimulationState(simulation_movement)
# Implementation of IDivergenceController # XXX-JPS move to IDivergenceController only mixin for # Implementation of IDivergenceController # XXX-JPS move to IDivergenceController only mixin for
security.declareProtected( Permissions.AccessContentsInformation, security.declareProtected( Permissions.AccessContentsInformation,
'isDivergent') 'isDivergent')
......
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