Commit 19d44646 authored by Alexandre Boeglin's avatar Alexandre Boeglin

Rules are now used as predicates:

- add PortalGroupedTypeList 'rule'
- Rule is a Predicate, it has a reference and a version
- RuleTool has a method named searchRuleList
- searchRuleList is used by SimulationMovement.expand
- test methods on Rules are no longer used


git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@17417 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent 3c75ea67
...@@ -87,14 +87,6 @@ class AmortisationRule(Rule): ...@@ -87,14 +87,6 @@ class AmortisationRule(Rule):
'correction': 'correction' 'correction': 'correction'
} }
def _test(self, movement):
"""
Tests if the rule (still) applies
"""
# An order rule never applies since it is always explicitely instanciated
# XXX And if it is an amortisation rule ?
return 0
# Simulation workflow # Simulation workflow
security.declareProtected(Permissions.ModifyPortalContent, 'expand') security.declareProtected(Permissions.ModifyPortalContent, 'expand')
......
...@@ -73,18 +73,6 @@ class AppliedRule(XMLObject): ...@@ -73,18 +73,6 @@ class AppliedRule(XMLObject):
""" show the content in the left pane of the ZMI """ """ show the content in the left pane of the ZMI """
return self.objectValues() return self.objectValues()
security.declareProtected(Permissions.AccessContentsInformation, 'test')
def test(self):
"""
Tests if the rule (still) applies
"""
if self.isRootAppliedRule():
return 1
else:
parent_value = self.getParentValue()
rule = self.getSpecialiseValue()
return rule.test(parent_value)
security.declareProtected(Permissions.AccessContentsInformation, security.declareProtected(Permissions.AccessContentsInformation,
'isAccountable') 'isAccountable')
def isAccountable(self, movement): def isAccountable(self, movement):
......
...@@ -656,11 +656,27 @@ class Delivery(XMLObject, ImmobilisationDelivery): ...@@ -656,11 +656,27 @@ 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 if none is related, or call expand
on the existing one. on the existing one.
The chosen applied rule will be the validated rule with reference ==
rule_id, and the higher version number.
If no rule is found, simply pass rule_id to _createAppliedRule, as we
did previously.
""" """
if (rule_id is not None) and\ if rule_id is None:
(self.getSimulationState() not in \ return
portal_rules = getToolByName(self, 'portal_rules')
res = portal_rules.searchFolder(reference=rule_id,
validation_state="validated", sort_on='version',
sort_order='descending') # XXX validated is Hardcoded !
if len(res) > 0:
rule_id = res[0].getId()
if (self.getSimulationState() not in \
self.getPortalDraftOrderStateList()): self.getPortalDraftOrderStateList()):
# Nothing to do if we are already simulated # Nothing to do if we are already simulated
self._createAppliedRule(rule_id,force=force,**kw) self._createAppliedRule(rule_id,force=force,**kw)
......
...@@ -59,15 +59,6 @@ class DeliveryRule(Rule): ...@@ -59,15 +59,6 @@ class DeliveryRule(Rule):
, PropertySheet.Task , PropertySheet.Task
) )
def _test(self, movement):
"""
Default behaviour of DeliveryRule.test
Tests if the rule (still) applies
"""
# A delivery rule never applies
# since it is always explicitely instanciated
return 0
# Simulation workflow # Simulation workflow
security.declareProtected(Permissions.ModifyPortalContent, 'expand') security.declareProtected(Permissions.ModifyPortalContent, 'expand')
def expand(self, applied_rule, **kw): def expand(self, applied_rule, **kw):
......
...@@ -63,30 +63,6 @@ class InvoiceTransactionRule(Rule, PredicateMatrix): ...@@ -63,30 +63,6 @@ class InvoiceTransactionRule(Rule, PredicateMatrix):
, PropertySheet.Task , PropertySheet.Task
) )
def _test(self, movement):
"""
Tests if the rule (still) applies
"""
# An invoice transaction rule applies when the movement's
# parent is an invoice rule
# If the parent rule is a Invoice Rule, we must also make sure that the
# movement's delivery is a Invoice Movement (and not a Accounting one)
parent = movement.getParentValue()
parent_rule_value = parent.getSpecialiseValue()
if parent_rule_value is None:
return 0
parent_rule_type = parent_rule_value.getPortalType()
if parent_rule_type in ('Invoicing Rule', 'Invoice Rule'):
if parent_rule_type == 'Invoice Rule':
delivery_movement = movement.getDeliveryValue()
if delivery_movement is not None:
if delivery_movement.getPortalType() not in \
movement.getPortalInvoiceMovementTypeList():
return 0
if self._getMatchingCell(movement) is not None:
return 1
return 0
#### Helper method for expand #### Helper method for expand
def _generatePrevisionList(self, applied_rule, **kw): def _generatePrevisionList(self, applied_rule, **kw):
""" """
......
...@@ -75,18 +75,6 @@ class InvoicingRule(Rule): ...@@ -75,18 +75,6 @@ class InvoicingRule(Rule):
""" """
return 0 return 0
def _test(self, movement):
"""
Tests if the rule (still) applies
"""
parent = movement.getParentValue()
result = 0
if (parent.getPortalType() == 'Applied Rule') and \
(parent.getSpecialiseId() in ('default_order_rule',
'default_delivery_rule' )):
result = 1
return result
#### Helper method for expand #### Helper method for expand
def _generatePrevisionList(self, applied_rule, **kw): def _generatePrevisionList(self, applied_rule, **kw):
""" """
......
...@@ -34,7 +34,7 @@ from Products.ERP5.Document.Predicate import Predicate ...@@ -34,7 +34,7 @@ from Products.ERP5.Document.Predicate import Predicate
from Acquisition import aq_base, aq_parent, aq_inner, aq_acquire from Acquisition import aq_base, aq_parent, aq_inner, aq_acquire
from zLOG import LOG, WARNING from zLOG import LOG, WARNING
class Rule(XMLObject, Predicate): class Rule(Predicate, XMLObject):
""" """
Rule objects implement the simulation algorithm Rule objects implement the simulation algorithm
(expand, solve) (expand, solve)
...@@ -67,6 +67,7 @@ class Rule(XMLObject, Predicate): ...@@ -67,6 +67,7 @@ class Rule(XMLObject, Predicate):
add_permission = Permissions.AddPortalContent add_permission = Permissions.AddPortalContent
isPortalContent = 1 isPortalContent = 1
isRADContent = 1 isRADContent = 1
isPredicate = 1
# Declarative security # Declarative security
security = ClassSecurityInfo() security = ClassSecurityInfo()
...@@ -81,6 +82,9 @@ class Rule(XMLObject, Predicate): ...@@ -81,6 +82,9 @@ class Rule(XMLObject, Predicate):
, PropertySheet.CategoryCore , PropertySheet.CategoryCore
, PropertySheet.DublinCore , PropertySheet.DublinCore
, PropertySheet.Task , PropertySheet.Task
, PropertySheet.Predicate
, PropertySheet.Reference
, PropertySheet.Version
) )
# Portal Type of created children # Portal Type of created children
...@@ -140,29 +144,6 @@ class Rule(XMLObject, Predicate): ...@@ -140,29 +144,6 @@ class Rule(XMLObject, Predicate):
diverge is called on the parent movement. diverge is called on the parent movement.
""" """
def test(self, movement):
"""
Tests if the rule (still) applies
First try to call a python script, then call the _test method defined in
the class
This method should not be overriden by Rules.
"""
method = self._getTypeBasedMethod('test')
if method is not None:
return method(movement)
return self._test(movement)
def _test(self, movement):
"""
Default behaviour of Rule.test, used when no test method for the rule
was defined
This method should be overriden by Rules if another default behaviour is
wanted.
"""
return 0
security.declareProtected(Permissions.ModifyPortalContent, 'diverge') security.declareProtected(Permissions.ModifyPortalContent, 'diverge')
def diverge(self, applied_rule): def diverge(self, applied_rule):
""" """
......
...@@ -223,7 +223,7 @@ class SimulationMovement(Movement): ...@@ -223,7 +223,7 @@ class SimulationMovement(Movement):
# we know that invoicing rule acts like this, and that it comes after # we know that invoicing rule acts like this, and that it comes after
# invoice or invoicing_rule, so we if we come from invoince rule or # invoice or invoicing_rule, so we if we come from invoince rule or
# invoicing rule, we always expand regardless of the causality state. # invoicing rule, we always expand regardless of the causality state.
if ((self.getParentValue().getSpecialiseId() not in if ((self.getParentValue().getSpecialiseReference() not in
('default_invoicing_rule', 'default_invoice_rule') ('default_invoicing_rule', 'default_invoice_rule')
and self.getCausalityState() == 'expanded' ) or \ and self.getCausalityState() == 'expanded' ) or \
len(self.objectIds()) != 0): len(self.objectIds()) != 0):
...@@ -233,9 +233,8 @@ class SimulationMovement(Movement): ...@@ -233,9 +233,8 @@ class SimulationMovement(Movement):
else: else:
portal_rules = getToolByName(self, 'portal_rules') portal_rules = getToolByName(self, 'portal_rules')
# Parse each rule and test if it applies # Parse each rule and test if it applies
for rule in portal_rules.objectValues(): for rule in portal_rules.searchRuleList(self):
if rule.test(self): rule.constructNewAppliedRule(self, **kw)
my_applied_rule = rule.constructNewAppliedRule(self, **kw)
for my_applied_rule in self.objectValues() : for my_applied_rule in self.objectValues() :
my_applied_rule.expand(force=force,**kw) my_applied_rule.expand(force=force,**kw)
# Set to expanded # Set to expanded
......
...@@ -656,6 +656,14 @@ class ERP5Site(FolderMixIn, CMFSite): ...@@ -656,6 +656,14 @@ class ERP5Site(FolderMixIn, CMFSite):
return self._getPortalGroupedTypeList('supply') or \ return self._getPortalGroupedTypeList('supply') or \
self._getPortalConfiguration('portal_supply_type_list') self._getPortalConfiguration('portal_supply_type_list')
security.declareProtected(Permissions.AccessContentsInformation,
'getPortalRuleTypeList')
def getPortalRuleTypeList(self):
"""
Return rule types.
"""
return self._getPortalGroupedTypeList('rule')
security.declareProtected(Permissions.AccessContentsInformation, security.declareProtected(Permissions.AccessContentsInformation,
'getPortalProjectTypeList') 'getPortalProjectTypeList')
def getPortalProjectTypeList(self): def getPortalProjectTypeList(self):
......
...@@ -32,6 +32,7 @@ from AccessControl import ClassSecurityInfo ...@@ -32,6 +32,7 @@ from AccessControl import ClassSecurityInfo
from Globals import InitializeClass, DTMLFile from Globals import InitializeClass, DTMLFile
from Products.ERP5Type.Core.Folder import Folder from Products.ERP5Type.Core.Folder import Folder
from Products.ERP5Type import Permissions from Products.ERP5Type import Permissions
from Products.CMFCore.utils import getToolByName
from Products.ERP5 import _dtmldir from Products.ERP5 import _dtmldir
...@@ -119,5 +120,23 @@ class RuleTool (UniqueObject, Folder): ...@@ -119,5 +120,23 @@ class RuleTool (UniqueObject, Folder):
meta_types.append(meta_type) meta_types.append(meta_type)
return meta_types return meta_types
security.declareProtected(Permissions.AccessContentsInformation,
'searchRuleList')
def searchRuleList(self, movement, tested_base_category_list=[], **kw):
"""
this method searches for rules, as predicates against movement
- the rule must be in "validated" state
- the rule must be of a known portal type
- Predicate criterions can be used (like start_date_range_min)
"""
domain_tool = getToolByName(self, "portal_domains")
rule_list = domain_tool.searchPredicateList(context=movement,
tested_base_category_list=tested_base_category_list,
portal_type=self.getPortalRuleTypeList(),
validation_state="validated", **kw) #XXX "validated" is hardcoded
return rule_list
InitializeClass(RuleTool) InitializeClass(RuleTool)
...@@ -162,7 +162,7 @@ class ERP5TypeInformation( FactoryTypeInformation, ...@@ -162,7 +162,7 @@ class ERP5TypeInformation( FactoryTypeInformation,
# with great care. # with great care.
defined_group_list = ( defined_group_list = (
# Framework # Framework
'alarm', 'alarm', 'rule',
# ERP5 UBM (5 Classes) # ERP5 UBM (5 Classes)
'resource', 'node', 'item', 'resource', 'node', 'item',
'delivery', 'delivery_movement', 'delivery', 'delivery_movement',
......
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