Commit e63028b4 authored by Romain Courteaud's avatar Romain Courteaud

Causality is now tested by Divergence Tester.

Rules now need to include divergence testers.


git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@11285 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent 825e0c2e
...@@ -284,7 +284,7 @@ class Delivery(XMLObject, ImmobilisationDelivery): ...@@ -284,7 +284,7 @@ class Delivery(XMLObject, ImmobilisationDelivery):
return 1 return 1
security.declareProtected(Permissions.View, 'isDivergent') security.declareProtected(Permissions.View, 'isDivergent')
def isDivergent(self,fast=0,**kw): def isDivergent(self, fast=0, **kw):
""" """
Returns 1 if the target is not met according to the current information Returns 1 if the target is not met according to the current information
After and edit, the isOutOfTarget will be checked. If it is 1, After and edit, the isOutOfTarget will be checked. If it is 1,
...@@ -304,6 +304,16 @@ class Delivery(XMLObject, ImmobilisationDelivery): ...@@ -304,6 +304,16 @@ class Delivery(XMLObject, ImmobilisationDelivery):
return 1 return 1
return 0 return 0
security.declareProtected(Permissions.View, 'getDivergenceList')
def getDivergenceList(self):
"""
Return a list of messages that contains the divergences
"""
divergence_list = []
for movement in self.getMovementList():
divergence_list.extend(movement.getDivergenceList())
return divergence_list
def updateCausalityState(self,**kw): def updateCausalityState(self,**kw):
""" """
This is often called as an activity, it will check if the This is often called as an activity, it will check if the
...@@ -554,8 +564,8 @@ class Delivery(XMLObject, ImmobilisationDelivery): ...@@ -554,8 +564,8 @@ class Delivery(XMLObject, ImmobilisationDelivery):
# Applied Rule stuff # Applied Rule stuff
def updateAppliedRule(self, rule_id,force=0,**kw): def updateAppliedRule(self, rule_id,force=0,**kw):
""" """
Create a new Applied Rule is none is related, or call expand Create a new Applied Rule is none is related, or call expand
on the existing one. on the existing one.
""" """
if (rule_id is not None) and\ if (rule_id is not None) and\
(self.getSimulationState() not in \ (self.getSimulationState() not in \
......
...@@ -69,6 +69,7 @@ class DeliveryLine(Movement, XMLObject, XMLMatrix, Variated, ...@@ -69,6 +69,7 @@ class DeliveryLine(Movement, XMLObject, XMLMatrix, Variated,
, PropertySheet.Price , PropertySheet.Price
, PropertySheet.VariationRange , PropertySheet.VariationRange
, PropertySheet.ItemAggregation , PropertySheet.ItemAggregation
, PropertySheet.SortIndex
) )
# Multiple inheritance definition # Multiple inheritance definition
...@@ -217,13 +218,25 @@ class DeliveryLine(Movement, XMLObject, XMLMatrix, Variated, ...@@ -217,13 +218,25 @@ class DeliveryLine(Movement, XMLObject, XMLMatrix, Variated,
emit targetUnreachable ! emit targetUnreachable !
""" """
if self.getDivergenceList() == []:
return 0
else:
return 1
security.declareProtected(Permissions.View, 'getDivergentList')
def getDivergenceList(self):
"""
Return a list of messages that contains the divergences
"""
divergence_list = []
if self.hasCellContent(): if self.hasCellContent():
for cell in self.contentValues(filter={'portal_type': self.getPortalDeliveryMovementTypeList()}): for cell in self.contentValues(filter={
if cell.isDivergent(): 'portal_type': self.getPortalDeliveryMovementTypeList()}):
return 1 divergence_list.extend(cell.getDivergenceList())
return divergence_list
else: else:
return Movement.isDivergent(self) return Movement.getDivergenceList(self)
def applyToDeliveryLineRelatedMovement(self, portal_type='Simulation Movement', method_id = 'expand'): def applyToDeliveryLineRelatedMovement(self, portal_type='Simulation Movement', method_id = 'expand'):
# Find related in simulation # Find related in simulation
for my_simulation_movement in self.getDeliveryRelatedValueList( for my_simulation_movement in self.getDeliveryRelatedValueList(
......
...@@ -89,9 +89,8 @@ class DeliveryRule(Rule): ...@@ -89,9 +89,8 @@ class DeliveryRule(Rule):
delivery_movement_list = delivery.getMovementList() delivery_movement_list = delivery.getMovementList()
# Check existing movements # Check existing movements
for movement in applied_rule.contentValues(portal_type=movement_type): for movement in applied_rule.contentValues(portal_type=movement_type):
if movement.getLastExpandSimulationState() not in \ if movement.getLastExpandSimulationState() in \
delivery.getPortalCurrentInventoryStateList(): delivery.getPortalDraftOrderStateList():
movement_delivery = movement.getDeliveryValue() movement_delivery = movement.getDeliveryValue()
if not self._isTreeDelivered([movement], ignore_first=1) and \ if not self._isTreeDelivered([movement], ignore_first=1) and \
movement_delivery not in delivery_movement_list: movement_delivery not in delivery_movement_list:
...@@ -184,7 +183,7 @@ class DeliveryRule(Rule): ...@@ -184,7 +183,7 @@ class DeliveryRule(Rule):
# Solvers # Solvers
security.declareProtected(Permissions.AccessContentsInformation, 'isStable') security.declareProtected(Permissions.AccessContentsInformation, 'isStable')
def isStable(self, movement): def isStable(self, applied_rule):
""" """
Checks that the applied_rule is stable Checks that the applied_rule is stable
""" """
......
...@@ -185,7 +185,6 @@ class InvoiceTransactionRule(Rule, PredicateMatrix): ...@@ -185,7 +185,6 @@ class InvoiceTransactionRule(Rule, PredicateMatrix):
# Pass to base class # Pass to base class
Rule.expand(self, applied_rule, force=force, **kw) Rule.expand(self, applied_rule, force=force, **kw)
# Matrix related # Matrix related
security.declareProtected( Permissions.ModifyPortalContent, security.declareProtected( Permissions.ModifyPortalContent,
...@@ -221,24 +220,24 @@ class InvoiceTransactionRule(Rule, PredicateMatrix): ...@@ -221,24 +220,24 @@ class InvoiceTransactionRule(Rule, PredicateMatrix):
and blocks expansion process and blocks expansion process
""" """
# Solvers # # Solvers
security.declareProtected(Permissions.View, 'isDivergent') # security.declareProtected(Permissions.View, 'isDivergent')
def isDivergent(self, applied_rule): # def isDivergent(self, applied_rule):
""" # """
Returns 1 if divergent rule # Returns 1 if divergent rule
""" # """
#
security.declareProtected(Permissions.View, 'getDivergenceList') # security.declareProtected(Permissions.View, 'getDivergenceList')
def getDivergenceList(self, applied_rule): # def getDivergenceList(self, applied_rule):
""" # """
Returns a list Divergence descriptors # Returns a list Divergence descriptors
""" # """
#
security.declareProtected(Permissions.View, 'getSolverList') # security.declareProtected(Permissions.View, 'getSolverList')
def getSolverList(self, applied_rule): # def getSolverList(self, applied_rule):
""" # """
Returns a list Divergence solvers # Returns a list Divergence solvers
""" # """
# Deliverability / orderability # Deliverability / orderability
def isOrderable(self, m): def isOrderable(self, m):
......
...@@ -38,7 +38,7 @@ from Products.ERP5Type.XMLObject import XMLObject ...@@ -38,7 +38,7 @@ from Products.ERP5Type.XMLObject import XMLObject
from Products.ERP5.Document.Amount import Amount from Products.ERP5.Document.Amount import Amount
from zLOG import LOG, WARNING from zLOG import LOG, WARNING, DEBUG
class Movement(XMLObject, Amount): class Movement(XMLObject, Amount):
""" """
...@@ -423,6 +423,16 @@ class Movement(XMLObject, Amount): ...@@ -423,6 +423,16 @@ class Movement(XMLObject, Amount):
return 1 return 1
return 0 return 0
def getDivergenceList(self):
"""
Return a list of messages that contains the divergences
"""
divergence_list = []
for simulation_movement in self.getDeliveryRelatedValueList():
divergence_list.extend(simulation_movement.getDivergenceList())
return divergence_list
security.declareProtected(Permissions.AccessContentsInformation, security.declareProtected(Permissions.AccessContentsInformation,
'isFrozen') 'isFrozen')
def isFrozen(self): def isFrozen(self):
...@@ -435,7 +445,7 @@ class Movement(XMLObject, Amount): ...@@ -435,7 +445,7 @@ class Movement(XMLObject, Amount):
# XXX Hardcoded # XXX Hardcoded
# Maybe, we should use getPortalCurrentInventoryStateList # Maybe, we should use getPortalCurrentInventoryStateList
# and another portal method for cancelled (and deleted) # and another portal method for cancelled (and deleted)
#LOG("Movement, isFrozen", WARNING, "Hardcoded state list") # LOG("Movement, isFrozen", DEBUG, "Hardcoded state list")
if self.getSimulationState() in ('stopped', 'delivered', 'cancelled'): if self.getSimulationState() in ('stopped', 'delivered', 'cancelled'):
return 1 return 1
if self._baseIsFrozen() == 0: if self._baseIsFrozen() == 0:
......
...@@ -175,53 +175,36 @@ class Rule(XMLObject, Predicate): ...@@ -175,53 +175,36 @@ class Rule(XMLObject, Predicate):
# Solvers # Solvers
security.declareProtected( Permissions.AccessContentsInformation, security.declareProtected( Permissions.AccessContentsInformation,
'isDivergent') 'isDivergent')
def isDivergent(self, movement, ignore_list=[]): def isDivergent(self, sim_mvt, ignore_list=[]):
""" """
Returns true if the Simulation Movement is divergent comparing to Returns true if the Simulation Movement is divergent comparing to
the delivery value the delivery value
""" """
delivery = movement.getDeliveryValue() delivery = sim_mvt.getDeliveryValue()
if delivery is None: if delivery is None:
return 0 return 0
default_match_list = ( if self.getDivergenceList(sim_mvt) == []:
'source_section', 'destination_section', 'source', return 0
'destination', 'resource', 'variation_category_list', else:
'aggregate_list', 'start_date', 'stop_date')
match_list = [x for x in default_match_list if x not in ignore_list]
for prop in match_list:
if movement.getProperty(prop) != delivery.getProperty(prop):
return 1
d_quantity = delivery.getQuantity()
quantity = movement.getCorrectedQuantity()
d_error = movement.getDeliveryError()
if quantity is None:
if d_quantity is None:
return 0
return 1
if d_quantity is None:
d_quantity = 0
if d_error is None:
d_error = 0
delivery_ratio = movement.getDeliveryRatio()
# if the delivery_ratio is None, make sure that we are
# divergent even if the delivery quantity is 0
if delivery_ratio is not None:
d_quantity *= delivery_ratio
if delivery_ratio == 0 and quantity > 0:
return 1
if d_quantity != quantity + d_error:
return 1 return 1
return 0
security.declareProtected(Permissions.View, 'getDivergenceList')
# security.declareProtected(Permissions.View, 'getDivergenceList') def getDivergenceList(self, sim_mvt):
# def getDivergenceList(self, applied_rule): """
# """ Return a list of messages that contains the divergences.
# Returns a list Divergence descriptors """
# """ result_list = []
# for divergence_tester in self.contentValues(
portal_type=self.getPortalDivergenceTesterTypeList()):
result = divergence_tester.explain(sim_mvt)
result_list.extend(result)
return result_list
# XXX getSolverList is not part of the API and should be removed.
# Use getDivergenceList instead.
# security.declareProtected(Permissions.View, 'getSolverList') # security.declareProtected(Permissions.View, 'getSolverList')
# def getSolverList(self, applied_rule): # def getSolverList(self, applied_rule):
# """ # """
# Returns a list Divergence solvers # Returns a list Divergence solvers
...@@ -330,8 +313,8 @@ class Rule(XMLObject, Predicate): ...@@ -330,8 +313,8 @@ class Rule(XMLObject, Predicate):
p_matched_list.append(movement) p_matched_list.append(movement)
# XXX hardcoded ... # XXX hardcoded ...
LOG("Rule, _getCompensatedMovementList", WARNING, # LOG("Rule, _getCompensatedMovementList", WARNING,
"Hardcoded properties check") # "Hardcoded properties check")
# Movements exist, we'll try to make them match the prevision # Movements exist, we'll try to make them match the prevision
if p_matched_list != []: if p_matched_list != []:
# Check the quantity # Check the quantity
......
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