From 6086c13180e51b7d2240531b6489ad0061ad702b Mon Sep 17 00:00:00 2001 From: Alexandre Boeglin <alex@nexedi.com> Date: Fri, 14 Mar 2008 16:20:14 +0000 Subject: [PATCH] * OrderCell.py: isMovement is now a function, depends on whether parent contains lines. getTotalPrice, getTotalQuantity return 0.0 if the current object is not considered a movement. * DeliveryLine.py (manage_afterAdd, manage_beforeDelete): when adding or removing a line from a line, reindex the parent, as its "isMovement" value might change. * OrderLine.py: _getTotalPrice, getTotalQuantity support hierarchical orders. * testOrder: test_19b_getTotalQuantityAndPrice verifies that isMovement, getTotalPrice, getTotalQuantity support hierarchical orders. git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@19922 20353a03-c40f-0410-a6d1-a30d3c3de9de --- product/ERP5/Document/DeliveryLine.py | 15 ++ product/ERP5/Document/OrderCell.py | 24 +++- product/ERP5/Document/OrderLine.py | 42 ++++++ product/ERP5/tests/testOrder.py | 196 +++++++++++++++++++++++++- 4 files changed, 274 insertions(+), 3 deletions(-) diff --git a/product/ERP5/Document/DeliveryLine.py b/product/ERP5/Document/DeliveryLine.py index f3306804d5..e0da6b812c 100644 --- a/product/ERP5/Document/DeliveryLine.py +++ b/product/ERP5/Document/DeliveryLine.py @@ -373,3 +373,18 @@ class DeliveryLine(Movement, XMLObject, XMLMatrix, Variated, parent = self.getParentValue() if parent is not None: parent.updateSimulationDeliveryProperties(movement_list, self) + + security.declarePrivate('manage_afterAdd') + def manage_afterAdd(self, item, container): + "if the container is a line too, reindex it" + if self.meta_type == container.meta_type: + container.reindexObject() + return Movement.manage_afterAdd(self, item, container) + + security.declarePrivate('manage_beforeDelete') + def manage_beforeDelete(self, item, container): + "if the container is a line too, reindex it" + if self.meta_type == container.meta_type: + container.reindexObject() + return Movement.manage_beforeDelete(self, item, container) + diff --git a/product/ERP5/Document/OrderCell.py b/product/ERP5/Document/OrderCell.py index 96844f71ef..b86cdff7d2 100644 --- a/product/ERP5/Document/OrderCell.py +++ b/product/ERP5/Document/OrderCell.py @@ -47,7 +47,6 @@ class OrderCell(DeliveryCell): meta_type = 'ERP5 Order Cell' portal_type = 'Order Cell' isCell = 1 - isMovement = 1 # Declarative security security = ClassSecurityInfo() @@ -74,3 +73,26 @@ class OrderCell(DeliveryCell): Reindex children and simulation """ self.recursiveReindexObject(*k,**kw) + + security.declareProtected(Permissions.AccessContentsInformation, + 'isMovement') + def isMovement(self): + """ + should be considered as a movement if the parent does not have sub lines + """ + return not self.getParentValue().hasLineContent() + + security.declareProtected(Permissions.AccessContentsInformation, + 'getTotalPrice') + def getTotalPrice(self, *args, **kw): + "only return a value if self is a movement" + if not self.isMovement(): return 0.0 + return DeliveryCell.getTotalPrice(self, *args, **kw) + + security.declareProtected(Permissions.AccessContentsInformation, + 'getTotalQuantity') + def getTotalQuantity(self, *args, **kw): + "only return a value if self is a movement" + if not self.isMovement(): return 0.0 + return DeliveryCell.getTotalQuantity(self, *args, **kw) + diff --git a/product/ERP5/Document/OrderLine.py b/product/ERP5/Document/OrderLine.py index 838684743b..e4f2e7636d 100644 --- a/product/ERP5/Document/OrderLine.py +++ b/product/ERP5/Document/OrderLine.py @@ -80,6 +80,48 @@ class OrderLine(DeliveryLine): transactional_variable[call_method_key] = result return result + def _getTotalPrice(self, context, fast=1): + """ + if hasLineContent: return sum of lines total price + if hasCellContent: return sum of cells total price + else: return quantity * price + """ + base_id = 'movement' + if self.hasLineContent(): + return sum(l.getTotalPrice() for l in + self.contentValues(meta_type=self.meta_type)) + elif self.hasCellContent(base_id=base_id): + if fast : # Use MySQL + aggregate = self.DeliveryLine_zGetTotal()[0] + return aggregate.total_price or 0.0 + return sum([ ( (cell.getQuantity() or 0) * + (cell.getPrice(context=context) or 0)) + for cell in self.getCellValueList()]) + else: + quantity = self.getQuantity() or 0.0 + price = self.getPrice(context=context) or 0.0 + return quantity * price + + security.declareProtected(Permissions.AccessContentsInformation, + 'getTotalQuantity') + def getTotalQuantity(self, fast=1): + """ + if hasLineContent: return sum of lines total quantity + if hasCellContent: return sum of cells total quantity + else: return quantity + """ + base_id = 'movement' + if self.hasLineContent(): + return sum(l.getTotalQuantity() for l in + self.contentValues(meta_type=self.meta_type)) + elif self.hasCellContent(base_id=base_id): + if fast : # Use MySQL + aggregate = self.DeliveryLine_zGetTotal()[0] + return aggregate.total_quantity or 0.0 + return sum([cell.getQuantity() for cell in self.getCellValueList()]) + else: + return self.getQuantity() + def applyToOrderLineRelatedMovement(self, portal_type='Simulation Movement', method_id = 'expand'): """ diff --git a/product/ERP5/tests/testOrder.py b/product/ERP5/tests/testOrder.py index 98bd8cc4d0..4f7236d851 100644 --- a/product/ERP5/tests/testOrder.py +++ b/product/ERP5/tests/testOrder.py @@ -1850,12 +1850,11 @@ class TestOrder(TestOrderMixin, ERP5TypeTestCase): def test_19_getMovementList(self, quiet=0, run=run_all_test): """ Check getMovementList. - Verify that it manage hierarchical order lines. + Verify that it supports hierarchical order lines. Check that order cells are returned when defined on a leaf line, and not returned when defined on a non leaf line. """ if not run: return - sequence_list = SequenceList() portal = self.getPortal() order_module = portal.getDefaultModule(portal_type=self.order_portal_type) @@ -1933,6 +1932,199 @@ class TestOrder(TestOrderMixin, ERP5TypeTestCase): *cell_key) self.assertEquals(2-1+len(cell_key_list), len(order.getMovementList())) + def test_19b_getTotalQuantityAndPrice(self, quiet=0, run=run_all_test): + """ + Check getTotalQuantity and getTotalPrice. + Check isMovement. + Verify that it supports hierarchical order lines. + Note that this depends on isMovement and Order Line reindexation + """ + if not run: return + + portal = self.getPortal() + base_id = 'movement' + order_line_vcl=['size/Baby'] + order_module = portal.getDefaultModule(portal_type=self.order_portal_type) + order = order_module.newContent(portal_type=self.order_portal_type) + + # No line, no movement + self.assertEquals(order.getTotalQuantity(fast=0), 0) + self.assertEquals(order.getTotalQuantity(fast=1), 0) + self.assertEquals(order.getTotalPrice(fast=0), 0) + self.assertEquals(order.getTotalPrice(fast=1), 0) + + # Create a variated resource + resource_module = portal.getDefaultModule(self.resource_portal_type) + resource = resource_module.newContent( + portal_type=self.resource_portal_type, + variation_base_category_list=['size'], + size_list=self.size_list) + + # One line is considered as a movement + order_line = order.newContent( + portal_type=self.order_line_portal_type, + resource_value=resource, + price=2, + quantity=3) + get_transaction().commit() + self.tic() + + self.assertEquals(order_line.isMovement(), True) + + self.assertEquals(order.getTotalQuantity(fast=0), 3) + self.assertEquals(order.getTotalQuantity(fast=1), 3) + self.assertEquals(order.getTotalPrice(fast=0), 6) + self.assertEquals(order.getTotalPrice(fast=1), 6) + + self.assertEquals(order_line.getTotalQuantity(fast=0), 3) + self.assertEquals(order_line.getTotalQuantity(fast=1), 3) + self.assertEquals(order_line.getTotalPrice(fast=0), 6) + self.assertEquals(order_line.getTotalPrice(fast=1), 6) + + # add cell to line, line is not a movement anymore + order_line.setVariationCategoryList(order_line_vcl) + cell_key = order_line.getCellKeyList(base_id=base_id)[0] + cell = order_line.newCell( + base_id=base_id, + portal_type=self.order_cell_portal_type, + *cell_key) + cell.edit(mapped_value_property_list=['price', 'quantity'], + price=3, quantity=4, + predicate_category_list=cell_key, + variation_category_list=cell_key) + get_transaction().commit() + self.tic() + + self.assertEquals(order_line.isMovement(), False) + self.assertEquals(cell.isMovement(), True) + + self.assertEquals(order.getTotalQuantity(fast=0), 4) + self.assertEquals(order.getTotalQuantity(fast=1), 4) + self.assertEquals(order.getTotalPrice(fast=0), 12) + self.assertEquals(order.getTotalPrice(fast=1), 12) + + self.assertEquals(order_line.getTotalQuantity(fast=0), 4) + self.assertEquals(order_line.getTotalQuantity(fast=1), 4) + self.assertEquals(order_line.getTotalPrice(fast=0), 12) + self.assertEquals(order_line.getTotalPrice(fast=1), 12) + + self.assertEquals(cell.getTotalQuantity(), 4) + self.assertEquals(cell.getTotalPrice(fast=0), 12) + self.assertEquals(cell.getTotalPrice(fast=1), 12) + + # add sub_line to line, cell and line are not movements + sub_order_line = order_line.newContent( + portal_type=self.order_line_portal_type, + price=4, + quantity=5) + get_transaction().commit() + self.tic() + + self.assertEquals(order_line.isMovement(), False) + self.assertEquals(cell.isMovement(), False) + self.assertEquals(sub_order_line.isMovement(), True) + + self.assertEquals(order.getTotalQuantity(fast=0), 5) + self.assertEquals(order.getTotalQuantity(fast=1), 5) + self.assertEquals(order.getTotalPrice(fast=0), 20) + self.assertEquals(order.getTotalPrice(fast=1), 20) + + self.assertEquals(order_line.getTotalQuantity(fast=0), 5) + self.assertEquals(order_line.getTotalQuantity(fast=1), 5) + self.assertEquals(order_line.getTotalPrice(fast=0), 20) + self.assertEquals(order_line.getTotalPrice(fast=1), 20) + + self.assertEquals(cell.getTotalQuantity(), 0) + self.assertEquals(cell.getTotalPrice(fast=0), 0) + self.assertEquals(cell.getTotalPrice(fast=1), 0) + + self.assertEquals(sub_order_line.getTotalQuantity(fast=0), 5) + self.assertEquals(sub_order_line.getTotalQuantity(fast=1), 5) + self.assertEquals(sub_order_line.getTotalPrice(fast=0), 20) + self.assertEquals(sub_order_line.getTotalPrice(fast=1), 20) + + # add sub_cell to sub_line, only sub_cell is movement + sub_order_line.setVariationCategoryList(order_line_vcl) + sub_cell_key = sub_order_line.getCellKeyList(base_id=base_id)[0] + sub_cell = sub_order_line.newCell( + base_id=base_id, + portal_type=self.order_cell_portal_type, + *cell_key) + sub_cell.edit(mapped_value_property_list=['price', 'quantity'], + price=5, quantity=6, + predicate_category_list=cell_key, + variation_category_list=cell_key) + get_transaction().commit() + self.tic() + + self.assertEquals(order_line.isMovement(), False) + self.assertEquals(cell.isMovement(), False) + self.assertEquals(sub_order_line.isMovement(), False) + self.assertEquals(sub_cell.isMovement(), True) + + self.assertEquals(order.getTotalQuantity(fast=0), 6) + self.assertEquals(order.getTotalQuantity(fast=1), 6) + self.assertEquals(order.getTotalPrice(fast=0), 30) + self.assertEquals(order.getTotalPrice(fast=1), 30) + + self.assertEquals(order_line.getTotalQuantity(fast=0), 6) + self.assertEquals(order_line.getTotalQuantity(fast=1), 6) + self.assertEquals(order_line.getTotalPrice(fast=0), 30) + self.assertEquals(order_line.getTotalPrice(fast=1), 30) + + self.assertEquals(cell.getTotalQuantity(), 0) + self.assertEquals(cell.getTotalPrice(fast=0), 0) + self.assertEquals(cell.getTotalPrice(fast=1), 0) + + self.assertEquals(sub_order_line.getTotalQuantity(fast=0), 6) + self.assertEquals(sub_order_line.getTotalQuantity(fast=1), 6) + self.assertEquals(sub_order_line.getTotalPrice(fast=0), 30) + self.assertEquals(sub_order_line.getTotalPrice(fast=1), 30) + + self.assertEquals(sub_cell.getTotalQuantity(), 6) + self.assertEquals(sub_cell.getTotalPrice(fast=0), 30) + self.assertEquals(sub_cell.getTotalPrice(fast=1), 30) + + # delete sub_line, cell is movement again + order_line.manage_delObjects([sub_order_line.getId()]) + get_transaction().commit() + self.tic() + + self.assertEquals(order_line.isMovement(), False) + self.assertEquals(cell.isMovement(), True) + + self.assertEquals(order.getTotalQuantity(fast=0), 4) + self.assertEquals(order.getTotalQuantity(fast=1), 4) + self.assertEquals(order.getTotalPrice(fast=0), 12) + self.assertEquals(order.getTotalPrice(fast=1), 12) + + self.assertEquals(order_line.getTotalQuantity(fast=0), 4) + self.assertEquals(order_line.getTotalQuantity(fast=1), 4) + self.assertEquals(order_line.getTotalPrice(fast=0), 12) + self.assertEquals(order_line.getTotalPrice(fast=1), 12) + + self.assertEquals(cell.getTotalQuantity(), 4) + self.assertEquals(cell.getTotalPrice(fast=0), 12) + self.assertEquals(cell.getTotalPrice(fast=1), 12) + + # delete cell, line is movement again + order_line.manage_delObjects([cell.getId()]) + order_line.setVariationCategoryList([]) + get_transaction().commit() + self.tic() + + self.assertEquals(order_line.isMovement(), True) + + self.assertEquals(order.getTotalQuantity(fast=0), 3) + self.assertEquals(order.getTotalQuantity(fast=1), 3) + self.assertEquals(order.getTotalPrice(fast=0), 6) + self.assertEquals(order.getTotalPrice(fast=1), 6) + + self.assertEquals(order_line.getTotalQuantity(fast=0), 3) + self.assertEquals(order_line.getTotalQuantity(fast=1), 3) + self.assertEquals(order_line.getTotalPrice(fast=0), 6) + self.assertEquals(order_line.getTotalPrice(fast=1), 6) + def stepCreateSubOrderLine(self,sequence=None, sequence_list=None, **kw): """ Create a empty order line -- 2.30.9