Commit 19d44646 by 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
1 parent 3c75ea67
......@@ -86,14 +86,6 @@ class AmortisationRule(Rule):
'depr': 'transfer_depr'},
'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
......
......@@ -73,18 +73,6 @@ class AppliedRule(XMLObject):
""" show the content in the left pane of the ZMI """
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,
'isAccountable')
def isAccountable(self, movement):
......
......@@ -656,11 +656,27 @@ class Delivery(XMLObject, ImmobilisationDelivery):
# Applied Rule stuff
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.
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\
(self.getSimulationState() not in \
if rule_id is None:
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()):
# Nothing to do if we are already simulated
self._createAppliedRule(rule_id,force=force,**kw)
......
......@@ -59,15 +59,6 @@ class DeliveryRule(Rule):
, 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
security.declareProtected(Permissions.ModifyPortalContent, 'expand')
def expand(self, applied_rule, **kw):
......
......@@ -63,30 +63,6 @@ class InvoiceTransactionRule(Rule, PredicateMatrix):
, 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
def _generatePrevisionList(self, applied_rule, **kw):
"""
......
......@@ -75,18 +75,6 @@ class InvoicingRule(Rule):
"""
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
def _generatePrevisionList(self, applied_rule, **kw):
"""
......
......@@ -34,7 +34,7 @@ from Products.ERP5.Document.Predicate import Predicate
from Acquisition import aq_base, aq_parent, aq_inner, aq_acquire
from zLOG import LOG, WARNING
class Rule(XMLObject, Predicate):
class Rule(Predicate, XMLObject):
"""
Rule objects implement the simulation algorithm
(expand, solve)
......@@ -67,6 +67,7 @@ class Rule(XMLObject, Predicate):
add_permission = Permissions.AddPortalContent
isPortalContent = 1
isRADContent = 1
isPredicate = 1
# Declarative security
security = ClassSecurityInfo()
......@@ -81,6 +82,9 @@ class Rule(XMLObject, Predicate):
, PropertySheet.CategoryCore
, PropertySheet.DublinCore
, PropertySheet.Task
, PropertySheet.Predicate
, PropertySheet.Reference
, PropertySheet.Version
)
# Portal Type of created children
......@@ -140,29 +144,6 @@ class Rule(XMLObject, Predicate):
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')
def diverge(self, applied_rule):
"""
......
......@@ -223,7 +223,7 @@ class SimulationMovement(Movement):
# 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
# 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')
and self.getCausalityState() == 'expanded' ) or \
len(self.objectIds()) != 0):
......@@ -233,9 +233,8 @@ class SimulationMovement(Movement):
else:
portal_rules = getToolByName(self, 'portal_rules')
# Parse each rule and test if it applies
for rule in portal_rules.objectValues():
if rule.test(self):
my_applied_rule = rule.constructNewAppliedRule(self, **kw)
for rule in portal_rules.searchRuleList(self):
rule.constructNewAppliedRule(self, **kw)
for my_applied_rule in self.objectValues() :
my_applied_rule.expand(force=force,**kw)
# Set to expanded
......
......@@ -657,6 +657,14 @@ class ERP5Site(FolderMixIn, CMFSite):
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,
'getPortalProjectTypeList')
def getPortalProjectTypeList(self):
"""
......
......@@ -32,6 +32,7 @@ from AccessControl import ClassSecurityInfo
from Globals import InitializeClass, DTMLFile
from Products.ERP5Type.Core.Folder import Folder
from Products.ERP5Type import Permissions
from Products.CMFCore.utils import getToolByName
from Products.ERP5 import _dtmldir
......@@ -119,5 +120,23 @@ class RuleTool (UniqueObject, Folder):
meta_types.append(meta_type)
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)
......@@ -162,7 +162,7 @@ class ERP5TypeInformation( FactoryTypeInformation,
# with great care.
defined_group_list = (
# Framework
'alarm',
'alarm', 'rule',
# ERP5 UBM (5 Classes)
'resource', 'node', 'item',
'delivery', 'delivery_movement',
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!