Commit ba1edb69 authored by Yusuke Muraoka's avatar Yusuke Muraoka

Add support for nested lines by Order/Delivery Builder.

Move getTotal* and related methods of OrderLine to DeliveryLine,
because nested lines would be used in delivery lines as well as order lines.


git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@25505 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent c11547c2
...@@ -263,16 +263,16 @@ class DeliveryBuilder(OrderBuilder): ...@@ -263,16 +263,16 @@ class DeliveryBuilder(OrderBuilder):
simulation_movement_list.append(simulation_movement) simulation_movement_list.append(simulation_movement)
# Collect # Collect
root_group = self.collectMovement(simulation_movement_list) root_group_node = self.collectMovement(simulation_movement_list)
# Build # Build
portal = self.getPortalObject() portal = self.getPortalObject()
delivery_module = getattr(portal, self.getDeliveryModule()) delivery_module = getattr(portal, self.getDeliveryModule())
delivery_to_update_list = [delivery] delivery_to_update_list = [delivery]
self._resetUpdated() self._resetUpdated()
delivery_list = self._deliveryGroupProcessing( delivery_list = self._processDeliveryGroup(
delivery_module, delivery_module,
root_group, root_group_node,
self.getDeliveryMovementGroupList(), self.getDeliveryMovementGroupList(),
delivery_to_update_list=delivery_to_update_list, delivery_to_update_list=delivery_to_update_list,
divergence_list=divergence_to_adopt_list, divergence_list=divergence_to_adopt_list,
......
...@@ -115,8 +115,19 @@ class DeliveryLine(Movement, XMLObject, XMLMatrix, Variated, ...@@ -115,8 +115,19 @@ class DeliveryLine(Movement, XMLObject, XMLMatrix, Variated,
return self.getParentValue().isAccountable() and (not self.hasCellContent()) return self.getParentValue().isAccountable() and (not self.hasCellContent())
def _getTotalPrice(self, default=0.0, context=None, fast=0): def _getTotalPrice(self, default=0.0, context=None, fast=0):
""" Returns the total price for this line or the cells it contains. """ """
if not self.hasCellContent(base_id='movement'): Returns the total price for this line, this line contains, or the cells it contains.
if hasLineContent: return sum of lines total price
if hasCellContent: return sum of cells total price
else: return quantity * price
if fast is argument true, then a SQL method will be used.
"""
if self.hasLineContent():
meta_type = self.meta_type
return sum(l.getTotalPrice(context=context)
for l in self.objectValues() if l.meta_type==meta_type)
elif not self.hasCellContent(base_id='movement'):
return Movement._getTotalPrice(self, default=default, context=context) return Movement._getTotalPrice(self, default=default, context=context)
elif fast: # Use MySQL elif fast: # Use MySQL
return self.DeliveryLine_zGetTotal()[0].total_price or 0.0 return self.DeliveryLine_zGetTotal()[0].total_price or 0.0
...@@ -129,18 +140,34 @@ class DeliveryLine(Movement, XMLObject, XMLMatrix, Variated, ...@@ -129,18 +140,34 @@ class DeliveryLine(Movement, XMLObject, XMLMatrix, Variated,
""" """
Returns the quantity if no cell or the total quantity if cells Returns the quantity if no cell or the total quantity if cells
If fast is equal to 0, we returns the right quantity even if hasLineContent: return sum of lines total quantity
if there is nothing into the catalog or the catalog is not if hasCellContent: return sum of cells total quantity
up to date else: return quantity
if fast argument is true, then a SQL method will be used.
""" """
base_id = 'movement' base_id = 'movement'
if not self.hasCellContent(base_id=base_id): if self.hasLineContent():
return self.getQuantity() meta_type = self.meta_type
else: return sum(l.getTotalQuantity() for l in
self.objectValues() if l.meta_type==meta_type)
elif self.hasCellContent(base_id=base_id):
if fast : # Use MySQL if fast : # Use MySQL
aggregate = self.DeliveryLine_zGetTotal()[0] aggregate = self.DeliveryLine_zGetTotal()[0]
return aggregate.total_quantity or 0.0 return aggregate.total_quantity or 0.0
return sum([cell.getQuantity() for cell in self.getCellValueList()]) return sum([cell.getQuantity() for cell in self.getCellValueList()])
else:
return self.getQuantity()
security.declareProtected(Permissions.AccessContentsInformation,
'hasLineContent')
def hasLineContent(self):
"""Return true if the object contains lines.
This method only checks the first sub line because all sub
lines should be same meta type in reality if we have line
inside line.
"""
return len(self) != 0 and self.objectValues()[0].meta_type == self.meta_type
security.declareProtected(Permissions.AccessContentsInformation, security.declareProtected(Permissions.AccessContentsInformation,
'hasCellContent') 'hasCellContent')
......
...@@ -79,3 +79,7 @@ class MovementGroup(XMLObject): ...@@ -79,3 +79,7 @@ class MovementGroup(XMLObject):
return sorted([[sorted(x[0], key=lambda x: x.getId()), x[1]] \ return sorted([[sorted(x[0], key=lambda x: x.getId()), x[1]] \
for x in self._separate(movement_list)], for x in self._separate(movement_list)],
key=lambda x: x[0][0].getId()) key=lambda x: x[0][0].getId())
def isBranch(self):
# self is taken as branch point by the builder if returned value is True.
return False
##############################################################################
#
# Copyright (c) 2009 Nexedi SA and Contributors. All Rights Reserved.
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsibility of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# guarantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
#
##############################################################################
from Products.ERP5.Document.MovementGroup import MovementGroup
class NestedLineMovementGroup(MovementGroup):
"""
This MovementGroup is only used to multiple lines control.
No more effect.
"""
meta_type = 'ERP5 Nested Line Movement Group'
portal_type = 'Nested Line Movement Group'
def _getPropertyDict(self, movement, **kw):
return {}
def test(self, object, property_dict, property_list=None, **kw):
if property_list not in (None, []):
target_property_list = [x for x in self.getTestedPropertyList() \
if x in property_list]
else:
target_property_list = self.getTestedPropertyList()
for prop in target_property_list:
if property_dict[prop] != object.getProperty(prop, None):
return False, property_dict
return True, property_dict
def isBranch(self):
return True
This diff is collapsed.
...@@ -64,57 +64,6 @@ class OrderLine(DeliveryLine): ...@@ -64,57 +64,6 @@ class OrderLine(DeliveryLine):
# Declarative interfaces # Declarative interfaces
__implements__ = ( Interface.Variated, ) __implements__ = ( Interface.Variated, )
security.declareProtected(Permissions.AccessContentsInformation,
'hasLineContent')
def hasLineContent(self):
"""Return true if the object contains lines.
This method only checks the first sub document because all sub
documents should be Order Line in reality if we have Order Line
inside Order Line.
"""
return len(self) != 0 and self.objectValues()[0].meta_type == self.meta_type
def _getTotalPrice(self, default=0.0, context=None, fast=0):
"""Returns the total price for this order line.
if hasLineContent: return sum of lines total price
if hasCellContent: return sum of cells total price
else: return quantity * price
if fast is argument true, then a SQL method will be used.
"""
if self.hasLineContent():
meta_type = self.meta_type
return sum(l.getTotalPrice(context=context)
for l in self.objectValues() if l.meta_type==meta_type)
return DeliveryLine._getTotalPrice(self,
default=default,
context=context,
fast=fast)
security.declareProtected(Permissions.AccessContentsInformation,
'getTotalQuantity')
def getTotalQuantity(self, fast=0):
"""Returns the total quantity of this order line.
if hasLineContent: return sum of lines total quantity
if hasCellContent: return sum of cells total quantity
else: return quantity
if fast argument is true, then a SQL method will be used.
"""
base_id = 'movement'
if self.hasLineContent():
meta_type = self.meta_type
return sum(l.getTotalQuantity() for l in
self.objectValues() if l.meta_type==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', def applyToOrderLineRelatedMovement(self, portal_type='Simulation Movement',
method_id = 'expand'): method_id = 'expand'):
""" """
......
...@@ -76,8 +76,7 @@ class MovementGroupNode: ...@@ -76,8 +76,7 @@ class MovementGroupNode:
for movement in movement_list[1:]: for movement in movement_list[1:]:
# We have a conflict here, because it is forbidden to have # We have a conflict here, because it is forbidden to have
# 2 movements on the same node group # 2 movements on the same node group
tmp_result = self._separate(movement) self._movement_list, split_movement = self._separate(movement)
self._movement_list, split_movement = tmp_result
if split_movement is not None: if split_movement is not None:
# We rejected a movement, we need to put it on another line # We rejected a movement, we need to put it on another line
# Or to create a new one # Or to create a new one
...@@ -109,6 +108,9 @@ class MovementGroupNode: ...@@ -109,6 +108,9 @@ class MovementGroupNode:
del(property_dict[key]) del(property_dict[key])
return property_dict return property_dict
def getCurrentMovementGroup(self):
return self._movement_group
def getMovementList(self): def getMovementList(self):
""" """
Return movement list in the current group Return movement list in the current group
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment