[Erp5-report] r17756 - /erp5/trunk/products/ERP5/Document/
nobody at svn.erp5.org
nobody at svn.erp5.org
Thu Nov 22 18:47:29 CET 2007
Author: alex
Date: Thu Nov 22 18:47:28 2007
New Revision: 17756
URL: http://svn.erp5.org?rev=17756&view=rev
Log:
* _isTreeDelivered method moved from Rule to AppliedRule and
SimulationMovement
* added transactional variable based cache to _isTreeDelivered
* activate and flush _isTreeDelivered cache in SimulationMovement.expand and
AppliedRule.expand (so that it's only active when calling expand, and
flushed afterwards, to prevent issues if we call expand in the same
transaction as a builder)
* modified SimulationMovement.expand behaviour, so that it removes applied
rules that no longer test(), and add new ones, if no movment in the applied
rule sub tree is linked to a delivery
Modified:
erp5/trunk/products/ERP5/Document/AppliedRule.py
erp5/trunk/products/ERP5/Document/DeliveryRule.py
erp5/trunk/products/ERP5/Document/OrderRule.py
erp5/trunk/products/ERP5/Document/Rule.py
erp5/trunk/products/ERP5/Document/SimulationMovement.py
Modified: erp5/trunk/products/ERP5/Document/AppliedRule.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5/Document/AppliedRule.py?rev=17756&r1=17755&r2=17756&view=diff
==============================================================================
--- erp5/trunk/products/ERP5/Document/AppliedRule.py (original)
+++ erp5/trunk/products/ERP5/Document/AppliedRule.py Thu Nov 22 18:47:28 2007
@@ -31,8 +31,12 @@
from Products.ERP5Type import Permissions, PropertySheet, Constraint, Interface
from Products.ERP5Type.XMLObject import XMLObject
from Products.ERP5Type.PsycoWrapper import psyco
+from Products.ERP5Type.TransactionalVariable import getTransactionalVariable
from zLOG import LOG
+
+TREE_DELIVERED_CACHE_KEY = 'AppliedRule._isTreeDelivered_cache'
+TREE_DELIVERED_CACHE_ENABLED = 'TREE_DELIVERED_CACHE_ENABLED'
class AppliedRule(XMLObject):
"""
@@ -89,6 +93,14 @@
An applied rule can be expanded only if its parent movement
is expanded.
"""
+ tv = getTransactionalVariable(self)
+ cache = tv.setdefault(TREE_DELIVERED_CACHE_KEY, {})
+ cache_enabled = cache.get(TREE_DELIVERED_CACHE_ENABLED, 0)
+
+ # enable cache
+ if not cache_enabled:
+ cache[TREE_DELIVERED_CACHE_ENABLED] = 1
+
rule = self.getSpecialiseValue()
if rule is not None:
if self.isRootAppliedRule():
@@ -102,6 +114,13 @@
# "recursiveImmediateReindexObject"]).\
# notifySimulationChange(rule._v_notify_dict)
+ # disable and clear cache
+ if not cache_enabled:
+ try:
+ del tv[TREE_DELIVERED_CACHE_KEY]
+ except KeyError:
+ pass
+
security.declareProtected(Permissions.ModifyPortalContent, 'solve')
def solve(self, solution_list):
"""
@@ -193,3 +212,33 @@
delivery_url)
else:
delivery_value.notifySimulationChange()
+
+ def _isTreeDelivered(self):
+ """
+ Checks if submovements of this applied rule (going down the complete
+ simulation tree) have a delivery relation.
+ Returns True if at least one is delivered, False if none of them are.
+
+ see SimulationMovement._isTreeDelivered
+ """
+ tv = getTransactionalVariable(self)
+ cache = tv.setdefault(TREE_DELIVERED_CACHE_KEY, {})
+ cache_enabled = cache.get(TREE_DELIVERED_CACHE_ENABLED, 0)
+
+ def getTreeDelivered(applied_rule):
+ for movement in applied_rule.objectValues():
+ if movement._isTreeDelivered():
+ return True
+ return False
+
+ rule_key = self.getRelativeUrl()
+ if cache_enabled:
+ try:
+ return cache[rule_key]
+ except:
+ result = getTreeDelivered(self)
+ cache[rule_key] = result
+ return result
+ else:
+ return getTreeDelivered(self)
+
Modified: erp5/trunk/products/ERP5/Document/DeliveryRule.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5/Document/DeliveryRule.py?rev=17756&r1=17755&r2=17756&view=diff
==============================================================================
--- erp5/trunk/products/ERP5/Document/DeliveryRule.py (original)
+++ erp5/trunk/products/ERP5/Document/DeliveryRule.py Thu Nov 22 18:47:28 2007
@@ -85,7 +85,7 @@
(delivery.getPortalDraftOrderStateList() + \
delivery.getPortalPlannedOrderStateList()):
movement_delivery = movement.getDeliveryValue()
- if not self._isTreeDelivered([movement], ignore_first=1) and \
+ if not movement._isTreeDelivered(ignore_first=1) and \
movement_delivery not in delivery_movement_list:
applied_rule._delObject(movement.getId())
else:
@@ -103,7 +103,7 @@
# We are on a line
new_id = deliv_mvt.getId()
else:
- # Weare on a cell
+ # We are on a cell
new_id = "%s_%s" % (deliv_mvt.getParentId(), deliv_mvt.getId())
# Generate the simulation deliv_mvt
# XXX Hardcoded value
Modified: erp5/trunk/products/ERP5/Document/OrderRule.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5/Document/OrderRule.py?rev=17756&r1=17755&r2=17756&view=diff
==============================================================================
--- erp5/trunk/products/ERP5/Document/OrderRule.py (original)
+++ erp5/trunk/products/ERP5/Document/OrderRule.py Thu Nov 22 18:47:28 2007
@@ -86,7 +86,7 @@
order.getPortalReservedInventoryStateList() and
not movement.getLastExpandSimulationState() in
order.getPortalCurrentInventoryStateList()) and \
- not self._isTreeDelivered([movement]):
+ not movement._isTreeDelivered():
movement_order = movement.getOrderValue()
if movement_order in order_movement_list:
Modified: erp5/trunk/products/ERP5/Document/Rule.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5/Document/Rule.py?rev=17756&r1=17755&r2=17756&view=diff
==============================================================================
--- erp5/trunk/products/ERP5/Document/Rule.py (original)
+++ erp5/trunk/products/ERP5/Document/Rule.py Thu Nov 22 18:47:28 2007
@@ -220,21 +220,6 @@
return 1
#### Helpers
- def _isTreeDelivered(self, movement_list, ignore_first=0):
- """
- returns 1 if the movement or any of its child is linked to a delivery
- """
- child_movement_list = []
- for movement in movement_list:
- if not ignore_first and len(movement.getDeliveryList()) > 0:
- return 1
- else:
- for applied_rule in movement.objectValues():
- child_movement_list = applied_rule.objectValues()
- if len(child_movement_list) == 0:
- return 0
- return self._isTreeDelivered(child_movement_list)
-
def _getCurrentMovementList(self, applied_rule, **kw):
"""
Returns the list of current children of the applied rule, sorted in 3
@@ -263,7 +248,7 @@
if movement.isFrozen():
immutable_movement_list.append(movement)
else:
- if self._isTreeDelivered([movement]):
+ if movement._isTreeDelivered():
mutable_movement_list.append(movement)
else:
deletable_movement_list.append(movement)
Modified: erp5/trunk/products/ERP5/Document/SimulationMovement.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5/Document/SimulationMovement.py?rev=17756&r1=17755&r2=17756&view=diff
==============================================================================
--- erp5/trunk/products/ERP5/Document/SimulationMovement.py (original)
+++ erp5/trunk/products/ERP5/Document/SimulationMovement.py Thu Nov 22 18:47:28 2007
@@ -31,12 +31,15 @@
from Products.CMFCore.utils import getToolByName
from Products.ERP5Type import Permissions, PropertySheet, Constraint, Interface
+from Products.ERP5Type.TransactionalVariable import getTransactionalVariable
from Products.ERP5.Document.Movement import Movement
from zLOG import LOG
from Acquisition import aq_base
+
+from AppliedRule import TREE_DELIVERED_CACHE_KEY, TREE_DELIVERED_CACHE_ENABLED
# XXX Do we need to create groups ? (ie. confirm group include confirmed, getting_ready and ready
@@ -209,36 +212,57 @@
security.declareProtected(Permissions.ModifyPortalContent, 'expand')
def expand(self, force=0, **kw):
"""
- Parses all existing applied rules and make sure they apply.
- Checks other possible rules and starts expansion process
- (instanciates rule and calls expand on rule)
-
- Only movements which applied rule parent is expanded can
- be expanded.
- """
- # XXX Default behaviour is not to expand if it has already been
- # expanded, but some rules are configuration rules and need to be
- # reexpanded each time, because the rule apply only if predicates
- # are true, then this kind of rule must always be tested. Currently,
- # 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().getSpecialiseReference() not in
- ('default_invoicing_rule', 'default_invoice_rule')
- and self.getCausalityState() == 'expanded' ) or \
- len(self.objectIds()) != 0):
- # Reexpand
- for my_applied_rule in self.objectValues():
- my_applied_rule.expand(force=force,**kw)
- else:
- portal_rules = getToolByName(self, 'portal_rules')
- # Parse each rule and test if it applies
- 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
- self.setCausalityState('expanded')
+ Checks all existing applied rules and make sure they still apply.
+ Checks for other possible rules and starts expansion process (instanciates
+ applied rules and calls expand on them).
+
+ First get all applicable rules,
+ then, delete all applied rules that no longer match and are not linked to
+ a delivery,
+ finally, apply new rules if no rule with the same type is already applied.
+ """
+ portal_rules = getToolByName(self, 'portal_rules')
+
+ tv = getTransactionalVariable(self)
+ cache = tv.setdefault(TREE_DELIVERED_CACHE_KEY, {})
+ cache_enabled = cache.get(TREE_DELIVERED_CACHE_ENABLED, 0)
+
+ # enable cache
+ if not cache_enabled:
+ cache[TREE_DELIVERED_CACHE_ENABLED] = 1
+
+ applied_rule_dict = {}
+ applicable_rule_dict = {}
+ for rule in portal_rules.searchRuleList(self, sort_on='version',
+ sort_order='descending'):
+ ref = rule.getReference()
+ if ref and ref not in applicable_rule_dict.iterkeys():
+ applicable_rule_dict[ref] = rule
+
+ for applied_rule in self.objectValues():
+ rule = applied_rule.getSpecialiseValue()
+ if not applied_rule._isTreeDelivered() and not rule.test(self):
+ self._delObject(applied_rule.getId())
+ else:
+ applied_rule_dict[rule.getPortalType()] = applied_rule
+
+ for rule in applicable_rule_dict.itervalues():
+ rule_type = rule.getPortalType()
+ if rule_type not in applied_rule_dict.iterkeys():
+ applied_rule = rule.constructNewAppliedRule(self, **kw)
+ applied_rule_dict[rule_type] = applied_rule
+
+ self.setCausalityState('expanded')
+ # expand
+ for applied_rule in applied_rule_dict.itervalues():
+ applied_rule.expand(force=force, **kw)
+
+ # disable and clear cache
+ if not cache_enabled:
+ try:
+ del tv[TREE_DELIVERED_CACHE_KEY]
+ except KeyError:
+ pass
security.declareProtected(Permissions.ModifyPortalContent, 'diverge')
def diverge(self):
@@ -480,3 +504,38 @@
# 'recursiveImmediateReindexObject']))
# activity.edit()
+ def _isTreeDelivered(self, ignore_first=0):
+ """
+ checks if subapplied rules of this movement (going down the complete
+ simulation tree) have a child with a delivery relation.
+ Returns True if at least one is delivered, False if none of them are.
+
+ see AppliedRule._isTreeDelivered
+ """
+ tv = getTransactionalVariable(self)
+ cache = tv.setdefault(TREE_DELIVERED_CACHE_KEY, {})
+ cache_enabled = cache.get(TREE_DELIVERED_CACHE_ENABLED, 0)
+
+ def getTreeDelivered(movement, ignore_first=0):
+ if ignore_first:
+ if len(movement.getDeliveryList()) > 0:
+ return True
+ for applied_rule in movement.objectValues():
+ if applied_rule._isTreeDelivered():
+ return True
+ return False
+
+ if ignore_first:
+ rule_key = (self.getRelativeUrl(), 1)
+ else:
+ rule_key = self.getRelativeUrl()
+ if cache_enabled:
+ try:
+ return cache[rule_key]
+ except:
+ result = getTreeDelivered(self, ignore_first=ignore_first)
+ cache[rule_key] = result
+ return result
+ else:
+ return getTreeDelivered(self, ignore_first=ignore_first)
+
More information about the Erp5-report
mailing list