[Erp5-report] r31336 kazuhiko - in /erp5/trunk/products/ERP5: Document/ mixin/
nobody at svn.erp5.org
nobody at svn.erp5.org
Wed Dec 16 15:22:02 CET 2009
Author: kazuhiko
Date: Wed Dec 16 15:21:59 2009
New Revision: 31336
URL: http://svn.erp5.org?rev=31336&view=rev
Log:
move IMovementCollectionUpdater implementation from RuleMixin to MovementCollectionUpdaterMixin.
Added:
erp5/trunk/products/ERP5/mixin/movement_collection_updater.py
Modified:
erp5/trunk/products/ERP5/Document/NewOrderRule.py
erp5/trunk/products/ERP5/mixin/rule.py
Modified: erp5/trunk/products/ERP5/Document/NewOrderRule.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5/Document/NewOrderRule.py?rev=31336&r1=31335&r2=31336&view=diff
==============================================================================
--- erp5/trunk/products/ERP5/Document/NewOrderRule.py [utf8] (original)
+++ erp5/trunk/products/ERP5/Document/NewOrderRule.py [utf8] Wed Dec 16 15:21:59 2009
@@ -34,9 +34,11 @@
from Products.ERP5Type import Permissions, PropertySheet, interfaces
from Products.ERP5.Document.Predicate import Predicate
from Products.ERP5.mixin.rule import RuleMixin
+from Products.ERP5.mixin.movement_collection_updater import \
+ MovementCollectionUpdaterMixin
from Products.ERP5.MovementCollectionDiff import _getPropertyAndCategoryList
-class NewOrderRule(RuleMixin, Predicate):
+class NewOrderRule(RuleMixin, MovementCollectionUpdaterMixin, Predicate):
"""
Order Rule object make sure an Order in the simulation
is consistent with the real order
Added: erp5/trunk/products/ERP5/mixin/movement_collection_updater.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5/mixin/movement_collection_updater.py?rev=31336&view=auto
==============================================================================
--- erp5/trunk/products/ERP5/mixin/movement_collection_updater.py (added)
+++ erp5/trunk/products/ERP5/mixin/movement_collection_updater.py [utf8] Wed Dec 16 15:21:59 2009
@@ -1,0 +1,171 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# Copyright (c) 2009 Nexedi SA and Contributors. All Rights Reserved.
+#
+# WARNING: This program as such is intended to be used by professional
+# programmers who take the whole responsibility of assessing all potential
+# consequences resulting from its eventual inadequacies and bugs
+# End users who are looking for a ready-to-use solution with commercial
+# guarantees and support are strongly adviced to contract a Free Software
+# Service Company
+#
+# This program is Free Software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+##############################################################################
+
+import zope.interface
+from AccessControl import ClassSecurityInfo
+from Products.ERP5Type import Permissions, interfaces
+from Products.ERP5.MovementCollectionDiff import MovementCollectionDiff
+from Products.ERP5.mixin.rule import _compare
+
+class MovementCollectionUpdaterMixin:
+ """Movement Collection Updater interface specification
+
+ Documents which implement IMovementCollectionUpdater
+ usually invoke an IMovementGenerator to generate
+ an IMovementList and compare it to another IMovementList
+ obtained from an IMovementCollection, thus generating
+ an IMovementCollectionDiff.
+ """
+
+ # Declarative security
+ security = ClassSecurityInfo()
+ security.declareObjectProtected(Permissions.AccessContentsInformation)
+
+ # Declarative interfaces
+ zope.interface.implements(interfaces.IMovementCollectionUpdater,)
+
+ # Implementation of IMovementCollectionUpdater
+ def getMovementCollectionDiff(self, context, rounding=False,
+ movement_generator=None):
+ """
+ Return a IMovementCollectionDiff by comparing movements
+ the list of movements of context and the list of movements
+ generated by movement_generator on context.
+
+ context -- an IMovementCollection usually, possibly
+ an IMovementList or an IMovement
+
+ movement_generator -- an optional IMovementGenerator
+ (if not specified, a context implicit
+ IMovementGenerator will be used)
+ """
+ # We suppose here that we have an IMovementCollection in hand
+ decision_movement_list = context.getMovementList()
+ prevision_movement_list = movement_generator.getAggregatedMovementList(
+ self._getMovementGeneratorContext(context),
+ movement_list=self._getMovementGeneratorMovementList(), rounding=rounding)
+
+ # Get divergence testers
+ tester_list = self._getMatchingTesterList()
+ if len(tester_list) == 0:
+ raise ValueError("It is not possible to match movements without divergence testers")
+
+ # Create small groups of movements per hash keys
+ decision_movement_dict = {}
+ for movement in decision_movement_list:
+ tester_key = []
+ for tester in tester_list:
+ if tester.test(movement):
+ tester_key.append(tester.generateHashKey(movement))
+ else:
+ tester_key.append(None)
+ tester_key = tuple(tester_key)
+ decision_movement_dict.setdefault(tester_key, []).append(movement)
+ prevision_movement_dict = {}
+ for movement in prevision_movement_list:
+ tester_key = []
+ for tester in tester_list:
+ if tester.test(movement):
+ tester_key.append(tester.generateHashKey(movement))
+ else:
+ tester_key.append(None)
+ tester_key = tuple(tester_key)
+ prevision_movement_dict.setdefault(tester_key, []).append(movement)
+
+ # Prepare a mapping between prevision and decision
+ # The prevision_to_decision_map is a list of tuples
+ # of the form (prevision_movement_dict, list of decision_movement)
+ prevision_to_decision_map = []
+
+ # First find out all existing (decision) movements which belong to no group
+ no_group_list = []
+ for tester_key in decision_movement_dict.keys():
+ if prevision_movement_dict.has_key(tester_key):
+ for decision_movement in decision_movement_dict[tester_key]:
+ no_match = True
+ for prevision_movement in prevision_movement_dict[tester_key]:
+ # Check if this movement belongs to an existing group
+ if _compare(tester_list, prevision_movement, decision_movement):
+ no_match = False
+ break
+ if no_match:
+ # There is no matching.
+ # So, let us add the decision movements to no_group_list
+ no_group_list.append(decision_movement)
+ else:
+ # The tester key does not even exist.
+ # So, let us add all decision movements to no_group_list
+ no_group_list.extend(decision_movement_dict[tester_key])
+ if len(no_group_list) > 0:
+ prevision_to_decision_map.append((None, no_group_list))
+
+ # Second, let us create small groups of movements
+ for tester_key in prevision_movement_dict.keys():
+ for prevision_movement in prevision_movement_dict[tester_key]:
+ map_list = []
+ for decision_movement in decision_movement_dict.get(tester_key, ()):
+ if _compare(tester_list, prevision_movement, decision_movement):
+ # XXX is it OK to have more than 2 decision_movements? # XXX-JPS - I think yes
+ map_list.append(decision_movement)
+ prevision_to_decision_map.append((prevision_movement, map_list))
+
+ # Third, time to create the diff
+ movement_collection_diff = MovementCollectionDiff()
+ for (prevision_movement, decision_movement_list) in prevision_to_decision_map:
+ self._extendMovementCollectionDiff(movement_collection_diff, prevision_movement,
+ decision_movement_list)
+
+ # Return result
+ return movement_collection_diff
+
+ def updateMovementCollection(self, context, rounding=False,
+ movement_generator=None):
+ """
+ Invoke getMovementCollectionDiff and update context with
+ the resulting IMovementCollectionDiff.
+
+ context -- an IMovementCollection usually, possibly
+ an IMovementList or an IMovement
+
+ movement_generator -- an optional IMovementGenerator
+ (if not specified, a context implicit
+ IMovementGenerator will be used)
+ """
+ movement_diff = self.getMovementCollectionDiff(context,
+ rounding=rounding, movement_generator=movement_generator)
+
+ # Apply Diff
+ for movement in movement_diff.getDeletableMovementList():
+ movement.getParentValue().deleteContent(movement.getId())
+ for movement in movement_diff.getUpdatableMovementList():
+ kw = movement_diff.getMovementPropertyDict(movement)
+ movement.edit(**kw)
+ for movement in movement_diff.getNewMovementList():
+ # This case is easy, because it is an applied rule
+ kw = movement_diff.getMovementPropertyDict(movement)
+ movement = context.newContent(portal_type=self.movement_type, **kw)
Modified: erp5/trunk/products/ERP5/mixin/rule.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5/mixin/rule.py?rev=31336&r1=31335&r2=31336&view=diff
==============================================================================
--- erp5/trunk/products/ERP5/mixin/rule.py [utf8] (original)
+++ erp5/trunk/products/ERP5/mixin/rule.py [utf8] Wed Dec 16 15:21:59 2009
@@ -31,7 +31,6 @@
from Acquisition import aq_base
from Products.CMFCore.utils import getToolByName
from Products.ERP5Type import Permissions, interfaces
-from Products.ERP5.MovementCollectionDiff import MovementCollectionDiff
def _compare(tester_list, prevision_movement, decision_movement):
for tester in tester_list:
@@ -150,125 +149,6 @@
elif result is not None:
result_list.append(result)
return result_list
-
- # Implementation of IMovementCollectionUpdater
- def getMovementCollectionDiff(self, context, rounding=False, movement_generator=None):
- """
- Return a IMovementCollectionDiff by comparing movements
- the list of movements of context and the list of movements
- generated by movement_generator on context.
-
- context -- an IMovementCollection usually, possibly
- an IMovementList or an IMovement
-
- movement_generator -- an optional IMovementGenerator
- (if not specified, a context implicit
- IMovementGenerator will be used)
- """
- # We suppose here that we have an IMovementCollection in hand
- decision_movement_list = context.getMovementList()
- prevision_movement_list = movement_generator.getAggregatedMovementList(
- self._getMovementGeneratorContext(context),
- movement_list=self._getMovementGeneratorMovementList(), rounding=rounding)
-
- # Get divergence testers
- tester_list = self._getMatchingTesterList()
- if len(tester_list) == 0:
- raise ValueError("It is not possible to match movements without divergence testers")
-
- # Create small groups of movements per hash keys
- decision_movement_dict = {}
- for movement in decision_movement_list:
- tester_key = []
- for tester in tester_list:
- if tester.test(movement):
- tester_key.append(tester.generateHashKey(movement))
- else:
- tester_key.append(None)
- tester_key = tuple(tester_key)
- decision_movement_dict.setdefault(tester_key, []).append(movement)
- prevision_movement_dict = {}
- for movement in prevision_movement_list:
- tester_key = []
- for tester in tester_list:
- if tester.test(movement):
- tester_key.append(tester.generateHashKey(movement))
- else:
- tester_key.append(None)
- tester_key = tuple(tester_key)
- prevision_movement_dict.setdefault(tester_key, []).append(movement)
-
- # Prepare a mapping between prevision and decision
- # The prevision_to_decision_map is a list of tuples
- # of the form (prevision_movement_dict, list of decision_movement)
- prevision_to_decision_map = []
-
- # First find out all existing (decision) movements which belong to no group
- no_group_list = []
- for tester_key in decision_movement_dict.keys():
- if prevision_movement_dict.has_key(tester_key):
- for decision_movement in decision_movement_dict[tester_key]:
- no_match = True
- for prevision_movement in prevision_movement_dict[tester_key]:
- # Check if this movement belongs to an existing group
- if _compare(tester_list, prevision_movement, decision_movement):
- no_match = False
- break
- if no_match:
- # There is no matching.
- # So, let us add the decision movements to no_group_list
- no_group_list.append(decision_movement)
- else:
- # The tester key does not even exist.
- # So, let us add all decision movements to no_group_list
- no_group_list.extend(decision_movement_dict[tester_key])
- if len(no_group_list) > 0:
- prevision_to_decision_map.append((None, no_group_list))
-
- # Second, let us create small groups of movements
- for tester_key in prevision_movement_dict.keys():
- for prevision_movement in prevision_movement_dict[tester_key]:
- map_list = []
- for decision_movement in decision_movement_dict.get(tester_key, ()):
- if _compare(tester_list, prevision_movement, decision_movement):
- # XXX is it OK to have more than 2 decision_movements? # XXX-JPS - I think yes
- map_list.append(decision_movement)
- prevision_to_decision_map.append((prevision_movement, map_list))
-
- # Third, time to create the diff
- movement_collection_diff = MovementCollectionDiff()
- for (prevision_movement, decision_movement_list) in prevision_to_decision_map:
- self._extendMovementCollectionDiff(movement_collection_diff, prevision_movement,
- decision_movement_list)
-
- # Return result
- return movement_collection_diff
-
- def updateMovementCollection(self, context, rounding=False, movement_generator=None):
- """
- Invoke getMovementCollectionDiff and update context with
- the resulting IMovementCollectionDiff.
-
- context -- an IMovementCollection usually, possibly
- an IMovementList or an IMovement
-
- movement_generator -- an optional IMovementGenerator
- (if not specified, a context implicit
- IMovementGenerator will be used)
- """
- movement_diff = self.getMovementCollectionDiff(context,
- rounding=rounding, movement_generator=movement_generator)
-
- # Apply Diff
- for movement in movement_diff.getDeletableMovementList():
- movement.getParentValue().deleteContent(movement.getId())
- for movement in movement_diff.getUpdatableMovementList():
- kw = movement_diff.getMovementPropertyDict(movement)
- movement.edit(**kw)
- for movement in movement_diff.getNewMovementList():
- # This case is easy, because it is an applied rule
- kw = movement_diff.getMovementPropertyDict(movement)
- movement = context.newContent(portal_type=self.movement_type, **kw)
# Placeholder for methods to override
def _getMovementGenerator(self):
More information about the Erp5-report
mailing list