[Erp5-report] r34217 jm - in /erp5/trunk: bt5/erp5_payroll/SkinTemplateItem/portal_skins/er...
nobody at svn.erp5.org
nobody at svn.erp5.org
Tue Mar 30 18:57:20 CEST 2010
Author: jm
Date: Tue Mar 30 18:57:17 2010
New Revision: 34217
URL: http://svn.erp5.org?rev=34217&view=rev
Log:
Delivery: add support for composition
CompositionMixin provides a 'asComposedDocument' method replacing
find{Effective,}SpecialiseValueList on Trade Condition.
Some deprecated code in TradeCondition is moved back to PaySheetModel for
compatibility reasons.
Added:
erp5/trunk/products/ERP5/mixin/composition.py
Modified:
erp5/trunk/bt5/erp5_payroll/SkinTemplateItem/portal_skins/erp5_payroll/PaySheetTransaction_applyModel.xml
erp5/trunk/bt5/erp5_payroll/SkinTemplateItem/portal_skins/erp5_payroll/PaySheetTransaction_getODTDataDict.xml
erp5/trunk/bt5/erp5_payroll/bt/revision
erp5/trunk/products/ERP5/Document/Delivery.py
erp5/trunk/products/ERP5/Document/PaySheetModel.py
erp5/trunk/products/ERP5/Document/PaySheetTransaction.py
erp5/trunk/products/ERP5/Document/TradeCondition.py
erp5/trunk/products/ERP5/Document/TradeModelLine.py
erp5/trunk/products/ERP5/tests/testPayroll.py
erp5/trunk/products/ERP5/tests/testTradeModelLine.py
Modified: erp5/trunk/bt5/erp5_payroll/SkinTemplateItem/portal_skins/erp5_payroll/PaySheetTransaction_applyModel.xml
URL: http://svn.erp5.org/erp5/trunk/bt5/erp5_payroll/SkinTemplateItem/portal_skins/erp5_payroll/PaySheetTransaction_applyModel.xml?rev=34217&r1=34216&r2=34217&view=diff
==============================================================================
--- erp5/trunk/bt5/erp5_payroll/SkinTemplateItem/portal_skins/erp5_payroll/PaySheetTransaction_applyModel.xml [utf8] (original)
+++ erp5/trunk/bt5/erp5_payroll/SkinTemplateItem/portal_skins/erp5_payroll/PaySheetTransaction_applyModel.xml [utf8] Tue Mar 30 18:57:17 2010
@@ -87,9 +87,7 @@
\n
def copyPaymentCondition(paysheet, model):\n
filter_dict = {\'portal_type\': \'Payment Condition\'}\n
- effective_model_list = model.findEffectiveSpecialiseValueList(\\\n
- context=model,\n
- start_date=paysheet.getStartDate(), stop_date=paysheet.getStopDate())\n
+ effective_model_list = model.findEffectiveSpecialiseValueList(paysheet)\n
for effective_model in effective_model_list:\n
to_copy = effective_model.contentIds(filter=filter_dict)\n
if len(to_copy) > 0 :\n
Modified: erp5/trunk/bt5/erp5_payroll/SkinTemplateItem/portal_skins/erp5_payroll/PaySheetTransaction_getODTDataDict.xml
URL: http://svn.erp5.org/erp5/trunk/bt5/erp5_payroll/SkinTemplateItem/portal_skins/erp5_payroll/PaySheetTransaction_getODTDataDict.xml?rev=34217&r1=34216&r2=34217&view=diff
==============================================================================
--- erp5/trunk/bt5/erp5_payroll/SkinTemplateItem/portal_skins/erp5_payroll/PaySheetTransaction_getODTDataDict.xml [utf8] (original)
+++ erp5/trunk/bt5/erp5_payroll/SkinTemplateItem/portal_skins/erp5_payroll/PaySheetTransaction_getODTDataDict.xml [utf8] Tue Mar 30 18:57:17 2010
@@ -153,7 +153,7 @@
def getSocialOrganisationValue():\n
model = context.getSpecialiseValue()\n
if model is not None:\n
- business_process_list = model.findSpecialiseValueList(\\\n
+ business_process_list = model.findEffectiveSpecialiseValueList(\\\n
context=context, portal_type_list=[\'Business Process\'])\n
business_process = None\n
if len(business_process_list):\n
Modified: erp5/trunk/bt5/erp5_payroll/bt/revision
URL: http://svn.erp5.org/erp5/trunk/bt5/erp5_payroll/bt/revision?rev=34217&r1=34216&r2=34217&view=diff
==============================================================================
--- erp5/trunk/bt5/erp5_payroll/bt/revision [utf8] (original)
+++ erp5/trunk/bt5/erp5_payroll/bt/revision [utf8] Tue Mar 30 18:57:17 2010
@@ -1,1 +1,1 @@
-559
+560
Modified: erp5/trunk/products/ERP5/Document/Delivery.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5/Document/Delivery.py?rev=34217&r1=34216&r2=34217&view=diff
==============================================================================
--- erp5/trunk/products/ERP5/Document/Delivery.py [utf8] (original)
+++ erp5/trunk/products/ERP5/Document/Delivery.py [utf8] Tue Mar 30 18:57:17 2010
@@ -36,11 +36,12 @@
from Products.ERP5Type.Accessor.Constant import PropertyGetter as ConstantGetter
from Products.ERP5Type.XMLObject import XMLObject
from Products.ERP5.Document.ImmobilisationDelivery import ImmobilisationDelivery
+from Products.ERP5.mixin.composition import CompositionMixin
from Products.ERP5Type.UnrestrictedMethod import UnrestrictedMethod
from zLOG import LOG, PROBLEM
-class Delivery(XMLObject, ImmobilisationDelivery):
+class Delivery(XMLObject, ImmobilisationDelivery, CompositionMixin):
"""
Each time delivery is modified, it MUST launch a reindexing of
inventories which are related to the resources contained in the Delivery
Modified: erp5/trunk/products/ERP5/Document/PaySheetModel.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5/Document/PaySheetModel.py?rev=34217&r1=34216&r2=34217&view=diff
==============================================================================
--- erp5/trunk/products/ERP5/Document/PaySheetModel.py [utf8] (original)
+++ erp5/trunk/products/ERP5/Document/PaySheetModel.py [utf8] Tue Mar 30 18:57:17 2010
@@ -30,8 +30,10 @@
from Products.ERP5Type import Permissions, PropertySheet
from Products.ERP5.Document.TradeCondition import TradeCondition
+from Products.ERP5Type.XMLMatrix import XMLMatrix
+from Products.ERP5.Document.PaySheetTransaction import PaySheetTransaction
-class PaySheetModel(TradeCondition):
+class PaySheetModel(TradeCondition, XMLMatrix):
"""A PaySheetModel defines calculation rules for paysheets.
PaySheetModel are used to define calculating rules specific to a
@@ -64,3 +66,74 @@
, PropertySheet.DefaultAnnotationLine
)
+ security.declareProtected( Permissions.AccessContentsInformation, 'getCell')
+ def getCell(self, *args, **kw):
+ '''Overload the function getCell to be able to search a cell on the
+ inheritance model tree if the cell is not found on current one.
+ '''
+ paysheet = kw.get('paysheet')
+ if paysheet is None:
+ from Products.ERP5Type.Document import newTempPaySheetTransaction
+ paysheet = newTempPaySheetTransaction(self.getPortalObject(), '',
+ specialise_value=self)
+ model_list = self.findEffectiveSpecialiseValueList(paysheet)
+ for specialised_model in model_list:
+ cell = XMLMatrix.getCell(specialised_model, *args, **kw)
+ if cell is not None:
+ return cell
+
+ security.declareProtected(Permissions.AccessContentsInformation,
+ 'getReferenceDict')
+ def getReferenceDict(self, portal_type_list, property_list=None):
+ """Return a dict containing all id's of the objects contained in
+ this model and corresponding to the given portal_type. The key of the dict
+ are the reference (or id if no reference)
+ """
+ if property_list is None:
+ property_list=[]
+ reference_dict = {}
+ object_list = self.contentValues(portal_type=portal_type_list,
+ sort_on='id')
+ for obj in object_list:
+ keep = (len(property_list) == 0)
+ for property_ in property_list:
+ if obj.hasProperty(property_):
+ keep = 1
+ break
+ if keep:
+ reference_dict[obj.getProperty('reference', obj.getId())] = obj.getId()
+ return reference_dict
+
+ security.declareProtected(Permissions.AccessContentsInformation,
+ 'getInheritanceReferenceDict')
+ def getInheritanceReferenceDict(self, context, portal_type_list,
+ property_list=None):
+ '''Returns a dict with the model url as key and a list of reference as
+ value. A Reference can appear only one time in the final output.
+ If property_list is not empty, documents which don't have any of theses
+ properties will be skipped.
+ '''
+ reference_list = []
+ model_reference_dict = {}
+ for model in self.findEffectiveSpecialiseValueList(context):
+ id_list = []
+ model_reference_list = model.getReferenceDict(
+ portal_type_list, property_list=property_list)
+ for reference in model_reference_list.keys():
+ if reference not in reference_list:
+ reference_list.append(reference)
+ id_list.append(model_reference_list[reference])
+ if len(id_list) != 0:
+ model_reference_dict[model.getRelativeUrl()]=id_list
+ return model_reference_dict
+
+ security.declareProtected(Permissions.AccessContentsInformation,
+ 'getModelInheritanceEffectiveProperty')
+ def getModelInheritanceEffectiveProperty(self, paysheet, property_name):
+ """Get a property from an effective model
+ """
+ model_list = self.findEffectiveSpecialiseValueList(paysheet)
+ for specialised_model in model_list:
+ v = specialised_model.getProperty(property_name)
+ if v:
+ return v
Modified: erp5/trunk/products/ERP5/Document/PaySheetTransaction.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5/Document/PaySheetTransaction.py?rev=34217&r1=34216&r2=34217&view=diff
==============================================================================
--- erp5/trunk/products/ERP5/Document/PaySheetTransaction.py [utf8] (original)
+++ erp5/trunk/products/ERP5/Document/PaySheetTransaction.py [utf8] Tue Mar 30 18:57:17 2010
@@ -32,7 +32,6 @@
from Products.ERP5.Document.Invoice import Invoice
#XXX TODO: review naming of new methods
-#XXX WARNING: current API naming may change although model should be stable.
class PaySheetTransaction(Invoice):
"""
@@ -135,13 +134,11 @@
If property_list is provided, only subobjects with at least one of those
properties will be taken into account
'''
- model = self.getSpecialiseValue().getEffectiveModel(\
- start_date=self.getStartDate(),
- stop_date=self.getStopDate())
+ model = self.getSpecialiseValue()
sub_object_list = []
if model is not None:
# if there is an effective model
- model_reference_dict = model.getInheritanceReferenceDict(
+ model_reference_dict = model.getInheritanceReferenceDict(self,
portal_type_list=portal_type_list,
property_list=property_list)
traverse = self.getPortalObject().unrestrictedTraverse
@@ -166,9 +163,8 @@
if len(parent.contentValues(portal_type='Pay Sheet Cell')) == 0:
# the line contain no movements, remove it
self.manage_delObjects(parent.getId())
- business_process_list = paysheet_model.findSpecialiseValueList(\
- context=paysheet_model,
- portal_type_list=['Business Process'])
+ business_process_list = paysheet_model.findEffectiveSpecialiseValueList(
+ self, portal_type_list=['Business Process'])
if len(business_process_list):
# XXX currently, we consider that is to complicated to use more than one
# Business Process, so we take the first (wich is the nearest from
Modified: erp5/trunk/products/ERP5/Document/TradeCondition.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5/Document/TradeCondition.py?rev=34217&r1=34216&r2=34217&view=diff
==============================================================================
--- erp5/trunk/products/ERP5/Document/TradeCondition.py [utf8] (original)
+++ erp5/trunk/products/ERP5/Document/TradeCondition.py [utf8] Tue Mar 30 18:57:17 2010
@@ -34,10 +34,10 @@
from AccessControl import ClassSecurityInfo
from Products.ERP5Type import Permissions, PropertySheet, interfaces
+from Products.ERP5.mixin.composition import _getEffectiveModel
from Products.ERP5.Document.Transformation import Transformation
from Products.ERP5.Document.Path import Path
from Products.ERP5.AggregatedAmountList import AggregatedAmountList
-from Products.ERP5Type.XMLMatrix import XMLMatrix
from Products.ZSQLCatalog.SQLCatalog import Query, ComplexQuery
import zope.interface
@@ -47,7 +47,7 @@
# XXX TODO: review naming of new methods
# XXX WARNING: current API naming may change although model should be stable.
-class TradeCondition(Path, Transformation, XMLMatrix):
+class TradeCondition(Path, Transformation):
"""
Trade Conditions are used to store the conditions (payment, logistic,...)
which should be applied (and used in the orders) when two companies make
@@ -121,18 +121,8 @@
'movement_to_add_list': movement_to_add_list}
security.declareProtected(Permissions.AccessContentsInformation,
- 'findSpecialiseValueList')
- def findSpecialiseValueList(self, context, portal_type_list=None):
- """Returns a list of specialised objects representing inheritance tree.
- """
- return self.findEffectiveSpecialiseValueList(context,
- portal_type_list=portal_type_list)
-
-
- security.declareProtected(Permissions.AccessContentsInformation,
'findEffectiveSpecialiseValueList')
- def findEffectiveSpecialiseValueList(self, context, start_date=None,
- stop_date=None, portal_type_list=None):
+ def findEffectiveSpecialiseValueList(self, context, portal_type_list=None):
"""Return a list of effective specialised objects that is the
inheritance tree.
An effective object is an object which have start_date and stop_date
@@ -142,30 +132,13 @@
"""
portal_type_set = set(portal_type_list or
self.getPortalAmountGeneratorTypeList())
- def getEffectiveModel(model):
- try:
- getEffectiveModel = model.getEffectiveModel
- except AttributeError:
- return model
- return getEffectiveModel(start_date, stop_date)
- filtered_list = []
- specialise_value_list = deque((getEffectiveModel(context),))
- specialise_value_set = set(specialise_value_list)
- specialise_index = 0
- while specialise_value_list:
- context = specialise_value_list.popleft()
- if context.getPortalType() in portal_type_set:
- filtered_list.append(context)
- for specialise_value in map(getEffectiveModel,
- context.getSpecialiseValueList()):
- if specialise_value not in specialise_value_set:
- specialise_value_set.add(specialise_value)
- specialise_value_list.append(specialise_value)
- return filtered_list
+ return [x for x in context._findEffectiveSpecialiseValueList()
+ if x.getPortalType() in portal_type_set]
security.declareProtected(Permissions.AccessContentsInformation,
'getTradeModelLineComposedList')
- def getTradeModelLineComposedList(self, context=None, portal_type_list=None):
+ def getTradeModelLineComposedList(self, context=None,
+ portal_type_list=None):
"""Returns list of Trade Model Lines using composition.
Reference of Trade Model Line is used to hide other Trade Model Line
@@ -176,32 +149,12 @@
"""
if portal_type_list is None:
portal_type_list = self.model_line_portal_type_list
-
- reference_list = []
- trade_model_line_composed_list = []
- containing_object_list = []
- start_date = None
- stop_date = None
- if context is not None:
- document = context
- if getattr(context, 'getExplanationValue', None) is not None:
- # if context is movement it is needed to ask its explanation
- # for contained Trade Model Lines
- document = context.getExplanationValue()
- containing_object_list.append(document)
- start_date = document.getStartDate()
- stop_date = document.getStopDate()
- containing_object_list.extend(\
- self.findEffectiveSpecialiseValueList(context=self,
- start_date=start_date, stop_date=stop_date))
-
- for specialise in containing_object_list:
- for trade_model_line in specialise.contentValues(
- portal_type=portal_type_list):
- reference = trade_model_line.getReference()
- if reference not in reference_list or reference is None:
- reference_list.append(reference)
- trade_model_line_composed_list.append(trade_model_line)
+ try:
+ context = context.getExplanationValue()
+ except AttributeError:
+ pass
+ trade_model_line_composed_list = \
+ context.asComposedDocument().contentValues(portal_type=portal_type_list)
# build a graph of precedences
# B---\
@@ -296,116 +249,8 @@
return aggregated_amount_list
- security.declareProtected( Permissions.AccessContentsInformation, 'getCell')
- def getCell(self, *kw , **kwd):
- '''Overload the function getCell to be able to search a cell on the
- inheritance model tree if the cell is not found on current one.
- '''
- cell = XMLMatrix.getCell(self, *kw, **kwd)
- if cell is None:
- # if cell not found, look on the inherited models
- start_date = kwd.has_key('paysheet') and \
- kwd['paysheet'].getStartDate() or None
- stop_date = kwd.has_key('paysheet') and \
- kwd['paysheet'].getStopDate() or None
- model_list = self.findEffectiveSpecialiseValueList(\
- context=self, start_date=start_date, stop_date=stop_date)
- for specialised_model in model_list:
- cell = XMLMatrix.getCell(specialised_model, *kw, **kwd)
- if cell is not None:
- return cell
- return cell
-
- security.declareProtected(Permissions.AccessContentsInformation,
- 'getReferenceDict')
- def getReferenceDict(self, portal_type_list, property_list=None):
- """Return a dict containing all id's of the objects contained in
- this model and corresponding to the given portal_type. The key of the dict
- are the reference (or id if no reference)
- """
- if property_list is None:
- property_list=[]
- reference_dict = {}
- object_list = self.contentValues(portal_type=portal_type_list,
- sort_on='id')
- for obj in object_list:
- keep = (len(property_list) == 0)
- for property_ in property_list:
- if obj.hasProperty(property_):
- keep = 1
- break
- if keep:
- reference_dict[obj.getProperty('reference', obj.getId())] = obj.getId()
- return reference_dict
-
- security.declareProtected(Permissions.AccessContentsInformation,
- 'getInheritanceReferenceDict')
- def getInheritanceReferenceDict(self, portal_type_list,
- property_list=None):
- '''Returns a dict with the model url as key and a list of reference as
- value. A Reference can appear only one time in the final output.
- If property_list is not empty, documents which don't have any of theses
- properties will be skipped.
- '''
- if property_list is None:
- property_list=[]
- model_list = self.findSpecialiseValueList(context=self)
- reference_list = []
- model_reference_dict = {}
- for model in model_list:
- id_list = []
- model_reference_list = model.getReferenceDict(
- portal_type_list, property_list=property_list)
- for reference in model_reference_list.keys():
- if reference not in reference_list:
- reference_list.append(reference)
- id_list.append(model_reference_list[reference])
- if len(id_list) != 0:
- model_reference_dict[model.getRelativeUrl()]=id_list
- return model_reference_dict
-
security.declareProtected(Permissions.AccessContentsInformation,
'getEffectiveModel')
def getEffectiveModel(self, start_date=None, stop_date=None):
- '''Return the more appropriate model using effective_date, expiration_date
- and version number.
- An effective model is a model which start and stop_date are equal (or
- excluded) to the range of the given start and stop_date and with the
- higher version number (if there is more than one)
- '''
- reference = self.getReference()
- if not reference or (start_date is None and stop_date is None):
- return self
-
- return self.getPortalObject().portal_catalog.unrestrictedGetResultValue(
- query=ComplexQuery(
- ComplexQuery(
- Query(effective_date=None),
- Query(effective_date=start_date,
- range='ngt'),
- logical_operator='OR'),
- ComplexQuery(
- Query(expiration_date=None),
- Query(expiration_date=stop_date,
- range='min'),
- logical_operator='OR'),
- Query(reference=reference),
- Query(validation_state=(
- 'deleted', 'invalidated'),
- operator='NOT'),
- Query(portal_type=self.getPortalType()),
- logical_operator='AND'),
- sort_on=(('version','descending'),))
-
-
- security.declareProtected(Permissions.AccessContentsInformation,
- 'getModelInheritanceEffectiveProperty')
- def getModelInheritanceEffectiveProperty(self, paysheet, property_name):
- """Get a property from an effective model
- """
- model_list = self.findEffectiveSpecialiseValueList(context=self,
- start_date=paysheet.getStartDate(), stop_date=paysheet.getStopDate())
- for specialised_model in model_list:
- v = specialised_model.getProperty(property_name)
- if v:
- return v
+ return _getEffectiveModel(self, start_date, stop_date)
+
Modified: erp5/trunk/products/ERP5/Document/TradeModelLine.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5/Document/TradeModelLine.py?rev=34217&r1=34216&r2=34217&view=diff
==============================================================================
--- erp5/trunk/products/ERP5/Document/TradeModelLine.py [utf8] (original)
+++ erp5/trunk/products/ERP5/Document/TradeModelLine.py [utf8] Tue Mar 30 18:57:17 2010
@@ -196,12 +196,12 @@
update = 1
else:
# get source and destination using Business Process
- if getattr(document, 'findSpecialiseValueList', None) is None:
+ if getattr(document, 'findEffectiveSpecialiseValueList', None) is None:
# if parent don't have findSpecialiseValueList, this mean it's on the
# specialise_value
document = self.getParentValue().getSpecialiseValue()
try:
- business_process_list = document.findSpecialiseValueList(
+ business_process_list = document.findEffectiveSpecialiseValueList(
context=context, portal_type_list=['Business Process'])
except AttributeError:
business_process_list = []
Added: erp5/trunk/products/ERP5/mixin/composition.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5/mixin/composition.py?rev=34217&view=auto
==============================================================================
--- erp5/trunk/products/ERP5/mixin/composition.py (added)
+++ erp5/trunk/products/ERP5/mixin/composition.py [utf8] Tue Mar 30 18:57:17 2010
@@ -1,0 +1,126 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# Copyright (c) 2010 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.
+#
+##############################################################################
+
+from AccessControl import ClassSecurityInfo
+from Acquisition import aq_base
+from Products.ERP5Type import Permissions
+from Products.ERP5.Document.Predicate import Predicate
+from Products.ZSQLCatalog.SQLCatalog import Query, ComplexQuery
+
+def _getEffectiveModel(self, start_date=None, stop_date=None):
+ """Return the most appropriate model using effective_date, expiration_date
+ and version number.
+ An effective model is a model which start and stop_date are equal (or
+ excluded) to the range of the given start and stop_date and with the
+ higher version number (if there is more than one)
+
+ XXX Should we moved this function to a class ? Which one ?
+ What about reusing IVersionable ?
+ """
+ reference = self.getReference()
+ if not reference:
+ return self
+
+ query_list = [Query(reference=reference),
+ Query(portal_type=self.getPortalType()),
+ Query(validation_state=('deleted', 'invalidated'),
+ operator='NOT')]
+ if start_date is not None:
+ query_list.append(ComplexQuery(Query(effective_date=None),
+ Query(effective_date=start_date,
+ range='ngt'),
+ logical_operator='OR'))
+ if stop_date is not None:
+ query_list.append(ComplexQuery(Query(expiration_date=None),
+ Query(expiration_date=stop_date,
+ range='min'),
+ logical_operator='OR'))
+
+ # XXX What to do the catalog returns nothing (either because 'self' was just
+ # created and not yet indexed, or because it was invalidated) ?
+ # For the moment, we raise.
+ model_list = self.getPortalObject().portal_catalog.unrestrictedSearchResults(
+ query=ComplexQuery(logical_operator='AND', *query_list),
+ sort_on=(('version', 'descending'),))
+ return model_list[0].getObject()
+
+class CompositionMixin:
+ """
+ """
+
+ # Declarative security
+ security = ClassSecurityInfo()
+ security.declareObjectProtected(Permissions.AccessContentsInformation)
+
+ security.declareProtected(Permissions.AccessContentsInformation,
+ 'asComposedDocument')
+ def asComposedDocument(self):
+ container_list = self._findEffectiveSpecialiseValueList()
+ self = self.asContext()
+ self._initBTrees()
+ reference_dict = {}
+ line_count = 0
+ for container in container_list:
+ for ob in container.contentValues():
+ if isinstance(ob, Predicate):
+ # reference is used to hide lines on farther containers
+ reference = ob.getProperty('reference')
+ if reference:
+ reference_set = reference_dict.setdefault(ob.getPortalType(), set())
+ if reference in reference_set:
+ continue
+ reference_set.add(reference)
+ id = str(line_count)
+ line_count += 1
+ self._setOb(id, aq_base(ob.asContext(id=id)))
+ return self
+
+ def _findEffectiveSpecialiseValueList(self):
+ """Return a list of effective specialised objects that is the
+ inheritance tree.
+ An effective object is an object which have start_date and stop_date
+ included to the range of the given parameters start_date and stop_date.
+
+ This algorithm uses Breadth First Search.
+ """
+ start_date = self.getStartDate()
+ stop_date = self.getStopDate()
+ def getEffectiveModel(model):
+ return _getEffectiveModel(model, start_date, stop_date)
+ model_list = [self]
+ model_set = set(model_list)
+ model_index = 0
+ while model_index < len(model_list):
+ model = model_list[model_index]
+ model_index += 1
+ for model in map(getEffectiveModel, model.getSpecialiseValueList()):
+ if model not in model_set:
+ model_set.add(model)
+ if 1: #model.test(self):
+ model_list.append(model)
+ return model_list
Modified: erp5/trunk/products/ERP5/tests/testPayroll.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5/tests/testPayroll.py?rev=34217&r1=34216&r2=34217&view=diff
==============================================================================
--- erp5/trunk/products/ERP5/tests/testPayroll.py [utf8] (original)
+++ erp5/trunk/products/ERP5/tests/testPayroll.py [utf8] Tue Mar 30 18:57:17 2010
@@ -1371,14 +1371,17 @@
quantity=4)
def stepCheckInheritanceModelReferenceDict(self, sequence=None, **kw):
+ paysheet = self.createPaysheet()
model_employee = sequence.get('model_employee')
+ paysheet.setSpecialiseValue(model_employee)
+
model_employee_url = model_employee.getRelativeUrl()
model_company_url = sequence.get('model_company').getRelativeUrl()
model_company_alt_url = sequence.get('model_company_alt').getRelativeUrl()
model_country_url = sequence.get('model_country').getRelativeUrl()
-
- model_reference_dict = model_employee.getInheritanceReferenceDict(\
- portal_type_list=('Annotation Line',))
+
+ model_reference_dict = model_employee.getInheritanceReferenceDict(
+ paysheet, portal_type_list=('Annotation Line',))
self.assertEquals(len(model_reference_dict), 3) # there is 4 model but two
# models have the same
# reference.
@@ -1394,8 +1397,6 @@
self.assertNotEquals(model_reference_dict.has_key(model_country_url), True)
# check the object list :
- paysheet = self.createPaysheet()
- paysheet.setSpecialiseValue(model_employee)
object_list = paysheet.getInheritedObjectValueList(portal_type_list=\
('Annotation Line',))
self.assertEquals(len(object_list), 3) # one line have the same reference
@@ -1527,6 +1528,7 @@
base_contribution_list=['base_amount/payroll/base/contribution',
'base_amount/payroll/report/salary/gross'],
quantity=10000)
+ self.stepTic()
# create a paysheet without date
paysheet_without_date = self.createPaysheet()
@@ -1694,9 +1696,7 @@
# check the effective model tree list
effective_value_list = specialise_value.findEffectiveSpecialiseValueList(\
- context=specialise_value,
- start_date=paysheet.getStartDate(),
- stop_date=paysheet.getStopDate())
+ context=paysheet)
self.assertEquals(effective_value_list, [model_2])
def stepCreateModelLineZeroPrice(self, sequence=None, **kw):
@@ -1857,30 +1857,15 @@
model_1.setSpecialiseValue(model_4)
model_4.setSpecialiseValue(model_6)
paysheet.PaySheetTransaction_applyModel()
- self.assertEquals(specialise_value.findSpecialiseValueList(context=paysheet),
- [model_1, model_4, model_6])
- self.assertEquals(specialise_value.findEffectiveSpecialiseValueList(\
- context=paysheet, start_date=paysheet.getStartDate(),
- stop_date=paysheet.getStopDate()), [model_2,])
+ self.assertEquals([model_2],
+ specialise_value.findEffectiveSpecialiseValueList(context=paysheet))
model_1.setSpecialiseValue(None)
model_2.setSpecialiseValue(model_5)
model_5.setSpecialiseValue(model_6)
paysheet.PaySheetTransaction_applyModel()
- self.assertEquals(specialise_value.findSpecialiseValueList(context=paysheet),
- [model_1,])
- self.assertEquals(specialise_value.findEffectiveSpecialiseValueList(\
- context=paysheet, start_date=paysheet.getStartDate(),
- stop_date=paysheet.getStopDate()), [model_2, model_5, model_7])
-
- model_3.setSpecialiseValue(model_5)
- model_5.setSpecialiseValue(model_6)
- paysheet.PaySheetTransaction_applyModel()
- self.assertEquals(specialise_value.findSpecialiseValueList(context=paysheet),
- [model_1,])
- self.assertEquals(specialise_value.findEffectiveSpecialiseValueList(\
- context=paysheet, start_date=paysheet.getStartDate(),
- stop_date=paysheet.getStopDate()), [model_2, model_5, model_7])
+ self.assertEquals([model_2, model_5, model_7],
+ specialise_value.findEffectiveSpecialiseValueList(context=paysheet))
def stepCheckPropertiesAreCopiedFromModelLineToPaySheetLine(self,
sequence=None, **kw):
@@ -2383,6 +2368,7 @@
sequence_string = """
CreateModelTree
ModelTreeAddAnnotationLines
+ Tic
CheckInheritanceModelReferenceDict
"""
sequence_list.addSequenceString(sequence_string)
Modified: erp5/trunk/products/ERP5/tests/testTradeModelLine.py
URL: http://svn.erp5.org/erp5/trunk/products/ERP5/tests/testTradeModelLine.py?rev=34217&r1=34216&r2=34217&view=diff
==============================================================================
--- erp5/trunk/products/ERP5/tests/testTradeModelLine.py [utf8] (original)
+++ erp5/trunk/products/ERP5/tests/testTradeModelLine.py [utf8] Tue Mar 30 18:57:17 2010
@@ -1369,31 +1369,10 @@
order_line_discounted.getTotalPrice() * 0.32) * 0.8
)
+ def assertSameUidSet(self, a, b, msg=None):
+ self.assertEqual(set(x.uid for x in a), set(x.uid for x in b), msg)
+
# Tests
- def test_TradeConditionTradeModelLineBasicComposition(self):
- """
- If Trade Condition is specialised by another Trade Condition they
- Trade Model Lines shall be merged.
- """
- trade_condition_1 = self.createTradeCondition()
- trade_condition_2 = self.createTradeCondition()
-
- trade_condition_1.setSpecialiseValue(trade_condition_2)
-
- trade_condition_1_trade_model_line = self.createTradeModelLine(
- trade_condition_1,
- reference='A')
-
- trade_condition_2_trade_model_line = self.createTradeModelLine(
- trade_condition_2,
- reference='B')
-
- self.assertSameSet(
- [trade_condition_1_trade_model_line,
- trade_condition_2_trade_model_line],
- trade_condition_1.getTradeModelLineComposedList()
- )
-
def test_TradeConditionTradeModelLineBasicCompositionWithOrder(self):
trade_condition_1 = self.createTradeCondition()
trade_condition_2 = self.createTradeCondition()
@@ -1414,66 +1393,26 @@
order,
reference='C')
- self.assertSameSet(
- [trade_condition_1_trade_model_line, trade_condition_2_trade_model_line],
- trade_condition_1.getTradeModelLineComposedList()
- )
-
- self.assertSameSet(
+ self.assertSameUidSet(
[trade_condition_1_trade_model_line, trade_condition_2_trade_model_line,
order_trade_model_line],
trade_condition_1.getTradeModelLineComposedList(context=order)
)
def test_TradeConditionCircularCompositionIsSafe(self):
+ order = self.createOrder()
trade_condition_1 = self.createTradeCondition()
trade_condition_2 = self.createTradeCondition()
+ order.setSpecialiseValue(trade_condition_1)
trade_condition_1.setSpecialiseValue(trade_condition_2)
trade_condition_2.setSpecialiseValue(trade_condition_1)
- self.assertEquals(trade_condition_1. \
- findSpecialiseValueList(trade_condition_1),
+ self.assertEqual(trade_condition_1.findEffectiveSpecialiseValueList(order),
[trade_condition_1, trade_condition_2]
)
- def test_findSpecialiseValueList(self):
- '''
- check that findSpecialiseValueList is able to return all the inheritance
- model tree using Depth-first search
-
- trade_condition_1
- / \
- / \
- / \
- trade_condition_2 trade_condition_3
- |
- |
- |
- trade_condition_4
-
- According to Depth-first search algorithm, result of this graph is:
- [trade_condition_1, trade_condition_2, trade_condition_3,
- trade_condition_4]
- '''
- trade_condition_1 = self.createTradeCondition()
- trade_condition_2 = self.createTradeCondition()
- trade_condition_3 = self.createTradeCondition()
- trade_condition_4 = self.createTradeCondition()
-
- trade_condition_1.setSpecialiseValueList((trade_condition_2,
- trade_condition_3))
- trade_condition_2.setSpecialiseValue(trade_condition_4)
-
- specialise_value_list = trade_condition_1.findSpecialiseValueList(
- context=trade_condition_1)
- self.assertEquals(len(specialise_value_list), 4)
- self.assertEquals(
- [trade_condition_1, trade_condition_2, trade_condition_3,
- trade_condition_4], specialise_value_list)
-
-
- def test_findSpecialiseValueListWithPortalType(self):
+ def test_findEffectiveSpecialiseValueListWithPortalType(self):
'''
check that findSpecialiseValueList is able to return all the inheritance
model tree using Depth-first search with a specific portal_type asked
@@ -1495,45 +1434,28 @@
As only business_process will be a "Business Process" and we search for business process
the result must be [business_process]
'''
+ order = self.createOrder()
trade_condition_1 = self.createTradeCondition()
trade_condition_2 = self.createTradeCondition()
trade_condition_3 = self.createTradeCondition()
trade_condition_4 = self.createTradeCondition()
business_process = self.createBusinessProcess()
-
+
+ order.setSpecialiseValue(trade_condition_1)
trade_condition_1.setSpecialiseValueList((trade_condition_2,
trade_condition_3))
trade_condition_2.setSpecialiseValue(trade_condition_4)
trade_condition_4.setSpecialiseValue(business_process)
-
- specialise_value_list = trade_condition_1.findSpecialiseValueList(
- portal_type_list = ['Business Process'],
- context=trade_condition_1)
- self.assertEquals(len(specialise_value_list), 1)
- self.assertEquals([business_process,] , specialise_value_list)
+
+ self.assertEqual(trade_condition_1.findEffectiveSpecialiseValueList(order),
+ [trade_condition_1, trade_condition_2, trade_condition_3,
+ trade_condition_4])
+ self.assertEqual(trade_condition_1.findEffectiveSpecialiseValueList(order,
+ portal_type_list = ['Business Process']), [business_process])
def test_TradeConditionTradeModelLineReferenceIsShadowingComposition(self):
trade_condition_1 = self.createTradeCondition()
trade_condition_2 = self.createTradeCondition()
-
- trade_condition_1.setSpecialiseValue(trade_condition_2)
-
- trade_condition_1_trade_model_line = self.createTradeModelLine(
- trade_condition_1,
- reference='A')
-
- trade_condition_2_trade_model_line = self.createTradeModelLine(
- trade_condition_2,
- reference='A')
-
- self.assertSameSet(
- [trade_condition_1_trade_model_line],
- trade_condition_1.getTradeModelLineComposedList()
- )
-
- def test_TradeConditionTradeModelLineReferenceIsShadowingCompositionWithOrder(self):
- trade_condition_1 = self.createTradeCondition()
- trade_condition_2 = self.createTradeCondition()
order = self.createOrder()
trade_condition_1.setSpecialiseValue(trade_condition_2)
@@ -1551,13 +1473,7 @@
order,
reference = 'B')
- self.assertSameSet(
- [trade_condition_1_trade_model_line,
- trade_condition_2_trade_model_line],
- trade_condition_1.getTradeModelLineComposedList()
- )
-
- self.assertSameSet(
+ self.assertSameUidSet(
[trade_condition_1_trade_model_line, order_trade_model_line],
trade_condition_1.getTradeModelLineComposedList(context=order)
)
@@ -1568,7 +1484,9 @@
where we create trade model line in a wrong order in comparison to application relations
We have a contribution graph like this A ---> C ---> B so final order must be A, C, B
"""
+ order = self.createOrder()
trade_condition = self.createTradeCondition()
+ order.setSpecialiseValue(trade_condition)
A = self.createTradeModelLine(trade_condition, reference='A', id=1,
base_contribution_list=['base_amount/total'])
@@ -1579,7 +1497,7 @@
C = self.createTradeModelLine(trade_condition, reference='C', id=3,
base_contribution_list=['base_amount/total_tax'],
base_application_list=['base_amount/total'])
- trade_model_line_list = trade_condition.getTradeModelLineComposedList()
+ trade_model_line_list = trade_condition.getTradeModelLineComposedList(order)
self.assertEquals([q.getReference() for q in trade_model_line_list],
[q.getReference() for q in [A, C, B,]])
@@ -1646,7 +1564,9 @@
* (DEFG) (BC) A
where everything in parenthesis can be not sorted
"""
+ order = self.createOrder()
trade_condition = self.createTradeCondition()
+ order.setSpecialiseValue(trade_condition)
A = self.createTradeModelLine(trade_condition, reference='A',
base_application_list=['base_amount/total'])
@@ -1675,7 +1595,7 @@
base_contribution_list=['base_amount/total_discount'],
base_application_list=['base_amount/discount'])
- trade_model_line_list = trade_condition.getTradeModelLineComposedList()
+ trade_model_line_list = trade_condition.getTradeModelLineComposedList(order)
possible_sort_list = [
[[D,E], [B], [F, G], [C], [A]],
@@ -1704,7 +1624,9 @@
* A (BC) D
where everything in parenthesis can be not sorted
"""
+ order = self.createOrder()
trade_condition = self.createTradeCondition()
+ order.setSpecialiseValue(trade_condition)
C = self.createTradeModelLine(trade_condition, reference='C',
base_contribution_list=['base_amount/total'],
@@ -1722,7 +1644,7 @@
base_contribution_list=['base_amount/total'],
base_application_list=['base_amount/total_tax'])
- trade_model_line_list = trade_condition.getTradeModelLineComposedList()
+ trade_model_line_list = trade_condition.getTradeModelLineComposedList(order)
possible_sort_list = [
[[A], [B,C], [D]]
More information about the Erp5-report
mailing list