From 08efff2cbd112085e9d8d3a988300664d9ad5dee Mon Sep 17 00:00:00 2001 From: Jean-Paul Smets <jp@nexedi.com> Date: Mon, 10 May 2004 14:04:31 +0000 Subject: [PATCH] Initial implementation of simplified predicates git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@859 20353a03-c40f-0410-a6d1-a30d3c3de9de --- product/ERP5/Document/PredicateGroup.py | 85 ++++++++++++++++++- product/ERP5/Document/SupplyCell.py | 2 + product/ERP5/Document/SupplyLine.py | 106 +++++++++++++++++++++++- 3 files changed, 190 insertions(+), 3 deletions(-) diff --git a/product/ERP5/Document/PredicateGroup.py b/product/ERP5/Document/PredicateGroup.py index f7352d9059..c7b9f5b771 100755 --- a/product/ERP5/Document/PredicateGroup.py +++ b/product/ERP5/Document/PredicateGroup.py @@ -28,9 +28,11 @@ from Globals import InitializeClass from AccessControl import ClassSecurityInfo +from Acquisition import aq_base from Products.ERP5Type import Permissions, PropertySheet, Constraint, Interface from Products.ERP5Type.Document.Folder import Folder +from Products.ERP5Type.Document import newTempBase from Products.ERP5.Document.Predicate import Predicate @@ -122,7 +124,31 @@ identify a bank account.""" """ A Predicate can be tested on a given context """ - pass + result = 1 + if not hasattr(aq_base(self), '_identity_criterion'): + self._identity_criterion = {} + self._range_criterion = {} + for property, value in self._identity_criterion.items(): + result = result and (context.getProperty(property) == value) + for property, (min, max) in self._range_criterion.items(): + value = context.getProperty(property) + if min is not None: + result = result and (value >= min) + if max is not None: + result = result and (value < max) + multimembership_criterion_base_category_list = self.getMultimembershipCriterionBaseCategoryList() + membership_criterion_base_category_list = self.getMembershipCriterionBaseCategoryList() + tested_base_category = {} + for c in self.getMembershipCriterionCategoryList(): + bc = c.split('/')[0] + if not bc in tested_base_category[bc]: + tested_base_category[bc] = 0 + if bc in multimembership_criterion_base_category_list: + tested_base_category[bc] = tested_base_category[bc] and context.isMemberOf(c) + elif bc in membership_criterion_base_category_list: + tested_base_category[bc] = tested_base_category[bc] or context.isMemberOf(c) + # XXX Add here additional method calls + return result and (0 not in tested_base_category.values()) def asPythonExpression(): """ @@ -145,3 +171,60 @@ identify a bank account.""" """ return getattr(self, 'title', self.predicate_operator) + + security.declareProtected( Permissions.AccessContentsInformation, 'getCriterionList' ) + def getCriterionList(self, **kw): + """ + Returns a list of criterion + """ + if not hasattr(aq_base(self), '_identity_criterion'): + self._identity_criterion = {} + self._range_criterion = {} + criterion_dict = {} + for p in self.getCriterionPropertyList(): + criterion_dict[p] = newTempBase(self, 'new_%s' % p) + criterion_dict[p].identity = self._identity_criterion.get(p, None) + criterion_dict[p].uid = 'new_%s' % p + criterion_dict[p].property = p + criterion_dict[p].min = self._range_criterion.get(p, (None, None))[0] + criterion_dict[p].max = self._range_criterion.get(p, (None, None))[1] + criterion_list = criterion_dict.values() + criterion_list.sort() + return criterion_list + + security.declareProtected( Permissions.ModifyPortalContent, 'setCriterionList' ) + def setCriterion(self, property, identity=None, min=None, max=None, **kw): + if not hasattr(aq_base(self), '_identity_criterion'): + self._identity_criterion = {} + self._range_criterion = {} + self._identity_criterion[property] = identity + self._range_criterion[property] = (min, max) + + # Predicate fusion method + def setPredicateCategoryList(self, category_list): + category_tool = aq_base(self.portal_categories) + base_category_id_list = category_tool.objectIds() + membership_criterion_category_list = [] + membership_criterion_base_category_list = [] + multimembership_criterion_base_category_list = [] + for c in category_list: + bc = c.split('/')[0] + if bc in base_category_id_list: + # This is a category + membership_criterion_category_list.append(c) + membership_criterion_base_category_list.append(bc) + else: + predicate_value = category_tool.resolveCategory(c) + if predicate_value: + membership_criterion_category_list.extend( + predicate_value.getMembershipCriterionCategoryList()) + membership_criterion_base_category_list.extend( + predicate_value.getMembershipCriterionBaseCategoryList()) + multimembership_criterion_base_category_list.extend( + predicate_value.getMultimembershipCriterionBaseCategoryList()) + for p in predicate_value.getCriterionList(): + self.setCriterion(p.property, identity=p.identity, min=p.min, max=p.max) + self.getMembershipCriterionCategoryList(membership_criterion_category_list) + self.getMembershipCriterionBaseCategoryList(membership_criterion_base_category_list) + self.getMultimembershipCriterionBaseCategoryList(multimembership_criterion_base_category_list) + \ No newline at end of file diff --git a/product/ERP5/Document/SupplyCell.py b/product/ERP5/Document/SupplyCell.py index 24b0856a49..57fbcf0535 100755 --- a/product/ERP5/Document/SupplyCell.py +++ b/product/ERP5/Document/SupplyCell.py @@ -65,6 +65,8 @@ class SupplyCell(DeliveryCell, Path): , PropertySheet.Price , PropertySheet.Path , PropertySheet.FlowCapacity + , PropertySheet.Predicate + , PropertySheet.MappedValue ) # Factory Type Information diff --git a/product/ERP5/Document/SupplyLine.py b/product/ERP5/Document/SupplyLine.py index 88087ddb05..907d4a0c80 100755 --- a/product/ERP5/Document/SupplyLine.py +++ b/product/ERP5/Document/SupplyLine.py @@ -31,8 +31,10 @@ from AccessControl import ClassSecurityInfo from Products.CMFCore.WorkflowCore import WorkflowAction from Products.ERP5Type import Permissions, PropertySheet, Constraint, Interface +from Products.ERP5Type.XMLMatrix import XMLMatrix from Products.ERP5.Document.DeliveryLine import DeliveryLine +from Products.ERP5.Document.Movement import Movement from Products.ERP5.Document.Path import Path class SupplyLine(DeliveryLine, Path): @@ -135,7 +137,7 @@ Une ligne tarifaire.""" return self.get(id) security.declareProtected( Permissions.ModifyPortalContent, 'hasCellContent' ) - def hasCellContent(self, base_id='movement'): + def hasCellContent(self, base_id='path'): """ This method can be overriden """ @@ -144,7 +146,7 @@ Une ligne tarifaire.""" return len(self.contentValues()) > 0 security.declareProtected( Permissions.AccessContentsInformation, 'getCellValueList' ) - def getCellValueList(self, base_id='movement'): + def getCellValueList(self, base_id='path'): """ This method can be overriden """ @@ -239,3 +241,103 @@ Une ligne tarifaire.""" return self._getDestinationTotalPrice(self.asContext(context=context, REQUEST=REQUEST, **kw)) + # Cell Related + security.declareProtected( Permissions.ModifyPortalContent, 'newCellContent' ) + def newCellContent(self, id): + """ + This method can be overriden + """ + self.invokeFactory(type_name="Supply Cell",id=id) + return self.get(id) + + security.declareProtected( Permissions.ModifyPortalContent, 'hasCellContent' ) + def hasCellContent(self, base_id='path'): + """ + This method can be overriden + """ + return XMLMatrix.hasCellContent(self, base_id=base_id) + # If we need it faster, we can use another approach... + return len(self.contentValues()) > 0 + + security.declareProtected( Permissions.AccessContentsInformation, 'getCellValueList' ) + def getCellValueList(self, base_id='path'): + """ + This method can be overriden + """ + return XMLMatrix.getCellValueList(self, base_id=base_id) + + security.declareProtected( Permissions.View, 'getCell' ) + def getCell(self, *kw , **kwd): + """ + This method can be overriden + """ + if 'base_id' not in kwd: + kwd['base_id'] = 'movement' + + return XMLMatrix.getCell(self, *kw, **kwd) + + security.declareProtected( Permissions.ModifyPortalContent, 'newCell' ) + def newCell(self, *kw, **kwd): + """ + This method creates a new cell + """ + if 'base_id' not in kwd: + kwd['base_id'] = 'path' + + return XMLMatrix.newCell(self, *kw, **kwd) + + # For generation of matrix lines + security.declareProtected( Permissions.ModifyPortalContent, '_setQuantityRangeList' ) + def _setQuantityRangeList(self, value): + self._baseSetQuantityRangeList(value) + value = self.getQuantityRangeList() + value.sort() + for pid in self.contentIds(filter={'portal_type': 'Predicate'}): + self.deleteContent(pid) + value = value + [None] + for i in range(0, len(value) - 1): + p = self.newContent(id = 'quantity_range_%s' % i, portal_type = 'Predicate') + p.setCriterionPropertyList(('quantity', )) + p.setCriterion('quantity', min=value[i], max=value[i+1]) + self._setVariationCategoryList(self.getVariationCategoryList()) + + security.declareProtected( Permissions.ModifyPortalContent, '_setVariationCategoryList' ) + def _setVariationCategoryList(self, value): + """ + Define the indices provided + one list per index (kw) + + Any number of list can be provided + """ + Movement._setVariationCategoryList(self, value) + # Update the cell range automatically + # This is far from easy and requires some specific wizzardry + base_id = 'path' + kwd = {'base_id': base_id} + new_range = self.SupplyLine_asCellRange() # This is a site dependent script + self._setCellRange(*new_range, **kwd ) + #LOG('setCellRange',0,str(new_range)) + cell_range_key_list = self.getCellRangeKeyList(base_id = base_id) + #LOG('cell_range_key_list',0,str(self.getCellRange(base_id = base_id))) + if cell_range_key_list <> [[None, None]] : + for k in cell_range_key_list: + #LOG('new cell',0,str(k)) + c = self.newCell(*k, **kwd) + c.edit( domain_base_category_list = self.getVariationBaseCategoryList(), + mapped_value_property_list = ( 'price',), + predicate_operator = 'SUPERSET_OF', + predicate_value = filter(lambda k_item: k_item is not None, k), + variation_category_list = filter(lambda k_item: k_item is not None, k), + force_update = 1 + ) # Make sure we do not take aquisition into account + else: + # If only one cell, delete it + cell_range_id_list = self.getCellRangeIdList(base_id = base_id) + for k in cell_range_id_list: + if self.get(k) is not None: + self[k].flushActivity(invoke=0) + self[k].immediateReindexObject() # We are forced to do this is url is changed (not uid) + self._delObject(k) + + # TO BE DONE XXX + # reindex cells when price, quantity or source/dest changes -- 2.30.9