From 449214a51dc7f54892043951fac1c3a0cd88f171 Mon Sep 17 00:00:00 2001 From: Jean-Paul Smets <jp@nexedi.com> Date: Wed, 23 Feb 2005 10:26:59 +0000 Subject: [PATCH] Massive update to remove target values in simulation git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@2539 20353a03-c40f-0410-a6d1-a30d3c3de9de --- product/ERP5/DeliverySolver/Copy.py | 2 +- product/ERP5/DeliverySolver/Distribute.py | 11 +- .../Document/AccountingTransactionLine.py | 20 +- product/ERP5/Document/Amount.py | 32 ---- product/ERP5/Document/ContainerLine.py | 6 +- product/ERP5/Document/Delivery.py | 97 ++++------ product/ERP5/Document/DeliveryCell.py | 34 +--- product/ERP5/Document/DeliveryLine.py | 71 +------ product/ERP5/Document/DeliveryRule.py | 6 - product/ERP5/Document/Domain.py | 23 ++- product/ERP5/Document/Invoice.py | 36 ++-- product/ERP5/Document/InvoicingRule.py | 18 +- product/ERP5/Document/Movement.py | 173 +++++++++++++++--- product/ERP5/Document/OrderLine.py | 17 +- product/ERP5/Document/OrderRule.py | 23 ++- product/ERP5/Document/PaymentRule.py | 20 +- product/ERP5/Document/PredicateGroup.py | 9 +- product/ERP5/Document/SimulationMovement.py | 15 ++ product/ERP5/Document/TransformationRule.py | 28 +-- product/ERP5/ERP5Defaults.py | 2 +- .../ERP5/Extensions/InitializeAcquisition.py | 4 +- product/ERP5/MovementGroup.py | 44 ++--- product/ERP5/PropertySheet/Amount.py | 25 --- product/ERP5/PropertySheet/Arrow.py | 166 ----------------- product/ERP5/PropertySheet/Inventory.py | 11 -- product/ERP5/PropertySheet/Predicate.py | 10 +- product/ERP5/TargetSolver/CopyToTarget.py | 6 +- product/ERP5/Tool/SimulationTool.py | 119 +++++------- product/ERP5/tests/testInvoice.py | 29 ++- 29 files changed, 444 insertions(+), 613 deletions(-) diff --git a/product/ERP5/DeliverySolver/Copy.py b/product/ERP5/DeliverySolver/Copy.py index 471d8926cb..bf7ddb66bb 100755 --- a/product/ERP5/DeliverySolver/Copy.py +++ b/product/ERP5/DeliverySolver/Copy.py @@ -45,6 +45,6 @@ class Copy(DeliverySolver): """ Solve a delivery """ - movement.setQuantity(movement.getTargetQuantity()) + movement.setQuantity(movement.getSimulationQuantity()) registerDeliverySolver(Copy) diff --git a/product/ERP5/DeliverySolver/Distribute.py b/product/ERP5/DeliverySolver/Distribute.py index aba8c31b73..4571a87bee 100755 --- a/product/ERP5/DeliverySolver/Distribute.py +++ b/product/ERP5/DeliverySolver/Distribute.py @@ -40,12 +40,12 @@ class Distribute(DeliverySolver): Solve a delivery by reducing / increasing each simulation movement it relates to """ + delivery_line_simulation_quantity = float(movement.getSimulationQuantity()) delivery_line_quantity = float(movement.getQuantity()) - delivery_line_target_quantity = float(movement.getTargetQuantity()) - if delivery_line_quantity != delivery_line_target_quantity: - if delivery_line_quantity != 0 : - # XXXXXXXXXXXXXXXXXXXXXXXXX something special should be done if delivery_line_quantity == 0 ! - distribute_ratio = delivery_line_target_quantity / delivery_line_quantity + if delivery_line_simulation_quantity != delivery_line_quantity: + if delivery_line_simulation_quantity != 0 : + # XXXXXXXXXXXXXXXXXXXXXXXXX something special should be done if delivery_line_simulation_quantity == 0 ! + distribute_ratio = delivery_line_quantity / delivery_line_simulation_quantity for s in movement.getDeliveryRelatedValueList(): # Reduce quantity s.setQuantity(s.getQuantity() * distribute_ratio) @@ -64,7 +64,6 @@ class Distribute(DeliverySolver): s.setStartDate(movement.getStartDate()) s.setStopDate(movement.getStopDate()) s.diverge() # Make sure everyone knows this simulation movement is inconsistent - movement.setQuantity(movement.getTargetQuantity()) # No need to touch date since it should be defined at the upper level. registerDeliverySolver(Distribute) diff --git a/product/ERP5/Document/AccountingTransactionLine.py b/product/ERP5/Document/AccountingTransactionLine.py index 18321f5103..4887fa62fa 100755 --- a/product/ERP5/Document/AccountingTransactionLine.py +++ b/product/ERP5/Document/AccountingTransactionLine.py @@ -28,6 +28,7 @@ from Globals import InitializeClass, PersistentMapping from AccessControl import ClassSecurityInfo +from Acquisition import aq_base, aq_inner, aq_acquire, aq_chain from Products.CMFCore.WorkflowCore import WorkflowAction from Products.ERP5Type import Permissions, PropertySheet, Constraint, Interface @@ -201,10 +202,13 @@ Une ligne tarifaire.""" security.declarePrivate('_setSource') def _setSource(self, value): self._setCategoryMembership('source', value, base=0) - if self.getPortalType() not in self.getPortalBalanceTransactionLineTypeList(): - source = self.restrictedTraverse(value) + if self.getPortalType() not in self.getPortalBalanceTransactionLineTypeList() and value not in (None, ''): + source = self.getPortalObject().portal_categories.resolveCategory(value) destination = self.getDestination() - mirror_list = source.getDestinationList() + if source is not None: + mirror_list = source.getDestinationList() + else: + mirror_list = [] #LOG('_setSource', 0, 'value = %s, mirror_list = %s, destination = %s' % (str(value), str(mirror_list), str(destination))) if len(mirror_list) > 0 and destination not in mirror_list: self._setCategoryMembership('destination', mirror_list[0], base=0) @@ -219,11 +223,15 @@ Une ligne tarifaire.""" security.declarePrivate('_setDestination') def _setDestination(self, value): - if self.getPortalType() not in self.getPortalBalanceTransactionLineTypeList(): + if self.getPortalType() not in self.getPortalBalanceTransactionLineTypeList() and value not in (None, ''): self._setCategoryMembership('destination', value, base=0) - destination = self.restrictedTraverse(value) + destination = self.getPortalObject().portal_categories.resolveCategory(value) source = self.getSource() - mirror_list = destination.getDestinationList() + if destination is not None: + #LOG('_setSource', 0, 'destination %s' % destination) + mirror_list = destination.getDestinationList() + else: + mirror_list = [] #LOG('_setDestination', 0, 'value = %s, mirror_list = %s, source = %s' % (str(value), str(mirror_list), str(source))) if len(mirror_list) > 0 and source not in mirror_list: self._setCategoryMembership('source', mirror_list[0], base=0) diff --git a/product/ERP5/Document/Amount.py b/product/ERP5/Document/Amount.py index 6cf48ff591..d306f0f576 100755 --- a/product/ERP5/Document/Amount.py +++ b/product/ERP5/Document/Amount.py @@ -206,38 +206,6 @@ class Amount(Base, Variated): except: LOG("ERP5 WARNING:", 100, 'could not set converted quantity for %s' % self.getRelativeUrl()) - security.declareProtected(Permissions.AccessContentsInformation, 'getConvertedTargetQuantity') - def getConvertedTargetQuantity(self): - """ - Converts target_quantity to default unit - """ - #if 1: - try: - #if 1: - resource = self.getResourceValue() - resource_quantity_unit = resource.getDefaultQuantityUnit() - quantity_unit = self.getQuantityUnit() - quantity = self.getTargetQuantity() - converted_quantity = resource.convertQuantity(quantity, quantity_unit, resource_quantity_unit) - #else: - except: - #else: - LOG("ERP5 WARNING:", 100, 'could not convert target_quantity for %s' % self.getRelativeUrl()) - converted_quantity = None - return converted_quantity - - security.declareProtected(Permissions.ModifyPortalContent, 'setConvertedTargetQuantity') - def setConvertedTargetQuantity(self, value): - try: - #if 1: - resource = self.getResourceValue() - resource_quantity_unit = resource.getDefaultQuantityUnit() - quantity_unit = self.getQuantityUnit() - quantity = resource.convertQuantity(value, resource_quantity_unit, quantity_unit) - self.setTargetQuantity(quantity) - except: - LOG("ERP5 WARNING:", 100, 'could not set converted quantity for %s' % self.getRelativeUrl()) - security.declareProtected(Permissions.AccessContentsInformation, 'getNetQuantity') def getNetQuantity(self): """ diff --git a/product/ERP5/Document/ContainerLine.py b/product/ERP5/Document/ContainerLine.py index b849b20593..c4c9a7c3cd 100755 --- a/product/ERP5/Document/ContainerLine.py +++ b/product/ERP5/Document/ContainerLine.py @@ -164,8 +164,8 @@ Une ligne tarifaire.""" # Never divergent return 0 - security.declareProtected(Permissions.AccessContentsInformation, 'getTargetTotalQuantity') - def getTargetTotalQuantity(self): + security.declareProtected(Permissions.AccessContentsInformation, 'getTotalQuantity') + def getTotalQuantity(self): """ Returns the quantity if no cell or the total quantity if cells """ @@ -174,4 +174,4 @@ Une ligne tarifaire.""" else: # Use MySQL aggregate = self.ContainerLine_zGetTotal()[0] - return aggregate.target_total_quantity + return aggregate.total_quantity diff --git a/product/ERP5/Document/Delivery.py b/product/ERP5/Document/Delivery.py index 8b16adddb1..30fc7dcd0f 100755 --- a/product/ERP5/Document/Delivery.py +++ b/product/ERP5/Document/Delivery.py @@ -373,18 +373,12 @@ class Delivery(XMLObject): for date_group in path_group.group_list : invoice = invoice_module.newContent(portal_type = invoice_type, - target_start_date = date_group.start_date, - target_stop_date = date_group.stop_date, start_date = date_group.start_date, stop_date = date_group.stop_date, source = path_group.source, destination = path_group.destination, source_section = path_group.source_section, destination_section = path_group.destination_section, - target_source = path_group.source, - target_destination = path_group.destination, - target_source_section = path_group.source_section, - target_destination_section = path_group.destination_section, causality_value = self, title = self.getTitle(), description = 'Invoice related to the Delivery %s' % self.getTitle()) @@ -396,7 +390,8 @@ class Delivery(XMLObject): LOG('buildInvoiceList resource_group.group_list',0,resource_group.group_list) # Create a new Sale Invoice Transaction Line for each resource - invoice_line = invoice.newContent(portal_type=invoice_line_type + invoice_line = invoice.newContent( + portal_type=invoice_line_type , resource=resource_group.resource) # line_variation_category_list = [] @@ -421,15 +416,15 @@ class Delivery(XMLObject): #XXX for now, we quickly need this working, without the need of variant_group object_to_update = invoice_line - # compute target_quantity, quantity and price for invoice_cell or invoice_line and + # compute quantity and price for invoice_cell or invoice_line and # build relation between simulation_movement and invoice_cell or invoice_line if object_to_update is not None : - target_quantity = 0 + quantity = 0 total_price = 0 for movement in resource_group.movement_list : - target_quantity += movement.getConvertedTargetQuantity() + quantity += movement.getConvertedQuantity() try : - total_price += movement.getNetConvertedTargetQuantity() * movement.getPrice() # XXX WARNING - ADD PRICED QUANTITY + total_price += movement.getNetConvertedQuantity() * movement.getPrice() # XXX WARNING - ADD PRICED QUANTITY except : total_price = None # What do we really need to update in the simulation movement ? @@ -437,17 +432,16 @@ class Delivery(XMLObject): movement._setDeliveryValue(object_to_update) reindexable_movement_list.append(movement) - if target_quantity <> 0 and total_price is not None: - average_price = total_price/target_quantity + if quantity <> 0 and total_price is not None: + average_price = total_price/quantity else : average_price = 0 - LOG('buildInvoiceList edit', 0, repr(( object_to_update, target_quantity, average_price, ))) - object_to_update.edit(target_quantity = target_quantity, - quantity = target_quantity, + LOG('buildInvoiceList edit', 0, repr(( object_to_update, quantity, average_price, ))) + object_to_update.edit(quantity = quantity, price = average_price) - # update target_quantity, quantity and price for each invoice_cell + # update quantity and price for each invoice_cell #XXX for variant_group in resource_group.group_list : if 0 : LOG('Variant_group examin',0,str(variant_group.category_list)) @@ -476,15 +470,15 @@ class Delivery(XMLObject): object_to_update = invoice_cell break - # compute target_quantity, quantity and price for invoice_cell or invoice_line and + # compute quantity and price for invoice_cell or invoice_line and # build relation between simulation_movement and invoice_cell or invoice_line if object_to_update is not None : - cell_target_quantity = 0 + cell_quantity = 0 cell_total_price = 0 for movement in variant_group.movement_list : - cell_target_quantity += movement.getConvertedTargetQuantity() + cell_quantity += movement.getConvertedQuantity() try : - cell_total_price += movement.getNetConvertedTargetQuantity() * movement.getPrice() # XXX WARNING - ADD PRICED QUANTITY + cell_total_price += movement.getNetConvertedQuantity() * movement.getPrice() # XXX WARNING - ADD PRICED QUANTITY except : cell_total_price = None # What do we really need to update in the simulation movement ? @@ -492,15 +486,15 @@ class Delivery(XMLObject): movement._setDeliveryValue(object_to_update) reindexable_movement_list.append(movement) - if cell_target_quantity <> 0 and cell_total_price is not None: - average_price = cell_total_price/cell_target_quantity + if cell_quantity <> 0 and cell_total_price is not None: + average_price = cell_total_price/cell_quantity else : average_price = 0 - LOG('buildInvoiceList edit', 0, repr(( object_to_update, cell_target_quantity, average_price, ))) - object_to_update.edit(target_quantity = cell_target_quantity, - quantity = cell_target_quantity, + LOG('buildInvoiceList edit', 0, repr(( object_to_update, cell_quantity, average_price, ))) + object_to_update.edit(quantity = cell_quantity, price = average_price) + # we now reindex the movements we modified for movement in reindexable_movement_list : movement.immediateReindexObject() @@ -527,13 +521,6 @@ class Delivery(XMLObject): result = self.z_total_price(delivery_uid = self.getUid()) return result[0][0] - security.declareProtected(Permissions.AccessContentsInformation, 'getTargetTotalPrice') - def getTargetTotalPrice(self): - """ - """ - result = self.z_total_price(delivery_uid = self.getUid()) - return result[0][1] - # security.declareProtected(Permissions.AccessContentsInformation, 'getTotalPrice') # def getTotalPrice(self, context=None, REQUEST=None, **kw): # """ @@ -581,14 +568,6 @@ class Delivery(XMLObject): aggregate = self.Delivery_zGetTotal(uid=self.getUid())[0] return aggregate.total_quantity - security.declareProtected(Permissions.AccessContentsInformation, 'getTargetTotalQuantity') - def getTargetTotalQuantity(self): - """ - Returns the quantity if no cell or the total quantity if cells - """ - aggregate = self.Delivery_zGetTotal()[0] - return aggregate.target_total_quantity - security.declareProtected(Permissions.AccessContentsInformation, 'getDeliveryUid') def getDeliveryUid(self): return self.getUid() @@ -694,8 +673,8 @@ class Delivery(XMLObject): LOG('Delivery.isSimulated m.isSimulated',0,m.isSimulated()) if not m.isSimulated(): LOG('Delivery.isSimulated m.getQuantity',0,m.getQuantity()) - LOG('Delivery.isSimulated m.getTargetQuantity',0,m.getTargetQuantity()) - if m.getQuantity() != 0.0 or m.getTargetQuantity() != 0: + LOG('Delivery.isSimulated m.getSimulationQuantity',0,m.getSimulationQuantity()) + if m.getQuantity() != 0.0 or m.getSimulationQuantity() != 0: return 0 # else Do we need to create a simulation movement ? XXX probably not return 1 @@ -718,9 +697,9 @@ class Delivery(XMLObject): Source is divergent if simulated and target values differ or if multiple sources are defined """ - if self.getSource() != self.getTargetSource() \ + if self.getSource() != self.getSimulationSource() \ or len(self.getSourceList()) > 1 \ - or len(self.getTargetSourceList()) > 1: + or len(self.getSimulationSourceList()) > 1: return 1 return 0 @@ -732,12 +711,12 @@ class Delivery(XMLObject): """ LOG('Delivery.isDestinationDivergent, self.getPath()',0,self.getPath()) LOG('Delivery.isDestinationDivergent, self.getDestination()',0,self.getDestination()) - LOG('Delivery.isDestinationDivergent, self.getTargetDestination()',0,self.getTargetDestination()) + LOG('Delivery.isDestinationDivergent, self.getSimulationDestination()',0,self.getSimulationDestination()) LOG('Delivery.isDestinationDivergent, self.getDestinationList()',0,self.getDestinationList()) - LOG('Delivery.isDestinationDivergent, self.getTargetDestinationList()',0,self.getTargetDestinationList()) - if self.getDestination() != self.getTargetDestination() \ + LOG('Delivery.isDestinationDivergent, self.getSimulationDestinationList()',0,self.getSimulationDestinationList()) + if self.getDestination() != self.getSimulationDestination() \ or len(self.getDestinationList()) > 1 \ - or len(self.getTargetDestinationList()) > 1: + or len(self.getSimulationDestinationList()) > 1: return 1 return 0 @@ -746,9 +725,9 @@ class Delivery(XMLObject): """ Same as isSourceDivergent for source_section """ - if self.getSourceSection() != self.getTargetSourceSection() \ + if self.getSourceSection() != self.getSimulationSourceSection() \ or len(self.getSourceSectionList()) > 1 \ - or len(self.getTargetSourceSectionList()) > 1: + or len(self.getSimulationSourceSectionList()) > 1: return 1 return 0 @@ -757,9 +736,9 @@ class Delivery(XMLObject): """ Same as isDestinationDivergent for source_section """ - if self.getDestinationSection() != self.getTargetDestinationSection() \ + if self.getDestinationSection() != self.getSimulationDestinationSection() \ or len(self.getDestinationSectionList()) > 1 \ - or len(self.getTargetDestinationSectionList()) > 1: + or len(self.getSimulationDestinationSectionList()) > 1: return 1 return 0 @@ -768,16 +747,16 @@ class Delivery(XMLObject): """ """ LOG("isDivergent getStartDate", 0, repr(self.getStartDate())) - LOG("isDivergent getTargetStartDate", 0, repr(self.getTargetStartDate())) + LOG("isDivergent getSimulationStartDate", 0, repr(self.getSimulationStartDate())) LOG("isDivergent getStopDate", 0, repr(self.getStopDate())) - LOG("isDivergent getTargetStopDate", 0, repr(self.getTargetStopDate())) + LOG("isDivergent getSimulationStopDate", 0, repr(self.getSimulationStopDate())) from DateTime import DateTime - if self.getStartDate() is None or self.getTargetStartDate() is None \ - or self.getStopDate() is None or self.getTargetStopDate() is None: + if self.getStartDate() is None or self.getSimulationStartDate() is None \ + or self.getStopDate() is None or self.getSimulationStopDate() is None: return 1 # This is uggly but required due to python2.2/2.3 Zope 2.6/2.7 inconsistency in _millis calculation - if self.getStartDate().Date() != self.getTargetStartDate().Date() or \ - self.getStopDate().Date() != self.getTargetStopDate().Date(): + if self.getStartDate().Date() != self.getSimulationStartDate().Date() or \ + self.getStopDate().Date() != self.getSimulationStopDate().Date(): # LOG("isDivergent getStartDate", 0, repr(self.getStartDate())) # LOG("isDivergent getTargetStartDate", 0, repr(self.getTargetStartDate())) # LOG("isDivergent getStopDate", 0, repr(self.getStopDate())) diff --git a/product/ERP5/Document/DeliveryCell.py b/product/ERP5/Document/DeliveryCell.py index e858866e65..fe16b76910 100755 --- a/product/ERP5/Document/DeliveryCell.py +++ b/product/ERP5/Document/DeliveryCell.py @@ -240,21 +240,6 @@ Une ligne tarifaire.""" return self.getTargetQuantity() # We have acquisition here which me should mimic # return None - security.declareProtected( Permissions.AccessContentsInformation, 'getTargetQuantity' ) - def getTargetQuantity(self): - """ - Returns the target quantity if defined on the cell - or acquire it - """ - # Call a script on the context - if 'target_quantity' in self.getMappedValuePropertyList([]): - if getattr(aq_base(self), 'target_quantity', None) is not None: - return getattr(self, 'target_quantity') - else: - return self.aq_parent.getProperty('target_quantity') - else: - return None - def _setItemIdList(self, value): """ Computes total_quantity of all given items and stores this total_quantity @@ -353,34 +338,19 @@ Une ligne tarifaire.""" return self.getParent().getRootDeliveryValue() # Simulation Consistency Check - def getRelatedQuantity(self): + def getSimulationQuantity(self): """ Computes the quantities in the simulation """ if isinstance(self, OrderLine): result = self.OrderLine_zGetRelatedQuantity(uid=self.getUid()) - if len(result) > 0: - return result[0].target_quantity - return None - else: - result = self.DeliveryLine_zGetRelatedQuantity(uid=self.getUid()) if len(result) > 0: return result[0].quantity return None - - def getRelatedTargetQuantity(self): - """ - Computes the target quantities in the simulation - """ - if isinstance(self, OrderLine): - result = self.OrderLine_zGetRelatedQuantity(uid=self.getUid()) - if len(result) > 0: - return result[0].target_quantity - return None else: result = self.DeliveryLine_zGetRelatedQuantity(uid=self.getUid()) if len(result) > 0: - return result[0].target_quantity + return result[0].quantity return None security.declareProtected( Permissions.ModifyPortalContent, 'notifyAfterUpdateRelatedContent' ) diff --git a/product/ERP5/Document/DeliveryLine.py b/product/ERP5/Document/DeliveryLine.py index b455239b4c..3916af785c 100755 --- a/product/ERP5/Document/DeliveryLine.py +++ b/product/ERP5/Document/DeliveryLine.py @@ -209,23 +209,13 @@ Une ligne tarifaire.""" def _getTotalPrice(self, context): if not self.hasCellContent(): - price = self.getPrice(context=context) - if price is None: price = 0.0 # Quick and dirty fix XXX - return self.getQuantity() * price - else: - # Use MySQL - aggregate = self.DeliveryLine_zGetTotal()[0] - return aggregate.total_price - - def _getTargetTotalPrice(self, context): - if not self.hasCellContent(): - target_quantity = self.getTargetQuantity() or 0.0 + quantity = self.getQuantity() or 0.0 price = self.getPrice(context=context) or 0.0 - return target_quantity * price + return quantity * price else: # Use MySQL aggregate = self.DeliveryLine_zGetTotal()[0] - return aggregate.target_total_price + return aggregate.total_price security.declareProtected(Permissions.AccessContentsInformation, 'getTotalQuantity') def getTotalQuantity(self): @@ -239,18 +229,6 @@ Une ligne tarifaire.""" aggregate = self.DeliveryLine_zGetTotal()[0] return aggregate.total_quantity - security.declareProtected(Permissions.AccessContentsInformation, 'getTargetTotalQuantity') - def getTargetTotalQuantity(self): - """ - Returns the quantity if no cell or the total quantity if cells - """ - if not self.hasCellContent(): - return self.getTargetQuantity() - else: - # Use MySQL - aggregate = self.DeliveryLine_zGetTotal()[0] - return aggregate.target_total_quantity - # Cell Related security.declareProtected( Permissions.ModifyPortalContent, 'newCellContent' ) def newCellContent(self, id, **kw): @@ -320,7 +298,7 @@ Une ligne tarifaire.""" #LOG('new cell',0,str(k)) c = self.newCell(*k, **kwd) c.edit( domain_base_category_list = self.getVariationBaseCategoryList(), - mapped_value_property_list = ('target_quantity', 'quantity', 'price',), + mapped_value_property_list = ('quantity', 'price',), #predicate_operator = 'SUPERSET_OF', membership_criterion_category = filter(lambda k_item: k_item is not None, k), variation_category_list = filter(lambda k_item: k_item is not None, k), @@ -468,7 +446,7 @@ Une ligne tarifaire.""" security.declarePrivate('_checkConsistency') - def _checkConsistency(self, fixit=0, mapped_value_property_list = ('target_quantity', 'quantity', 'price')): + def _checkConsistency(self, fixit=0, mapped_value_property_list = ('quantity', 'price')): """ Check the constitency of transformation elements """ @@ -507,18 +485,10 @@ Une ligne tarifaire.""" """ Computes the quantities in the simulation """ - result = self.DeliveryLine_zGetRelatedQuantity(uid=self.getUid()) - if len(result) > 0: - return result[0].quantity - return None - - def getSimulationTargetQuantity(self): - """ - Computes the target quantities in the simulation - """ - result = self.DeliveryLine_zGetRelatedQuantity(uid=self.getUid()) - if len(result) > 0: - return result[0].target_quantity + if not self.hasCellContent(): + result = self.DeliveryLine_zGetRelatedQuantity(uid=self.getUid()) + if len(result) > 0: + return result[0].quantity return None def getSimulationSourceList(self): @@ -556,26 +526,3 @@ Une ligne tarifaire.""" """ return self.getParent().getRootDeliveryValue() - # Simulation Consistency Check - def getRelatedQuantity(self): - """ - Computes the quantities in the simulation - """ - if not self.hasCellContent(): - result = self.DeliveryLine_zGetRelatedQuantity(uid=self.getUid()) - if len(result) > 0: - return result[0].quantity - return None - - def getRelatedTargetQuantity(self): - """ - Computes the target quantities in the simulation - """ - if not self.hasCellContent(): - result = self.DeliveryLine_zGetRelatedQuantity(uid=self.getUid()) - if len(result) > 0: - return result[0].target_quantity - return None - - - diff --git a/product/ERP5/Document/DeliveryRule.py b/product/ERP5/Document/DeliveryRule.py index 15ca32cad3..9d0111ccc4 100755 --- a/product/ERP5/Document/DeliveryRule.py +++ b/product/ERP5/Document/DeliveryRule.py @@ -183,11 +183,8 @@ An ERP5 Rule...""" delivery_value = c, order_value = c, quantity = c.getQuantity(), - target_quantity = c.getTargetQuantity(), start_date = c.getStartDate(), stop_date = c.getStopDate(), - target_start_date = c.getTargetStartDate(), - target_stop_date = c.getTargetStopDate(), deliverable = 1 ) # We must create both order and delivery link in this case @@ -203,11 +200,8 @@ An ERP5 Rule...""" delivery_value = delivery_line_object, order_value = delivery_line_object, quantity = delivery_line_object.getQuantity(), - target_quantity = delivery_line_object.getTargetQuantity(), start_date = delivery_line_object.getStartDate(), stop_date = delivery_line_object.getStopDate(), - target_start_date = delivery_line_object.getTargetStartDate(), - target_stop_date = delivery_line_object.getTargetStopDate(), deliverable = 1 ) # Source, Destination, Quantity, Date, etc. are diff --git a/product/ERP5/Document/Domain.py b/product/ERP5/Document/Domain.py index 958051c542..25eaaf2db1 100755 --- a/product/ERP5/Document/Domain.py +++ b/product/ERP5/Document/Domain.py @@ -37,7 +37,28 @@ class Domain(PredicateGroup): """ An abstract class subclassed by reports and mapped values - Implements subdomain traversal methods + Structure is: + - base domain (like base category) + - sub domain (like category) + + Allows to define ranges: + - price between X and Y + - portal_type in (a, b, c) + - price between X and Y and region in (a, b, c) + + Reports: + - listbox allows to produce reports + - output to html, pdf or ooffice + - definition through the web (ie. which field in which column, which statistics) + - definition of selection (to list) + - ability for use to "save" favourite report (user reports) + - library of favourite reports (global reports) + - matrixbox allows to produce reports + - output to html, pdf or ooffice + - definition through the web (ie. which base_category or base_domain in which axis) + - definition of selection (to map to matrix) + - ability for use to "save" favourite report (user reports) + - library of favourite reports (global reports) """ meta_type = 'ERP5 Domain' portal_type = 'Domain' diff --git a/product/ERP5/Document/Invoice.py b/product/ERP5/Document/Invoice.py index 7a47dc1988..41e67b7063 100755 --- a/product/ERP5/Document/Invoice.py +++ b/product/ERP5/Document/Invoice.py @@ -106,7 +106,7 @@ class Invoice(AccountingTransaction): for rule in o.objectValues(): invoice_transaction_rule_list.append(rule) simulation_line_list += rule.objectValues() - LOG('buildInvoiceTransactionList simulation_line_list',0,simulation_line_list) + #LOG('buildInvoiceTransactionList simulation_line_list',0,simulation_line_list) from Products.ERP5.MovementGroup import CategoryMovementGroup class_list = [CategoryMovementGroup, ] root_group = self.portal_simulation.collectMovement(simulation_line_list,class_list=class_list) @@ -144,9 +144,14 @@ class Invoice(AccountingTransaction): # add sum of movements to invoice #LOG('buildInvoiceTransactionList group_id',0,group_id) + #LOG('buildInvoiceTransactionList reference_movement',0,str(reference_movement.getRelativeUrl())) + #LOG('buildInvoiceTransactionList reference_movement',0,str(reference_movement.showDict())) + #LOG('buildInvoiceTransactionList reference_movement',0,str(reference_movement.getSource())) + #LOG('buildInvoiceTransactionList reference_movement',0,str(reference_movement.getDestination())) sale_invoice_transaction_line_item = getattr(self, group_id, None) if sale_invoice_transaction_line_item is None : - sale_invoice_transaction_line_item = self.newContent(portal_type = self._transaction_line_portal_type + sale_invoice_transaction_line_item = self.newContent( + portal_type = self._transaction_line_portal_type , id = group_id , source = reference_movement.getSource() , destination = reference_movement.getDestination() @@ -156,11 +161,13 @@ class Invoice(AccountingTransaction): sale_invoice_transaction_line_item._setDestinationSection(reference_movement.getDestinationSection()) if self.getSourceSection() != reference_movement.getSourceSection(): sale_invoice_transaction_line_item._setSourceSection(reference_movement.getSourceSection()) + #LOG('buildInvoiceTransactionList sale_invoice_transaction_line',0,str(sale_invoice_transaction_line_item.showDict())) else : sale_invoice_transaction_line_item.edit( source = reference_movement.getSource() , destination = reference_movement.getDestination() , quantity = quantity + , force_update = 1 ) if self.getDestinationSection() != reference_movement.getDestinationSection(): sale_invoice_transaction_line_item._setDestinationSection(reference_movement.getDestinationSection()) @@ -200,7 +207,7 @@ class Invoice(AccountingTransaction): for rule in o.objectValues(): payment_transaction_rule_list.append(rule) simulation_line_list += rule.objectValues() - LOG('buildPaymentTransactionList simulation_line_list',0,simulation_line_list) + #LOG('buildPaymentTransactionList simulation_line_list',0,simulation_line_list) # create payment transaction accounting_module = self.accounting @@ -208,17 +215,15 @@ class Invoice(AccountingTransaction): payment_id = str(accounting_module.generateNewId()) payment_transaction = accounting_module.newContent(portal_type = payment_type , id = payment_id - , source = self.getSource() , reference = self.getReference() , resource = self.getResource() , start_date = self.getStartDate() , source_payment = self.getSourcePayment() , source_section = self.getSourceSection() - , destination = self.getDestination() , destination_payment = self.getDestinationPayment() , destination_section = self.getDestinationSection() ) - LOG('buildPaymentTransactionList payment_transaction', 0, repr(( payment_transaction ))) + #LOG('buildPaymentTransactionList payment_transaction', 0, repr(( payment_transaction.showDict() ))) # fill quantity in lines for movement in simulation_line_list : @@ -228,16 +233,25 @@ class Invoice(AccountingTransaction): payment_transaction_line = getattr(payment_transaction, movement_id, None) if payment_transaction_line is None : - payment_transaction.newContent(portal_type = 'Accounting Transaction Line' + payment_transaction.newContent( + portal_type = 'Accounting Transaction Line' , id = movement_id - , quantity = quantity ) + previous_quantity = 0.0 else : previous_quantity = payment_transaction_line.getQuantity() - if previous_quantity is not None: - quantity = quantity + previous_quantity - payment_transaction_line.setQuantity(quantity) + if previous_quantity is not None: + quantity = quantity + previous_quantity + payment_transaction_line.edit( + quantity = quantity + , source = movement.getSource() + , destination = movement.getDestination() + , force_update = 1 + ) + #LOG('buildPaymentTransactionList movement', 0, repr(( movement.showDict() ))) + #LOG('buildPaymentTransactionList payment_transaction_line', 0, repr(( payment_transaction_line.showDict() ))) + # What do we really need to update in the simulation movement ? if movement.getPortalType() == 'Simulation Movement' : movement._setDeliveryValue(payment_transaction_line) diff --git a/product/ERP5/Document/InvoicingRule.py b/product/ERP5/Document/InvoicingRule.py index 69356fc29a..870b462720 100755 --- a/product/ERP5/Document/InvoicingRule.py +++ b/product/ERP5/Document/InvoicingRule.py @@ -85,9 +85,7 @@ class InvoicingRule(Rule): my_context_movement = applied_rule.getParent() LOG('InvoicingRule.expand, my_context_movement.getPhysicalPath()',0,my_context_movement.getPhysicalPath()) LOG('InvoicingRule.expand, my_context_movement.getSource()',0,my_context_movement.getSource()) - LOG('InvoicingRule.expand, my_context_movement.getTargetSource()',0,my_context_movement.getTargetSource()) LOG('InvoicingRule.expand, my_context_movement.showDict()',0,my_context_movement.showDict()) - LOG('InvoicingRule.expand, my_context_movement.getSource',0,my_context_movement.getSource()) if my_context_movement.getSource() is not None: # We should only expand movements if they have a source # otherwise, it creates infinite recursion @@ -106,16 +104,16 @@ class InvoicingRule(Rule): resource = my_context_movement.getResource() invoice_line._edit( price = my_context_movement.getPrice(), - target_quantity = my_context_movement.getTargetQuantity(), - target_efficiency = my_context_movement.getTargetEfficiency(), + quantity = my_context_movement.getQuantity(), + efficiency = my_context_movement.getEfficiency(), resource = resource, - target_start_date = my_context_movement.getTargetStartDate(), - target_stop_date = my_context_movement.getTargetStartDate(), - target_source = my_context_movement.getTargetDestination(), - target_source_section = my_context_movement.getTargetSourceSection(), + start_date = my_context_movement.getStartDate(), + stop_date = my_context_movement.getStartDate(), + source = my_context_movement.getDestination(), + source_section = my_context_movement.getSourceSection(), quantity_unit = my_context_movement.getQuantityUnit(), - target_destination = my_context_movement.getTargetDestination(), - target_destination_section = my_context_movement.getTargetDestinationSection(), + destination = my_context_movement.getDestination(), + destination_section = my_context_movement.getDestinationSection(), deliverable = 1 # We do need to collect invoice lines to build invoices ) # transformation_source.setVariationCategoryList( diff --git a/product/ERP5/Document/Movement.py b/product/ERP5/Document/Movement.py index bd5e4e9021..76100b3d1e 100755 --- a/product/ERP5/Document/Movement.py +++ b/product/ERP5/Document/Movement.py @@ -269,14 +269,6 @@ a service in a public administration).""" else: return None - def _getTargetTotalPrice(self, context): - price = self.getPrice(context=context) - quantity = self.getTargetQuantity() - if type(price) in (type(1.0), type(1)) and type(quantity) in (type(1.0), type(1)): - return quantity * price - else: - return None - security.declareProtected(Permissions.AccessContentsInformation, 'getPrice') def getPrice(self, context=None, REQUEST=None, **kw): """ @@ -295,12 +287,6 @@ a service in a public administration).""" """ return self._getTotalPrice(self.asContext(context=context, REQUEST=REQUEST, **kw)) - security.declareProtected(Permissions.AccessContentsInformation, 'getTargetTotalPrice') - def getTargetTotalPrice(self, context=None, REQUEST=None, **kw): - """ - """ - return self._getTargetTotalPrice(self.asContext(context=context, REQUEST=REQUEST, **kw)) - security.declareProtected(Permissions.AccessContentsInformation, 'getTotalQuantity') def getTotalQuantity(self): """ @@ -308,13 +294,6 @@ a service in a public administration).""" """ return self.getQuantity() - security.declareProtected(Permissions.AccessContentsInformation, 'getTargetTotalQuantity') - def getTargetTotalQuantity(self): - """ - Returns the quantity if no cell or the total quantity if cells - """ - return self.getTargetQuantity() - # Industrial price API security.declareProtected(Permissions.AccessContentsInformation, 'getIndustrialPrice') def getIndustrialPrice(self): @@ -418,3 +397,155 @@ a service in a public administration).""" security.declareProtected(Permissions.View, 'isSimulated') def isSimulated(self): return len(self.getDeliveryRelatedValueList()) > 0 or len(self.getOrderRelatedValueList()) > 0 + + # New Causality API + security.declareProtected(Permissions.AccessContentsInformation, 'getOrderQuantity') + def getOrderQuantity(self): + """ + Returns the quantity of related order(s) + """ + return self.getQuantity() + + security.declareProtected(Permissions.AccessContentsInformation, 'getDeliveryQuantity') + def getDeliveryQuantity(self): + """ + Returns the quantity of related delivery(s) + """ + return self.getQuantity() + + security.declareProtected(Permissions.AccessContentsInformation, 'getSimulationQuantity') + def getSimulationQuantity(self): + """ + Returns the sum of quantities in related simulation movements + """ + return self.getQuantity() + + security.declareProtected(Permissions.AccessContentsInformation, 'getOrderStartDateList') + def getOrderStartDateList(self): + """ + Returns the start date of related order(s) + """ + return [self.getStartDate()] + + security.declareProtected(Permissions.AccessContentsInformation, 'getDeliveryStartDateList') + def getDeliveryStartDateList(self): + """ + Returns the start date of related delivery(s) + """ + return [self.getStartDate()] + + security.declareProtected(Permissions.AccessContentsInformation, 'getSimulationStartDateList') + def getSimulationStartDateList(self): + """ + Returns the of start date related simulation movements + """ + return [self.getStartDate()] + + security.declareProtected(Permissions.AccessContentsInformation, 'getOrderStopDateList') + def getOrderStopDateList(self): + """ + Returns the stop date of related order(s) + """ + return [self.getStopDate()] + + security.declareProtected(Permissions.AccessContentsInformation, 'getDeliveryStopDateList') + def getDeliveryStopDateList(self): + """ + Returns the stop date of related delivery(s) + """ + return [self.getStopDate()] + + security.declareProtected(Permissions.AccessContentsInformation, 'getSimulationStopDateList') + def getSimulationStopDateList(self): + """ + Returns the of stop date related simulation movements + """ + return [self.getStopDate()] + + security.declareProtected(Permissions.AccessContentsInformation, 'getOrderSourceList') + def getOrderSourceList(self): + """ + Returns the source of related orders + """ + return self.getSourceList() + + security.declareProtected(Permissions.AccessContentsInformation, 'getDeliverySourceList') + def getDeliverySourceList(self): + """ + Returns the source of related deliveries + """ + return self.getSourceList() + + security.declareProtected(Permissions.AccessContentsInformation, 'getSimulationSourceList') + def getSimulationSourceList(self): + """ + Returns the source of related simulation movements + """ + return self.getSourceList() + + security.declareProtected(Permissions.AccessContentsInformation, 'getOrderDestinationList') + def getOrderDestinationList(self): + """ + Returns the destination of related orders + """ + return self.getDestinationList() + + security.declareProtected(Permissions.AccessContentsInformation, 'getDeliveryDestinationList') + def getDeliveryDestinationList(self): + """ + Returns the destination of related deliveries + """ + return self.getDestinationList() + + security.declareProtected(Permissions.AccessContentsInformation, 'getSimulationDestinationList') + def getSimulationDestinationList(self): + """ + Returns the destination of related simulation movements + """ + return self.getDestinationList() + + security.declareProtected(Permissions.AccessContentsInformation, 'getOrderSourceSectionList') + def getOrderSourceSectionList(self): + """ + Returns the source_section of related orders + """ + return self.getSourceSectionList() + + security.declareProtected(Permissions.AccessContentsInformation, 'getDeliverySourceSectionList') + def getDeliverySourceSectionList(self): + """ + Returns the source_section of related deliveries + """ + return self.getSourceSectionList() + + security.declareProtected(Permissions.AccessContentsInformation, 'getSimulationSourceSectionList') + def getSimulationSourceSectionList(self): + """ + Returns the source_section of related simulation movements + """ + return self.getSourceSectionList() + + security.declareProtected(Permissions.AccessContentsInformation, 'getOrderDestinationSectionList') + def getOrderDestinationSectionList(self): + """ + Returns the destination_section of related orders + """ + return self.getDestinationSectionList() + + security.declareProtected(Permissions.AccessContentsInformation, 'getDeliveryDestinationSectionList') + def getDeliveryDestinationSectionList(self): + """ + Returns the destination_section of related deliveries + """ + return self.getDestinationSectionList() + + security.declareProtected(Permissions.AccessContentsInformation, 'getSimulationDestinationSectionList') + def getSimulationDestinationSectionList(self): + """ + Returns the destination_section of related simulation movements + """ + return self.getDestinationSectionList() + + + + \ No newline at end of file diff --git a/product/ERP5/Document/OrderLine.py b/product/ERP5/Document/OrderLine.py index 497dba9b03..df3dda9185 100755 --- a/product/ERP5/Document/OrderLine.py +++ b/product/ERP5/Document/OrderLine.py @@ -151,7 +151,7 @@ Une ligne tarifaire.""" c = self.newCell(*k, **kwd) #LOG('OrderLine _setVariationCategoryList', 0, 'k = %s, c = %s, self.getVariationBaseCategoryList() = %s' % (repr(k), repr(c), repr(self.getVariationBaseCategoryList()))) c.edit( domain_base_category_list = self.getVariationBaseCategoryList(), - mapped_value_property_list = ('target_quantity', 'price',), + mapped_value_property_list = ('quantity', '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), @@ -168,7 +168,7 @@ Une ligne tarifaire.""" self._delObject(k) security.declarePrivate('_checkConsistency') - def _checkConsistency(self, fixit=0, mapped_value_property_list = ('target_quantity', 'price')): + def _checkConsistency(self, fixit=0, mapped_value_property_list = ('quantity', 'price')): """ Check the constitency of transformation elements """ @@ -211,20 +211,11 @@ Une ligne tarifaire.""" self.aq_parent.activate()._createOrderRule() # Simulation Consistency Check - def getRelatedQuantity(self): - """ - Computes the quantities in the simulation - """ - result = self.OrderLine_zGetRelatedQuantity(uid=self.getUid()) - if len(result) > 0: - return result[0].quantity - return None - - def getRelatedTargetQuantity(self): + def getSimulationQuantity(self): """ Computes the target quantities in the simulation """ result = self.OrderLine_zGetRelatedQuantity(uid=self.getUid()) if len(result) > 0: - return result[0].target_quantity + return result[0].quantity return None diff --git a/product/ERP5/Document/OrderRule.py b/product/ERP5/Document/OrderRule.py index 8f5da5331e..cf7d4509dc 100755 --- a/product/ERP5/Document/OrderRule.py +++ b/product/ERP5/Document/OrderRule.py @@ -146,7 +146,7 @@ An ERP5 Rule...""" # eventually delete movement which do not exist anylonger existing_uid_list = [] for movement in applied_rule.contentValues(filter={'portal_type':applied_rule.getPortalMovementTypeList()}): - #LOG('Movement', 0, str(movement)) + LOG('Movement', 0, str(movement)) order_value = movement.getOrderValue(portal_type=applied_rule.getPortalOrderMovementTypeList()) if order_value is None: movement.flushActivity(invoke=0) @@ -156,7 +156,7 @@ An ERP5 Rule...""" existing_uid_list += [order_value.getUid()] elif order_value.hasCellContent(): # Do not keep head of cells - #LOG('INFO', 0, 'Order Rule Deleting Simulatino Movement %s' % movement.getRelativeUrl()) + LOG('INFO', 0, 'Order Rule Deleting Simulatino Movement %s' % movement.getRelativeUrl()) order_value.flushActivity(invoke=0) applied_rule._delObject(movement.getId()) # XXXX Make sur this is not deleted if already in delivery else: @@ -164,16 +164,22 @@ An ERP5 Rule...""" # Copy each movement (line or cell) from the order for order_line_object in my_order.contentValues(filter={'portal_type':applied_rule.getPortalMovementTypeList()}): + LOG('OrderRule.expand, examining:',0,order_line_object.getPhysicalPath()) try: if order_line_object.hasCellContent(): for c in order_line_object.getCellValueList(): - #LOG('Cell in', 0, '%s %s' % (c.getUid(), existing_uid_list)) + LOG('Cell in', 0, '%s %s' % (c.getUid(), existing_uid_list)) if c.getUid() not in existing_uid_list: new_id = order_line_object.getId() + '_' + c.getId() - #LOG('Create Cell', 0, str(new_id)) + LOG('Create Cell', 0, str(new_id)) new_line = applied_rule.newContent(type_name=delivery_line_type, id=new_id, order_value = c, + quantity = c.getQuantity(), + source = c.getSource(), + destination = c.getDestination(), + source_section = c.getSourceSection(), + destination_section = c.getDestinationSection(), deliverable = 1 ) LOG('OrderRule.expand, object created:',0,new_line.getPhysicalPath()) @@ -182,16 +188,21 @@ An ERP5 Rule...""" else: if order_line_object.getUid() not in existing_uid_list: new_id = order_line_object.getId() - #LOG('Line', 0, str(new_id)) + LOG('Line', 0, str(new_id)) new_line = applied_rule.newContent(type_name=delivery_line_type, container=applied_rule, id=new_id, order_value = order_line_object, + quantity = order_line_object.getQuantity(), + source = order_line_object.getSource(), + destination = order_line_object.getDestination(), + source_section = order_line_object.getSourceSection(), + destination_section = order_line_object.getDestinationSection(), deliverable = 1 ) LOG('OrderRule.expand, object created:',0,new_line.getPhysicalPath()) new_line.immediateReindexObject() - #LOG('After Create Cell', 0, str(new_id)) + LOG('After Create Cell', 0, str(new_id)) # Source, Destination, Quantity, Date, etc. are # acquired from the order and need not to be copied. except AttributeError: diff --git a/product/ERP5/Document/PaymentRule.py b/product/ERP5/Document/PaymentRule.py index 6439d40190..6a91a7141d 100755 --- a/product/ERP5/Document/PaymentRule.py +++ b/product/ERP5/Document/PaymentRule.py @@ -69,7 +69,7 @@ class PaymentRule(Rule): if 'receivable' in movement.getId() : parent = movement.getParent() if parent.getPortalType()=='Applied Rule' and parent.getSpecialiseId()=='default_invoice_transaction_rule': - LOG('PaymentRule.test :', 0, repr(( 'applies with', movement, parent ))) + #LOG('PaymentRule.test :', 0, repr(( 'applies with', movement, parent ))) return 1 return 0 @@ -103,9 +103,21 @@ class PaymentRule(Rule): type_name = payment_line_type, id = receivable_id) - bank_movement.setQuantity(my_parent_movement.getQuantity()) - receivable_movement.setQuantity(0 - my_parent_movement.getQuantity()) - + bank_movement.edit( + quantity = my_parent_movement.getQuantity(), + source = 'account/banques_etablissements_financiers', # XXX Not Generic + destination = 'account/banques_etablissements_financiers', # XXX Not Generic + source_section = my_parent_movement.getSourceSection(), + destination_section = my_parent_movement.getDestinationSection(), + ) + receivable_movement.edit( + quantity = - my_parent_movement.getQuantity(), + source = 'account/creance_client', # XXX Not Generic + destination = 'account/dette_fournisseur', # XXX Not Generic + source_section = my_parent_movement.getSourceSection(), + destination_section = my_parent_movement.getDestinationSection(), + ) + Rule.expand(self, applied_rule, **kw) diff --git a/product/ERP5/Document/PredicateGroup.py b/product/ERP5/Document/PredicateGroup.py index 773100fe8b..b6570d03d2 100755 --- a/product/ERP5/Document/PredicateGroup.py +++ b/product/ERP5/Document/PredicateGroup.py @@ -226,6 +226,7 @@ identify a bank account.""" membership_criterion_category_list = [] membership_criterion_base_category_list = [] multimembership_criterion_base_category_list = [] + test_method_id_list = [] criterion_property_list = [] for c in category_list: bc = c.split('/')[0] @@ -243,12 +244,14 @@ identify a bank account.""" predicate_value.getMembershipCriterionBaseCategoryList()) multimembership_criterion_base_category_list.extend( predicate_value.getMultimembershipCriterionBaseCategoryList()) + test_method_id_list += list(predicate_value.getTestMethodIdList() or []) for p in predicate_value.getCriterionList(): self.setCriterion(p.property, identity=p.identity, min=p.min, max=p.max) self.setCriterionPropertyList(criterion_property_list) - self.setMembershipCriterionCategoryList(membership_criterion_category_list) - self.setMembershipCriterionBaseCategoryList(membership_criterion_base_category_list) - self.setMultimembershipCriterionBaseCategoryList(multimembership_criterion_base_category_list) + self._setMembershipCriterionCategoryList(membership_criterion_category_list) + self._setMembershipCriterionBaseCategoryList(membership_criterion_base_category_list) + self._setMultimembershipCriterionBaseCategoryList(multimembership_criterion_base_category_list) + self._setTestMethodIdList(test_method_id_list) self.reindexObject() # Predicate handling diff --git a/product/ERP5/Document/SimulationMovement.py b/product/ERP5/Document/SimulationMovement.py index 7dc9a042e1..bfc83e7046 100755 --- a/product/ERP5/Document/SimulationMovement.py +++ b/product/ERP5/Document/SimulationMovement.py @@ -435,3 +435,18 @@ a service in a public administration).""" return 0 getDeliverable = isDeliverable + + # Simulation Dates - acquire target dates + security.declareProtected(Permissions.AccessContentsInformation, 'getOrderStartDate') + def getOrderStartDate(self): + order_value = self.getOrderValue() + if order_value is not None: + return order_value.getStartDate() + + security.declareProtected(Permissions.AccessContentsInformation, 'getOrderStopDate') + def getOrderStopDate(self): + order_value = self.getOrderValue() + if order_value is not None: + return order_value.getStopDate() + + \ No newline at end of file diff --git a/product/ERP5/Document/TransformationRule.py b/product/ERP5/Document/TransformationRule.py index a93d4d47d6..84169757b7 100755 --- a/product/ERP5/Document/TransformationRule.py +++ b/product/ERP5/Document/TransformationRule.py @@ -232,15 +232,15 @@ An ERP5 Rule...""" produced_resource = applied_rule[new_id] produced_resource._edit( - target_start_date = my_context_movement.getTargetStartDate(), - target_stop_date = my_context_movement.getTargetStartDate(), + start_date = my_context_movement.getStartDate(), + stop_date = my_context_movement.getStartDate(), resource = my_context_movement.getResource(), - target_quantity = my_context_movement.getTargetQuantity() + lost_quantity, - target_source_list = (), - target_source_section_list = (), + quantity = my_context_movement.getQuantity() + lost_quantity, + source_list = (), + source_section_list = (), quantity_unit = my_context_movement.getQuantityUnit(), - target_destination_section = production_section, - target_destination = production_node, + destination_section = production_section, + destination = production_node, deliverable = 1 ) # Mising quantity unit conversion for my_quantity !!!! XXXX @@ -270,15 +270,15 @@ An ERP5 Rule...""" if amount_line['quantity'] != 0.0: # Only create line if it is not 0.0 transformed_resource._edit( - target_start_date = my_context_movement.getTargetStartDate(), - target_stop_date = my_context_movement.getTargetStartDate(), - target_quantity = amount_line['quantity'] * my_quantity, - target_efficiency = amount_line['efficiency'], + start_date = my_context_movement.getStartDate(), + stop_date = my_context_movement.getStartDate(), + quantity = amount_line['quantity'] * my_quantity, + efficiency = amount_line['efficiency'], resource_value = amount_line['resource'], quantity_unit = amount_line['quantity_unit'], - target_source = production_node, - target_source_section = production_section, - target_destination_list = (), + source = production_node, + source_section = production_section, + destination_list = (), deliverable = 1 ) LOG('TransformationRule.expand transformed_resource.getPhysicalPath()',0,transformed_resource.getPhysicalPath()) diff --git a/product/ERP5/ERP5Defaults.py b/product/ERP5/ERP5Defaults.py index 61d4b0e6dc..9cf2b69ab0 100755 --- a/product/ERP5/ERP5Defaults.py +++ b/product/ERP5/ERP5Defaults.py @@ -140,7 +140,7 @@ portal_balance_transaction_line_type_list = ('Balance Transaction Line',) ## Inventory States portal_current_inventory_state_list = ('delivered', 'started', 'stopped', 'invoiced') # invoiced is Coramy specific and should be removed -portal_target_inventory_state_list = ('ready', 'delivered', 'started', 'stopped', 'invoiced') # if simulation_state in target_list, target_quantity should be considered instead of quantity for stock indexing +portal_target_inventory_state_list = ('ready', 'delivered', 'started', 'stopped', 'invoiced') # if simulation_state in target_list, target_quantity should be considered instead of quantity for stock indexing XXX why do we need two inventory_state_list ? portal_draft_order_state_list = ('cancelled', 'draft', 'auto_planned' ) portal_planned_order_state_list = ('planned', 'ordered', ) portal_reserved_inventory_state_list = ('confirmed', 'getting_ready', 'ready') diff --git a/product/ERP5/Extensions/InitializeAcquisition.py b/product/ERP5/Extensions/InitializeAcquisition.py index 70c4632b1a..19c443f887 100755 --- a/product/ERP5/Extensions/InitializeAcquisition.py +++ b/product/ERP5/Extensions/InitializeAcquisition.py @@ -9,9 +9,7 @@ def setBaseAcquisition(self): # we should not use causality here because of production reports # for which source or destination can be None (ie. different from Production Order) for bc in ('source', 'destination', - 'target_source', 'target_destination', - 'source_section', 'destination_section', - 'target_source_section', 'target_destination_section',): + 'source_section', 'destination_section',): if not hasattr(pc, bc): addBaseCategory(pc, bc) pc[bc].setAcquisitionBaseCategoryList(('delivery', 'order', 'parent', )) diff --git a/product/ERP5/MovementGroup.py b/product/ERP5/MovementGroup.py index 7df00e525f..609f0f9042 100755 --- a/product/ERP5/MovementGroup.py +++ b/product/ERP5/MovementGroup.py @@ -48,11 +48,11 @@ class RootMovementGroup: This sets an appropriate nested class. """ - LOG('RootGroup.setNestedClass, class_list:',0,class_list) + #LOG('RootGroup.setNestedClass, class_list:',0,class_list) for i in range(len(class_list)): - LOG('RootGroup.setNestedClass, class_list[i]:',0,class_list[i]) + #LOG('RootGroup.setNestedClass, class_list[i]:',0,class_list[i]) #LOG('RootGroup.setNestedClass, class_list[i].getId():',0,class_list[i].getId()) - LOG('RootGroup.setNestedClass, self.__class__:',0,self.__class__) + #LOG('RootGroup.setNestedClass, self.__class__:',0,self.__class__) if class_list[i] == self.__class__: break else: @@ -71,7 +71,7 @@ class RootMovementGroup: def appendGroup(self, movement,class_list=None): if self.nested_class is not None: - LOG('RootGroup.appendGroup, class_list',0,class_list) + #LOG('RootGroup.appendGroup, class_list',0,class_list) nested_instance = self.nested_class(movement=movement,class_list=class_list) self.group_list.append(nested_instance) @@ -84,7 +84,7 @@ class RootMovementGroup: movement_in_group = 1 break if movement_in_group == 0 : - LOG('RootGroup.append, class_list',0,class_list) + #LOG('RootGroup.append, class_list',0,class_list) self.appendGroup(movement,class_list=class_list) allow_class(RootMovementGroup) @@ -93,7 +93,7 @@ class OrderMovementGroup(RootMovementGroup): def __init__(self,movement,**kw): - LOG('OrderMovementGroup.__init__, kw:',0,kw) + #LOG('OrderMovementGroup.__init__, kw:',0,kw) RootMovementGroup.__init__(self,movement,**kw) if hasattr(movement, 'getRootAppliedRule'): # This is a simulation movement @@ -146,32 +146,20 @@ class PathMovementGroup(RootMovementGroup): def __init__(self,movement,**kw): RootMovementGroup.__init__(self,movement,**kw) self.source = movement.getSource() - LOG('PathGroup.__init__ source',0,self.source) + #LOG('PathGroup.__init__ source',0,self.source) self.destination = movement.getDestination() - LOG('PathGroup.__init__ destination',0,self.destination) + #LOG('PathGroup.__init__ destination',0,self.destination) self.source_section = movement.getSourceSection() - LOG('PathGroup.__init__ source_section',0,self.source_section) + #LOG('PathGroup.__init__ source_section',0,self.source_section) self.destination_section = movement.getDestinationSection() - LOG('PathGroup.__init__ destination_section',0,self.destination_section) - self.target_source = movement.getTargetSource() - LOG('PathGroup.__init__ target_source',0,self.target_source) - self.target_destination = movement.getTargetDestination() - LOG('PathGroup.__init__ target_destination',0,self.target_destination) - self.target_source_section = movement.getTargetSourceSection() - LOG('PathGroup.__init__ target_source_section',0,self.target_source_section) - self.target_destination_section = movement.getTargetDestinationSection() - LOG('PathGroup.__init__ target_destination_section',0,self.target_destination_section) + #LOG('PathGroup.__init__ destination_section',0,self.destination_section) def test(self,movement): if movement.getSource() == self.source and \ movement.getDestination() == self.destination and \ movement.getSourceSection() == self.source_section and \ - movement.getDestinationSection() == self.destination_section and \ - movement.getTargetSource() == self.target_source and \ - movement.getTargetDestination() == self.target_destination and \ - movement.getTargetSourceSection() == self.target_source_section and \ - movement.getTargetDestinationSection() == self.target_destination_section : + movement.getDestinationSection() == self.destination_section : return 1 else : @@ -183,8 +171,6 @@ class DateMovementGroup(RootMovementGroup): def __init__(self,movement,**kw): RootMovementGroup.__init__(self,movement,**kw) - self.target_start_date = movement.getTargetStartDate() - self.target_stop_date = movement.getTargetStopDate() self.start_date = movement.getStartDate() self.stop_date = movement.getStopDate() @@ -236,7 +222,7 @@ class BaseVariantMovementGroup(RootMovementGroup): RootMovementGroup.__init__(self,movement,**kw) self.base_category_list = movement.getVariationBaseCategoryList() if self.base_category_list is None: - LOG('BaseVariantGroup __init__', 0, 'movement = %s, movement.showDict() = %s' % (repr(movement), repr(movement.showDict()))) + #LOG('BaseVariantGroup __init__', 0, 'movement = %s, movement.showDict() = %s' % (repr(movement), repr(movement.showDict()))) self.base_category_list = [] def test(self,movement): @@ -245,7 +231,7 @@ class BaseVariantMovementGroup(RootMovementGroup): #LOG('BaseVariantGroup', 0, 'self.base_category_list = %s, movement = %s, movement.getVariationBaseCategoryList() = %s' % (repr(self.base_category_list), repr(movement), repr(movement.getVariationBaseCategoryList()))) movement_base_category_list = movement.getVariationBaseCategoryList() if movement_base_category_list is None: - LOG('BaseVariantGroup test', 0, 'movement = %s, movement.showDict() = %s' % (repr(movement), repr(movement.showDict()))) + #LOG('BaseVariantGroup test', 0, 'movement = %s, movement.showDict() = %s' % (repr(movement), repr(movement.showDict()))) movement_base_category_list = [] if len(self.base_category_list) == len(movement_base_category_list): for category in movement_base_category_list: @@ -263,7 +249,7 @@ class VariantMovementGroup(RootMovementGroup): RootMovementGroup.__init__(self,movement,**kw) self.category_list = movement.getVariationCategoryList() if self.category_list is None: - LOG('VariantGroup __init__', 0, 'movement = %s, movement.showDict() = %s' % (repr(movement), repr(movement.showDict()))) + #LOG('VariantGroup __init__', 0, 'movement = %s, movement.showDict() = %s' % (repr(movement), repr(movement.showDict()))) self.category_list = [] def test(self,movement): @@ -271,7 +257,7 @@ class VariantMovementGroup(RootMovementGroup): categories_identity = 0 movement_category_list = movement.getVariationCategoryList() if movement_category_list is None: - LOG('VariantGroup test', 0, 'movement = %s, movement.showDict() = %s' % (repr(movement), repr(movement.showDict()))) + #LOG('VariantGroup test', 0, 'movement = %s, movement.showDict() = %s' % (repr(movement), repr(movement.showDict()))) movement_category_list = [] if len(self.category_list) == len(movement_category_list): for category in movement_category_list: diff --git a/product/ERP5/PropertySheet/Amount.py b/product/ERP5/PropertySheet/Amount.py index 4e01d6e902..9c09f6ec0d 100755 --- a/product/ERP5/PropertySheet/Amount.py +++ b/product/ERP5/PropertySheet/Amount.py @@ -90,7 +90,6 @@ class Amount: 'acquisition_mask_value' : 1, 'acquisition_accessor_id' : 'getQuantity', 'acquisition_depends' : None, - 'alt_accessor_id' : ('getTargetQuantity', ), 'mode' : 'w' }, { 'id' : 'efficiency', 'description' : """The efficiency.""", @@ -102,34 +101,10 @@ class Amount: 'acquisition_mask_value' : 1, 'acquisition_accessor_id' : 'getEfficiency', 'acquisition_depends' : None, - 'alt_accessor_id' : ('getTargetEfficiency', ), #'get_adapter_id' : #'set_adapater_id' : #'has_adapater_id' : 'mode' : 'w' }, - # Planning - { 'id' : 'target_quantity', - 'description' : """The target quantity of resource.""", - 'type' : 'float', - 'default' : 0.0, - 'acquisition_base_category' : ('order',), - 'acquisition_portal_type' : Expression('python: portal.getPortalAcquisitionMovementTypeList() + portal.getPortalOrderTypeList()'), - 'acquisition_copy_value' : 0, - 'acquisition_mask_value' : 1, - 'acquisition_accessor_id' : 'getTargetQuantity', - 'acquisition_depends' : None, - 'mode' : 'w' }, - { 'id' : 'target_efficiency', - 'description' : """The target efficiency.""", - 'type' : 'float', - 'default' : 1.0, - 'acquisition_base_category' : ('order',), - 'acquisition_portal_type' : Expression('python: portal.getPortalAcquisitionMovementTypeList() + portal.getPortalOrderTypeList()'), - 'acquisition_copy_value' : 0, - 'acquisition_mask_value' : 1, - 'acquisition_accessor_id' : 'getTargetEfficiency', - 'acquisition_depends' : None, - 'mode' : 'w' }, # Profit and loss { 'id' : 'profit_quantity', 'description' : 'A quantity which represents generation of resource from nowhere', diff --git a/product/ERP5/PropertySheet/Arrow.py b/product/ERP5/PropertySheet/Arrow.py index efb9e6f6ea..56c611c126 100755 --- a/product/ERP5/PropertySheet/Arrow.py +++ b/product/ERP5/PropertySheet/Arrow.py @@ -135,108 +135,6 @@ class Arrow: 'acquisition_accessor_id' : 'getTitle', 'acquisition_depends' : None, 'mode' : 'r' }, - # Target Source reference - { 'id' : 'target_source_title', - 'description' : 'The title of the target source of this movement', - 'type' : 'string', - 'acquisition_base_category' : ('target_source',), - 'acquisition_portal_type' : Expression('python: portal.getPortalNodeTypeList()'), - 'acquisition_copy_value' : 0, - 'acquisition_accessor_id' : 'getTitle', - 'acquisition_depends' : None, - 'alt_accessor_id' : ('_categoryGetTargetSourceTitle', '_categoryGetSourceTitle'), - 'mode' : 'w' }, - { 'id' : 'target_source_id', - 'description' : 'The id of the target source of this movement', - 'type' : 'string', - 'acquisition_base_category' : ('target_source',), - 'acquisition_portal_type' : Expression('python: portal.getPortalNodeTypeList()'), - 'acquisition_copy_value' : 0, - 'acquisition_accessor_id' : 'getId', - 'acquisition_depends' : None, - 'alt_accessor_id' : ('_categoryGetTargetSourceId', '_categoryGetSourceId' ), - 'mode' : 'w' }, - { 'id' : 'target_source_relative_url', - 'description' : 'The relative url of the target destination of this movement', - 'type' : 'string', - 'acquisition_base_category' : ('target_source',), - 'acquisition_portal_type' : Expression('python: portal.getPortalNodeTypeList()'), - 'acquisition_copy_value' : 0, - 'acquisition_accessor_id' : 'getRelativeUrl', - 'acquisition_depends' : None, - 'alt_accessor_id' : ('_categoryGetTargetSourceRelativeUrl', '_categoryGetSourceRelativeUrl' ), - 'mode' : 'w' }, - { 'id' : 'target_source_person_title', - 'description' : 'The title of the target source person of this movement', - 'type' : 'string', - 'acquisition_base_category' : ('target_source',), - 'acquisition_portal_type' : ('Person'), - 'acquisition_copy_value' : 0, - 'acquisition_accessor_id' : 'getTitle', - 'acquisition_depends' : None, - 'alt_accessor_id' : ('getSourcePersonTitle', ), - 'mode' : 'r' }, - { 'id' : 'target_source_organisation_title', - 'description' : 'The title of the target source organisation of this movement', - 'type' : 'string', - 'acquisition_base_category' : ('target_source',), - 'acquisition_portal_type' : ('Organisation'), - 'acquisition_copy_value' : 0, - 'acquisition_accessor_id' : 'getTitle', - 'acquisition_depends' : None, - 'alt_accessor_id' : ('getSourceOrganisationTitle', ), - 'mode' : 'r' }, - # Destination reference - { 'id' : 'target_destination_title', - 'description' : 'The title of the target destination of this movement', - 'type' : 'string', - 'acquisition_base_category' : ('target_destination',), - 'acquisition_portal_type' : Expression('python: portal.getPortalNodeTypeList()'), - 'acquisition_copy_value' : 0, - 'acquisition_accessor_id' : 'getTitle', - 'acquisition_depends' : None, - 'alt_accessor_id' : ('_categoryGetTargetDestinationTitle', '_categoryGetDestinationTitle' ), - 'mode' : 'w' }, - { 'id' : 'target_destination_id', - 'description' : 'The id of the target destination of this movement', - 'type' : 'string', - 'acquisition_base_category' : ('target_destination',), - 'acquisition_portal_type' : Expression('python: portal.getPortalNodeTypeList()'), - 'acquisition_copy_value' : 0, - 'acquisition_accessor_id' : 'getId', - 'acquisition_depends' : None, - 'alt_accessor_id' : ('_categoryGetTargetDestinationId', '_categoryGetDestinationId' ), - 'mode' : 'w' }, - { 'id' : 'target_destination_relative_url', - 'description' : 'The relative url of the target destination of this movement', - 'type' : 'string', - 'acquisition_base_category' : ('target_destination',), - 'acquisition_portal_type' : Expression('python: portal.getPortalNodeTypeList()'), - 'acquisition_copy_value' : 0, - 'acquisition_accessor_id' : 'getRelativeUrl', - 'acquisition_depends' : None, - 'alt_accessor_id' : ('_categoryGetTargetDestinationRelativeUrl', '_categoryGetDestinationRelativeUrl' ), - 'mode' : 'w' }, - { 'id' : 'target_destination_person_title', - 'description' : 'The title of the target destination person of this movement', - 'type' : 'string', - 'acquisition_base_category' : ('target_destination',), - 'acquisition_portal_type' : ('Person'), - 'acquisition_copy_value' : 0, - 'acquisition_accessor_id' : 'getTitle', - 'acquisition_depends' : None, - 'alt_accessor_id' : ('getDestinationPersonTitle', ), - 'mode' : 'r' }, - { 'id' : 'target_destination_organisation_title', - 'description' : 'The title of the target destination organisation of this movement', - 'type' : 'string', - 'acquisition_base_category' : ('target_destination',), - 'acquisition_portal_type' : ('Organisation'), - 'acquisition_copy_value' : 0, - 'acquisition_accessor_id' : 'getTitle', - 'acquisition_depends' : None, - 'alt_accessor_id' : ('getDestinationOrganisationTitle', ), - 'mode' : 'r' }, # Source decision reference { 'id' : 'source_decision_title', 'description' : 'The title of the source decision of this movement', @@ -361,68 +259,6 @@ class Arrow: 'acquisition_depends' : None, 'alt_accessor_id' : ('_categoryGetDestinationSectionRelativeUrl', ), 'mode' : 'w' }, - # Source section reference - { 'id' : 'target_source_section_title', - 'description' : 'The title of the target source section of this movement', - 'type' : 'string', - 'acquisition_base_category' : ('target_source_section',), - 'acquisition_portal_type' : Expression('python: portal.getPortalNodeTypeList()'), - 'acquisition_copy_value' : 0, - 'acquisition_accessor_id' : 'getTitle', - 'acquisition_depends' : None, - 'alt_accessor_id' : ('_categoryGetTargetSourceSectionTitle', '_categoryGetSourceSectionTitle' ), - 'mode' : 'w' }, - { 'id' : 'target_source_section_id', - 'description' : 'The id of the target source section of this movement', - 'type' : 'string', - 'acquisition_base_category' : ('target_source_section',), - 'acquisition_portal_type' : Expression('python: portal.getPortalNodeTypeList()'), - 'acquisition_copy_value' : 0, - 'acquisition_accessor_id' : 'getId', - 'acquisition_depends' : None, - 'alt_accessor_id' : ('_categoryGetTargetSourceSectionId', '_categoryGetSourceSectionId' ), - 'mode' : 'w' }, - { 'id' : 'target_source_section_relative_url', - 'description' : 'The relative url of the target source section of this movement', - 'type' : 'string', - 'acquisition_base_category' : ('target_source_section',), - 'acquisition_portal_type' : Expression('python: portal.getPortalNodeTypeList()'), - 'acquisition_copy_value' : 0, - 'acquisition_accessor_id' : 'getRelativeUrl', - 'acquisition_depends' : None, - 'alt_accessor_id' : ('_categoryGetTargetSourceSectionRelativeUrl', '_categoryGetSourceSectionRelativeUrl' ), - 'mode' : 'w' }, - # Destination section reference - { 'id' : 'target_destination_section_title', - 'description' : 'The title of the target destination section of this movement', - 'type' : 'string', - 'acquisition_base_category' : ('target_destination_section',), - 'acquisition_portal_type' : Expression('python: portal.getPortalNodeTypeList()'), - 'acquisition_copy_value' : 0, - 'acquisition_accessor_id' : 'getTitle', - 'acquisition_depends' : None, - 'alt_accessor_id' : ('_categoryGetTargetDestinationSectionTitle', '_categoryGetDestinationSectionTitle' ), - 'mode' : 'w' }, - { 'id' : 'target_destination_section_id', - 'description' : 'The id of the target destination section of this movement', - 'type' : 'string', - 'acquisition_base_category' : ('target_destination_section',), - 'acquisition_portal_type' : Expression('python: portal.getPortalNodeTypeList()'), - 'acquisition_copy_value' : 0, - 'acquisition_accessor_id' : 'getId', - 'acquisition_depends' : None, - 'alt_accessor_id' : ('_categoryGetTargetDestinationSectionId', '_categoryGetDestinationSectionId'), - 'mode' : 'w' }, - { 'id' : 'target_destination_section_relative_url', - 'description' : 'The relative url of the target destination section of this movement', - 'type' : 'string', - 'acquisition_base_category' : ('target_destination_section',), - 'acquisition_portal_type' : Expression('python: portal.getPortalNodeTypeList()'), - 'acquisition_copy_value' : 0, - 'acquisition_accessor_id' : 'getRelativeUrl', - 'acquisition_depends' : None, - 'alt_accessor_id' : ('_categoryGetTargetDestinationSectionRelativeUrl', '_categoryGetDestinationSectionRelativeUrl' ), - 'mode' : 'w' }, # Source administration reference { 'id' : 'source_administration_title', 'description' : 'The title of the source administration of this movement', @@ -711,9 +547,7 @@ class Arrow: ) _categories = ( 'source', 'destination', - 'target_source', 'target_destination', 'source_section', 'destination_section', - 'target_source_section', 'target_destination_section', 'source_decision', 'destination_decision', 'source_administration', 'destination_administration', 'source_payment', 'destination_payment', diff --git a/product/ERP5/PropertySheet/Inventory.py b/product/ERP5/PropertySheet/Inventory.py index bf82df01ce..1457e7a357 100755 --- a/product/ERP5/PropertySheet/Inventory.py +++ b/product/ERP5/PropertySheet/Inventory.py @@ -50,23 +50,12 @@ class Inventory: 'acquisition_mask_value' : 1, 'acquisition_accessor_id' : 'getInventory', 'acquisition_depends' : None, - 'alt_accessor_id' : ('getTargetInventory', ), 'mode' : 'w' }, { 'id' : 'inventory_efficiency', 'description' : """The efficiency of the inventory. 1.0 is perfect.""", 'type' : 'float', 'default' : None, 'mode' : 'w' }, - { 'id' : 'target_inventory', - 'description' : """The quantity of items in stock after inventory.""", - 'type' : 'float', - 'default' : None, - 'mode' : 'w' }, - { 'id' : 'target_inventory_efficiency', - 'description' : """The efficiency of the inventory. 1.0 is perfect.""", - 'type' : 'float', - 'default' : None, - 'mode' : 'w' }, ) _categories = () diff --git a/product/ERP5/PropertySheet/Predicate.py b/product/ERP5/PropertySheet/Predicate.py index 804f5e23a8..6a2153d37d 100755 --- a/product/ERP5/PropertySheet/Predicate.py +++ b/product/ERP5/PropertySheet/Predicate.py @@ -65,12 +65,12 @@ class Predicate: 'mode' : 'w' }, { 'id' : 'test_method_id', 'description' : 'A python method to implement additional tests', - 'type' : 'string', - 'mode' : 'w' }, - { 'id' : 'parameter_string', - 'description' : 'A string defining default values for parameters (python syntax)', - 'type' : 'string', + 'type' : 'lines', # Only a list of method ids is feasable for lines 'mode' : 'w' }, + #{ 'id' : 'parameter_string', # XXX Not feasable for AND + # 'description' : 'A string defining default values for parameters (python syntax)', + # 'type' : 'string', + # 'mode' : 'w' }, # Compatibility with legacy implementation # { 'id' : 'predicate_property', # 'description' : 'The properties to use for the predicate', diff --git a/product/ERP5/TargetSolver/CopyToTarget.py b/product/ERP5/TargetSolver/CopyToTarget.py index eaa865a0b8..111730eb2b 100755 --- a/product/ERP5/TargetSolver/CopyToTarget.py +++ b/product/ERP5/TargetSolver/CopyToTarget.py @@ -44,10 +44,10 @@ class CopyToTarget(TargetSolver): Adopt values as new target """ # Reduce quantity - movement.setTargetQuantity(new_target.target_quantity) + movement.setQuantity(new_target.target_quantity) # Change dates - movement.setTargetStartDate(new_target.target_start_date) - movement.setTargetStopDate(new_target.target_stop_date) + movement.setStartDate(new_target.target_start_date) + movement.setStopDate(new_target.target_stop_date) def close(self): """ diff --git a/product/ERP5/Tool/SimulationTool.py b/product/ERP5/Tool/SimulationTool.py index c2ccdf782c..b6944b7108 100755 --- a/product/ERP5/Tool/SimulationTool.py +++ b/product/ERP5/Tool/SimulationTool.py @@ -286,18 +286,12 @@ class SimulationTool (BaseTool): self.portal_types.constructContent(type_name = delivery_type, container = delivery_module, id = new_delivery_id, - target_start_date = date_group.start_date, - target_stop_date = date_group.stop_date, start_date = date_group.start_date, stop_date = date_group.stop_date, source = path_group.source, destination = path_group.destination, source_section = path_group.source_section, destination_section = path_group.destination_section, - target_source = path_group.source, - target_destination = path_group.destination, - target_source_section = path_group.source_section, - target_destination_section = path_group.destination_section, description = of_description, title = new_delivery_id ) @@ -335,7 +329,7 @@ class SimulationTool (BaseTool): # IMPORTANT : delivery cells are automatically created during setVariationCategoryList - # update target_quantity for each delivery_cell + # update quantity for each delivery_cell for variant_group in resource_group.group_list : #LOG('Variant_group examin',0,str(variant_group.category_list)) object_to_update = None @@ -364,16 +358,15 @@ class SimulationTool (BaseTool): object_to_update = delivery_cell break - # compute target_quantity, quantity and price for delivery_cell or delivery_line and + # compute quantity and price for delivery_cell or delivery_line and # build relation between simulation_movement and delivery_cell or delivery_line if object_to_update is not None : - cell_target_quantity = 0 + cell_quantity = 0 for movement in variant_group.movement_list : - cell_target_quantity += movement.getConvertedTargetQuantity() + cell_quantity += movement.getConvertedQuantity() # We do not create a relation or modifu anything # since planification of this movement will create new applied rule - object_to_update.edit(target_quantity = cell_target_quantity, - quantity = cell_target_quantity, + object_to_update.edit(quantity = cell_quantity, force_update = 1) return order_list @@ -448,27 +441,27 @@ class SimulationTool (BaseTool): else: # if path is internal ??? # JPS NEW - if path_group.target_source is None or path_group.target_destination is None: + if path_group.source is None or path_group.destination is None: # Production Path - LOG("Builder",0, "Strange Path %s " % path_group.target_source) - LOG("Builder",0, "Strange Path %s " % path_group.target_destination) + LOG("Builder",0, "Strange Path %s " % path_group.source) + LOG("Builder",0, "Strange Path %s " % path_group.destination) LOG("Builder path_group in pathGroupProcessing",0, path_group.__dict__) - if path_group.target_source is None or path_group.target_destination is None: + if path_group.source is None or path_group.destination is None: pass #delivery_module = self.rapport_fabrication #delivery_type = 'Production Report' #delivery_line_type = 'Production Report Line' #delivery_cell_type = 'Production Report Cell' - elif path_group.target_destination.find('site/Stock_PF') >= 0 and \ - path_group.target_source.find('site/Piquage') >= 0: + elif path_group.destination.find('site/Stock_PF') >= 0 and \ + path_group.source.find('site/Piquage') >= 0: delivery_module = self.livraison_fabrication delivery_type = 'Production Packing List' delivery_line_type = delivery_type + ' Line' delivery_cell_type = 'Delivery Cell' - elif path_group.target_source.find('site/Stock_MP') >= 0 and \ - path_group.target_destination.find('site/Piquage') >= 0: + elif path_group.source.find('site/Stock_MP') >= 0 and \ + path_group.destination.find('site/Piquage') >= 0: delivery_module = self.livraison_fabrication delivery_type = 'Production Packing List' delivery_line_type = delivery_type + ' Line' @@ -518,8 +511,6 @@ class SimulationTool (BaseTool): new_delivery_id = str(delivery_module.generateNewId()) accounting_transaction = delivery_module.newContent(portal_type = delivery_type, id = new_delivery_id, - target_start_date = date_group.start_date, - target_stop_date = date_group.stop_date, start_date = date_group.start_date, stop_date = date_group.stop_date, source_section = source_section, @@ -544,18 +535,12 @@ class SimulationTool (BaseTool): new_delivery_id = str(delivery_module.generateNewId()) delivery = delivery_module.newContent(type_name = delivery_type, id = new_delivery_id, - target_start_date = date_group.start_date, - target_stop_date = date_group.stop_date, start_date = date_group.start_date, stop_date = date_group.stop_date, source = path_group.source, destination = path_group.destination, source_section = path_group.source_section, destination_section = path_group.destination_section, - target_source = path_group.source, - target_destination = path_group.destination, - target_source_section = path_group.source_section, - target_destination_section = path_group.destination_section ) if order is not None : delivery.edit(title = order.getTitle(), @@ -628,7 +613,7 @@ class SimulationTool (BaseTool): # IMPORTANT : delivery cells are automatically created during setVariationCategoryList - # update target_quantity for each delivery_cell + # update quantity for each delivery_cell for variant_group in resource_group.group_list: #LOG('Variant_group examin?,0,str(variant_group.category_list)) object_to_update = None @@ -656,17 +641,17 @@ class SimulationTool (BaseTool): object_to_update = delivery_cell break - # compute target_quantity, quantity and price for delivery_cell or delivery_line and + # compute quantity, quantity and price for delivery_cell or delivery_line and # build relation between simulation_movement and delivery_cell or delivery_line if object_to_update is not None : - cell_target_quantity = 0 + cell_quantity = 0 cell_total_price = 0 for movement in variant_group.movement_list : LOG('SimulationTool, movement.getPhysicalPath',0,movement.getPhysicalPath()) LOG('SimulationTool, movement.showDict',0,movement.showDict()) - cell_target_quantity += movement.getNetConvertedTargetQuantity() + cell_quantity += movement.getNetConvertedQuantity() try: - cell_total_price += movement.getNetConvertedTargetQuantity()*movement.getPrice() # XXX WARNING - ADD PRICED QUANTITY + cell_total_price += movement.getNetConvertedQuantity()*movement.getPrice() # XXX WARNING - ADD PRICED QUANTITY except: cell_total_price = None @@ -674,34 +659,26 @@ class SimulationTool (BaseTool): # update every simulation_movement # we set delivery_value and target dates and quantity movement._setDeliveryValue(object_to_update) - movement._setTargetQuantity(movement.getTargetQuantity()) - movement._setQuantity(movement.getTargetQuantity()) - movement._setEfficiency(movement.getTargetEfficiency()) - movement._setTargetStartDate(movement.getTargetStartDate()) - movement._setTargetStopDate(movement.getTargetStopDate()) - movement._setStartDate(movement.getTargetStartDate()) - movement._setStopDate(movement.getTargetStopDate()) - movement._setSource(movement.getTargetSource()) - movement._setDestination(movement.getTargetDestination()) - movement._setTargetSource(movement.getTargetSource()) - movement._setTargetDestination(movement.getTargetDestination()) - movement._setSourceSection(movement.getTargetSourceSection()) - movement._setDestinationSection(movement.getTargetDestinationSection()) - movement._setTargetSourceSection(movement.getTargetSourceSection()) - movement._setTargetDestinationSection(movement.getTargetDestinationSection()) + movement._setQuantity(movement.getQuantity()) + movement._setEfficiency(movement.getEfficiency()) + movement._setStartDate(movement.getStartDate()) + movement._setStopDate(movement.getStopDate()) + movement._setSource(movement.getSource()) + movement._setDestination(movement.getDestination()) + movement._setSourceSection(movement.getSourceSection()) + movement._setDestinationSection(movement.getDestinationSection()) # We will reindex later reindexable_movement_list.append(movement) - if cell_target_quantity <> 0 and cell_total_price is not None: - average_price = cell_total_price/cell_target_quantity + if cell_quantity <> 0 and cell_total_price is not None: + average_price = cell_total_price/cell_quantity else : average_price = 0 #LOG('object mis à jour',0,str(object_to_update.getRelativeUrl())) - object_to_update._edit(target_quantity = cell_target_quantity, - quantity = cell_target_quantity, - price = average_price, - force_update = 1, + object_to_update._edit(quantity = cell_quantity, + price = average_price, + force_update = 1, ) @@ -795,8 +772,8 @@ class SimulationTool (BaseTool): # Get nodes and dat source_node = movement.getSourceValue() destination_node = movement.getDestinationValue() - start_date = movement.getTargetStartDate() - stop_date = movement.getTargetStopDate() + start_date = movement.getStartDate() + stop_date = movement.getStopDate() # Return result return self.isNodeInsideCapacity(source_node, start_date, additional_movement=movement, sign=1) and self.isNodeInsideCapacity(destination_node, stop_date, additional_movement=movement, sign=-1) @@ -1029,21 +1006,21 @@ class SimulationTool (BaseTool): asset_price = m.getIndustrialPrice() if asset_price is None: asset_price = current_asset_price # Use current price if no price defined result.append((m.getRelativeUrl(), m.getStartDate(), m.getSource(), m.getSourceSection(), m.getDestination(), m.getDestinationSection(), - m.getTargetQuantity(), 'Production or Inventory', 'Price: %s' % asset_price + m.getQuantity(), 'Production or Inventory', 'Price: %s' % asset_price )) elif m.getDestinationValue() is None: # This is a consumption movement or an inventory movement current_inventory += inventory_quantity # Update inventory asset_price = current_asset_price result.append((m.getRelativeUrl(),m.getStartDate(), m.getSource(), m.getSourceSection(), m.getDestination(), m.getDestinationSection(), - m.getTargetQuantity(), 'Consumption or Inventory', 'Price: %s' % asset_price + m.getQuantity(), 'Consumption or Inventory', 'Price: %s' % asset_price )) elif m.getSourceValue().isAcquiredMemberOf(node_category) and m.getDestinationValue().isAcquiredMemberOf(node_category): # This is an internal movement current_inventory += inventory_quantity # Update inventory asset_price = current_asset_price result.append((m.getRelativeUrl(),m.getStartDate(), m.getSource(), m.getSourceSection(), m.getDestination(), m.getDestinationSection(), - m.getTargetQuantity(), 'Internal', 'Price: %s' % asset_price + m.getQuantity(), 'Internal', 'Price: %s' % asset_price )) elif m.getSourceValue().isAcquiredMemberOf(node_category) and quantity < 0: # This is a physically inbound movement - try to use commercial price @@ -1052,14 +1029,14 @@ class SimulationTool (BaseTool): current_inventory += inventory_quantity # Update inventory asset_price = current_asset_price result.append((m.getRelativeUrl(),m.getStartDate(), m.getSource(), m.getSourceSection(), m.getDestination(), m.getDestinationSection(), - m.getTargetQuantity(), 'Error', 'Price: %s' % asset_price + m.getQuantity(), 'Error', 'Price: %s' % asset_price )) elif m.getDestinationSectionValue() is None: # No meaning current_inventory += inventory_quantity # Update inventory asset_price = current_asset_price result.append((m.getRelativeUrl(),m.getStartDate(), m.getSource(), m.getSourceSection(), m.getDestination(), m.getDestinationSection(), - m.getTargetQuantity(), 'Error', 'Price: %s' % asset_price + m.getQuantity(), 'Error', 'Price: %s' % asset_price )) elif m.getDestinationSectionValue().isAcquiredMemberOf(section_category): current_inventory += inventory_quantity # Update inventory @@ -1068,19 +1045,19 @@ class SimulationTool (BaseTool): asset_price = m.getIndustrialPrice() if asset_price is None: asset_price = current_asset_price # Use current price if no price defined result.append((m.getRelativeUrl(),m.getStartDate(), m.getSource(), m.getSourceSection(), m.getDestination(), m.getDestinationSection(), - m.getTargetQuantity(), 'Production', 'Price: %s' % asset_price + m.getQuantity(), 'Production', 'Price: %s' % asset_price )) else: # Inbound from same section asset_price = current_asset_price result.append((m.getRelativeUrl(),m.getStartDate(), m.getSource(), m.getSourceSection(), m.getDestination(), m.getDestinationSection(), - m.getTargetQuantity(), 'Inbound same section', 'Price: %s' % asset_price + m.getQuantity(), 'Inbound same section', 'Price: %s' % asset_price )) else: current_inventory += inventory_quantity # Update inventory asset_price = m.getPrice() result.append((m.getRelativeUrl(),m.getStartDate(), m.getSource(), m.getSourceSection(), m.getDestination(), m.getDestinationSection(), - m.getTargetQuantity(), 'Inbound different section', 'Price: %s' % asset_price + m.getQuantity(), 'Inbound different section', 'Price: %s' % asset_price )) elif m.getDestinationValue().isAcquiredMemberOf(node_category) and quantity > 0: # This is a physically inbound movement - try to use commercial price @@ -1089,14 +1066,14 @@ class SimulationTool (BaseTool): current_inventory += inventory_quantity # Update inventory asset_price = current_asset_price result.append((m.getRelativeUrl(),m.getStartDate(), m.getSource(), m.getSourceSection(), m.getDestination(), m.getDestinationSection(), - m.getTargetQuantity(), 'Error', 'Price: %s' % asset_price + m.getQuantity(), 'Error', 'Price: %s' % asset_price )) elif m.getDestinationSectionValue() is None: # No meaning current_inventory += inventory_quantity # Update inventory asset_price = current_asset_price result.append((m.getRelativeUrl(),m.getStartDate(), m.getSource(), m.getSourceSection(), m.getDestination(), m.getDestinationSection(), - m.getTargetQuantity(), 'Error', 'Price: %s' % asset_price + m.getQuantity(), 'Error', 'Price: %s' % asset_price )) elif m.getSourceSectionValue().isAcquiredMemberOf(section_category): current_inventory += inventory_quantity # Update inventory @@ -1105,26 +1082,26 @@ class SimulationTool (BaseTool): asset_price = m.getIndustrialPrice() if asset_price is None: asset_price = current_asset_price # Use current price if no price defined result.append((m.getRelativeUrl(),m.getStartDate(), m.getSource(), m.getSourceSection(), m.getDestination(), m.getDestinationSection(), - m.getTargetQuantity(), 'Production', 'Price: %s' % asset_price + m.getQuantity(), 'Production', 'Price: %s' % asset_price )) else: # Inbound from same section asset_price = current_asset_price result.append((m.getRelativeUrl(),m.getStartDate(), m.getSource(), m.getSourceSection(), m.getDestination(), m.getDestinationSection(), - m.getTargetQuantity(), 'Inbound same section', 'Price: %s' % asset_price + m.getQuantity(), 'Inbound same section', 'Price: %s' % asset_price )) else: current_inventory += inventory_quantity # Update inventory asset_price = m.getPrice() result.append((m.getRelativeUrl(),m.getStartDate(), m.getSource(), m.getSourceSection(), m.getDestination(), m.getDestinationSection(), - m.getTargetQuantity(), 'Inbound different section', 'Price: %s' % asset_price + m.getQuantity(), 'Inbound different section', 'Price: %s' % asset_price )) else: # Outbound movement current_inventory += inventory_quantity # Update inventory asset_price = current_asset_price result.append((m.getRelativeUrl(),m.getStartDate(), m.getSource(), m.getSourceSection(), m.getDestination(), m.getDestinationSection(), - m.getTargetQuantity(), 'Outbound', 'Price: %s' % asset_price + m.getQuantity(), 'Outbound', 'Price: %s' % asset_price )) # Update asset_price @@ -1335,7 +1312,7 @@ class SimulationTool (BaseTool): if object_to_update is not None: cell_price = object_to_update.getPrice() or 0.0 cell_quantity = object_to_update.getQuantity() or 0.0 - cell_target_quantity = object_to_update.getNetConvertedTargetQuantity() or 0.0 + cell_target_quantity = object_to_update.getNetConvertedTargetQuantity() or 0.0 # XXX What to do ? cell_total_price = cell_target_quantity * cell_price cell_category_list = list(object_to_update.getCategoryList()) diff --git a/product/ERP5/tests/testInvoice.py b/product/ERP5/tests/testInvoice.py index 1d608d7275..0fff5e48bb 100755 --- a/product/ERP5/tests/testInvoice.py +++ b/product/ERP5/tests/testInvoice.py @@ -82,9 +82,12 @@ class Test(ERP5TypeTestCase): account1 = 'prestation_service' account2 = 'creance_client' account3 = 'tva_collectee_196' - quantity1 = 3 - price1 = 72 - total_price1 = 216 + account1_mirror = 'fourniture_service' # Not used + account2_mirror = 'dette_client' # Not used + account3_mirror = 'tva_collectee_196' # Not used + quantity1 = 3.0 + price1 = 72.0 + total_price1 = 216.0 def getTitle(self): return "Invoices" @@ -284,7 +287,7 @@ class Test(ERP5TypeTestCase): line1 = order.newContent(portal_type='Sale Order Line',id='1') product = sequence.get('product') line1.setResourceValue(product) - line1.setTargetQuantity(self.quantity1) + line1.setQuantity(self.quantity1) line1.setPrice(self.price1) sequence.edit(order=order) self.assertEquals(line1.getTotalPrice(),self.total_price1) @@ -321,7 +324,7 @@ class Test(ERP5TypeTestCase): rule_line = rule_line_list[0] sequence.edit(order_rule_line=rule_line) order_line = order_line_list[0] - self.assertEquals(rule_line.getTargetQuantity(),self.quantity1) + self.assertEquals(rule_line.getQuantity(),self.quantity1) self.assertEquals(rule_line.getPrice(),self.price1) self.assertEquals(rule_line.getOrderValue(),order_line) self.assertEquals(rule_line.getStartDate(),order_line.getStartDate()) @@ -342,7 +345,7 @@ class Test(ERP5TypeTestCase): rule_line = rule_line_list[0] sequence.edit(invoicing_rule_line=rule_line) product = sequence.get('product') - self.assertEquals(rule_line.getTargetQuantity(),self.quantity1) + self.assertEquals(rule_line.getQuantity(),self.quantity1) self.assertEquals(rule_line.getPrice(),self.price1) self.assertEquals(rule_line.getPortalType(),'Simulation Movement') self.assertEquals(rule_line.getResourceValue(), product) @@ -442,7 +445,7 @@ class Test(ERP5TypeTestCase): invoice = sequence.get('invoice') # It should be in a script inside the workflow - invoice.buildInvoiceTransactionList() + invoice.buildInvoiceTransactionList() def stepBuildPaymentTransactionList(self, sequence=None, sequence_list=None, **kw) : invoice = sequence.get('invoice') @@ -521,6 +524,7 @@ class Test(ERP5TypeTestCase): self.assertEquals(transaction_line.getQuantity(), 3 * 72 * 0.5) sequence.edit(invoice_transaction_line_receivable=transaction_line) elif transaction_line.getId() == 'collected_vat' : + simulation_movement = transaction_line.getDeliveryRelatedValueList()[0].getObject() self.assertEquals(transaction_line.getSourceValue(), self.getAccountModule()['tva_collectee_196']) # this is defined in SaleInvoiceTransaction_init in ERP5 skins. else : raise self.failureException @@ -538,6 +542,7 @@ class Test(ERP5TypeTestCase): invoice_transaction_line_receivable = sequence.get('invoice_transaction_line_receivable') for transaction_line in payment_transaction_line_list : + if transaction_line.getId() == 'receivable' : self.assertEquals(transaction_line.getSourceValue(), self.getAccountModule()['creance_client']) self.assertEquals(transaction_line.getQuantity(), 0 - invoice_transaction_line_receivable.getQuantity()) @@ -548,8 +553,14 @@ class Test(ERP5TypeTestCase): self.assertEquals(transaction_line.getSourceValue(), self.getAccountModule()['dette_fournisseur']) # this is defined in SaleInvoiceTransaction_init in ERP5 skins. else : raise self.failureException - - + + # Make sure payment and simulation are consistent + for simulation_movement in transaction_line.getDeliveryRelatedValueList(): + self.assertEquals(simulation_movement.getSource(), transaction_line.getSource()) + self.assertEquals(simulation_movement.getDestination(), transaction_line.getDestination()) + self.assertEquals(simulation_movement.getSourceSection(), transaction_line.getSourceSection()) + self.assertEquals(simulation_movement.getDestinationSection(), transaction_line.getDestinationSection()) + def testInvoice(self, quiet=0,run=1): """ We will play many sequences -- 2.30.9