Commit b13ff9a6 authored by Romain Courteaud's avatar Romain Courteaud

erp5_open_trade: SubscriptionItem: many improvements

* copy all aggregate values
* expand source/destination project defined on the open order
* expand source/destination payment
* support Open Order Cell
* if there is no stop_date, block the generation to today
parent aee27173
...@@ -39,6 +39,7 @@ from erp5.component.mixin.MovementGeneratorMixin import MovementGeneratorMixin ...@@ -39,6 +39,7 @@ from erp5.component.mixin.MovementGeneratorMixin import MovementGeneratorMixin
from Products.ERP5.mixin.periodicity import PeriodicityMixin from Products.ERP5.mixin.periodicity import PeriodicityMixin
from Products.ERP5Type.Base import Base from Products.ERP5Type.Base import Base
from erp5.component.interface.IMovementGenerator import IMovementGenerator from erp5.component.interface.IMovementGenerator import IMovementGenerator
from DateTime import DateTime
@zope.interface.implementer(IMovementGenerator,) @zope.interface.implementer(IMovementGenerator,)
class SubscriptionItem(Item, CompositionMixin, MovementGeneratorMixin, class SubscriptionItem(Item, CompositionMixin, MovementGeneratorMixin,
...@@ -99,6 +100,29 @@ class SubscriptionItem(Item, CompositionMixin, MovementGeneratorMixin, ...@@ -99,6 +100,29 @@ class SubscriptionItem(Item, CompositionMixin, MovementGeneratorMixin,
# Default implementation bellow can be overriden by subclasses # Default implementation bellow can be overriden by subclasses
return {} return {}
def _getLatestOpenOrderPath(self):
catalog_tool = getToolByName(self, 'portal_catalog')
# Try to find the source open order
line_list = catalog_tool(
portal_type=["Open Sale Order Line", "Open Sale Order Cell"],
aggregate__uid=self.getUid(),
validation_state=('open', 'validated', 'archived'), # XXX-JPS hard coding
sort_on=(('effective_date', 'descending'),
# Do not return archived if effective dates are identical
('validation_state', 'descending')),
limit=1 # Note Luke: Support the newest Open Order which defines
# something for current subscription item
)
"""
if line.hasCellContent(base_id='path'):
movement_list = line.getCellValueList(base_id='path')
else:
movement_list = [line]
"""
if len(line_list) == 1:
return line_list[0]
return None
def _getInputMovementList(self, movement_list=None, rounding=None): def _getInputMovementList(self, movement_list=None, rounding=None):
""" """
Generate the list of input movements by looking at all Generate the list of input movements by looking at all
...@@ -108,158 +132,170 @@ class SubscriptionItem(Item, CompositionMixin, MovementGeneratorMixin, ...@@ -108,158 +132,170 @@ class SubscriptionItem(Item, CompositionMixin, MovementGeneratorMixin,
of resource, ie. float or unit) of resource, ie. float or unit)
""" """
result = [] result = []
catalog_tool = getToolByName(self, 'portal_catalog')
# Try to find the source open order movement = self._getLatestOpenOrderPath()
for movement in catalog_tool(portal_type="Open Sale Order Line", if movement is not None:
default_aggregate_uid=self.getUid(), resource = movement.getResource()
validation_state=('open', 'validated', 'archived'), # XXX-JPS hard coding start_date = movement.getStartDate()
sort_on=(('effective_date', 'descending'), # if there is no stop_date, block the generation
# Do not return archived if effective dates are identical # to today
('validation_state', 'descending')), stop_date = movement.getStopDate()
limit=1 # Note Luke: Support the newest Open Order which defines if (start_date == stop_date) or (stop_date is None):
# something for current subscription item # stop_date seems acquired from start_date
): # YXU-Why we have a list here? stop_date = DateTime()
resource = movement.getResource() if (start_date is None) or (stop_date < start_date):
start_date = movement.getStartDate() # infinity nor time back machine does not exist
stop_date = movement.getStopDate() return result
if start_date is None or stop_date is None or start_date>=stop_date: source = movement.getSource()
# infinity nor time back machine does not exist source_section = movement.getSourceSection()
continue source_project = movement.getSourceProject()
source = movement.getSource() source_decision = movement.getSourceDecision()
source_section = movement.getSourceSection() source_payment = movement.getSourcePayment()
source_decision = movement.getSourceDecision() destination = movement.getDestination()
destination = movement.getDestination() destination_section = movement.getDestinationSection()
destination_section = movement.getDestinationSection() destination_project = movement.getDestinationProject()
destination_decision = movement.getDestinationDecision() destination_decision = movement.getDestinationDecision()
quantity = movement.getQuantity() destination_payment = movement.getDestinationPayment()
quantity_unit = movement.getQuantityUnit() quantity = movement.getQuantity()
price = movement.getPrice() quantity_unit = movement.getQuantityUnit()
price_currency = movement.getPriceCurrency() price = movement.getPrice()
base_application_list = movement.getBaseApplicationList() price_currency = movement.getPriceCurrency()
base_contribution_list = movement.getBaseContributionList() # XXX no acquisition
use_list = movement.getUseList() base_application_list = movement.getBaseApplicationList()
base_contribution_list = movement.getBaseContributionList()
specialise = movement.getSpecialise() # XXX no acquisition
current_date = start_date use_list = movement.getUseList()
id_index = 0 # XXX no acquisition
while current_date < stop_date: aggregate_list = movement.getAggregateList()
next_date = self.getNextPeriodicalDate(current_date)
generated_movement = self.newContent(temp_object=True, variation_category_list = movement.getVariationCategoryList()
portal_type='Movement',
id='subscription_%s' % id_index) # XXX no acquisition
generated_movement._edit( aggregate_value=self, specialise = movement.getSpecialise()
resource=resource, current_date = start_date
quantity=quantity, id_index = 0
quantity_unit=quantity_unit, while current_date < stop_date:
price=price, next_date = self.getNextPeriodicalDate(current_date)
price_currency=price_currency, generated_movement = self.newContent(temp_object=True,
start_date=current_date, portal_type='Movement',
stop_date=next_date, id='subscription_%s' % id_index)
source=source, generated_movement._edit( aggregate_list=aggregate_list,
source_section=source_section, resource=resource,
source_decision=source_decision, quantity=quantity,
destination=destination, quantity_unit=quantity_unit,
destination_section=destination_section, price=price,
destination_decision=destination_decision, price_currency=price_currency,
specialise=specialise, start_date=current_date,
base_application_list=base_application_list, stop_date=next_date,
base_contribution_list=base_contribution_list, source=source,
use_list=use_list source_section=source_section,
) source_project=source_project,
result.append(generated_movement) source_decision=source_decision,
current_date = next_date source_payment=source_payment,
id_index += 1 destination=destination,
destination_section=destination_section,
destination_project=destination_project,
destination_decision=destination_decision,
destination_payment=destination_payment,
specialise=specialise,
base_application_list=base_application_list,
base_contribution_list=base_contribution_list,
use_list=use_list,
variation_category_list=variation_category_list
)
result.append(generated_movement)
current_date = next_date
id_index += 1
return result return result
# XXX BELOW HACKS # XXX BELOW HACKS
def getResource(self): def getResource(self):
open_order_line = self.getAggregateRelatedValue(portal_type='Open Sale Order Line') open_order_line = self._getLatestOpenOrderPath()
if open_order_line is None: if open_order_line is None:
return None return None
return open_order_line.getResource() return open_order_line.getResource()
def getStartDate(self): def getStartDate(self):
open_order_line = self.getAggregateRelatedValue(portal_type='Open Sale Order Line') open_order_line = self._getLatestOpenOrderPath()
if open_order_line is None: if open_order_line is None:
return None return None
return open_order_line.getStartDate() return open_order_line.getStartDate()
def getStopDate(self): def getStopDate(self):
open_order_line = self.getAggregateRelatedValue(portal_type='Open Sale Order Line') open_order_line = self._getLatestOpenOrderPath()
if open_order_line is None: if open_order_line is None:
return None return None
return open_order_line.getStopDate() return open_order_line.getStopDate()
def getSource(self): def getSource(self):
open_order_line = self.getAggregateRelatedValue(portal_type='Open Sale Order Line') open_order_line = self._getLatestOpenOrderPath()
if open_order_line is None: if open_order_line is None:
return None return None
return open_order_line.getSource() return open_order_line.getSource()
def getSourceSection(self): def getSourceSection(self):
open_order_line = self.getAggregateRelatedValue(portal_type='Open Sale Order Line') open_order_line = self._getLatestOpenOrderPath()
if open_order_line is None: if open_order_line is None:
return None return None
return open_order_line.getSourceSection() return open_order_line.getSourceSection()
def getDestination(self): def getDestination(self):
open_order_line = self.getAggregateRelatedValue(portal_type='Open Sale Order Line') open_order_line = self._getLatestOpenOrderPath()
if open_order_line is None: if open_order_line is None:
return None return None
return open_order_line.getDestination() return open_order_line.getDestination()
def getDestinationSection(self): def getDestinationSection(self):
open_order_line = self.getAggregateRelatedValue(portal_type='Open Sale Order Line') open_order_line = self._getLatestOpenOrderPath()
if open_order_line is None: if open_order_line is None:
return None return None
return open_order_line.getDestinationSection() return open_order_line.getDestinationSection()
def getQuantity(self): def getQuantity(self):
open_order_line = self.getAggregateRelatedValue(portal_type='Open Sale Order Line') open_order_line = self._getLatestOpenOrderPath()
if open_order_line is None: if open_order_line is None:
return None return None
return open_order_line.getQuantity() return open_order_line.getQuantity()
def getQuantityUnit(self, checked_permission=None): def getQuantityUnit(self, checked_permission=None):
open_order_line = self.getAggregateRelatedValue(portal_type='Open Sale Order Line') open_order_line = self._getLatestOpenOrderPath()
if open_order_line is None: if open_order_line is None:
return None return None
return open_order_line.getQuantityUnit(checked_permission=checked_permission) return open_order_line.getQuantityUnit(checked_permission=checked_permission)
def getPrice(self, context=None): def getPrice(self, context=None):
open_order_line = self.getAggregateRelatedValue(portal_type='Open Sale Order Line') open_order_line = self._getLatestOpenOrderPath()
if open_order_line is None: if open_order_line is None:
return None return None
return open_order_line.getPrice() return open_order_line.getPrice()
def getPriceCurrency(self): def getPriceCurrency(self):
open_order_line = self.getAggregateRelatedValue(portal_type='Open Sale Order Line') open_order_line = self._getLatestOpenOrderPath()
if open_order_line is None: if open_order_line is None:
return None return None
return open_order_line.getPriceCurrency() return open_order_line.getPriceCurrency()
def getSpecialise(self): def getSpecialise(self):
open_order_line = self.getAggregateRelatedValue(portal_type='Open Sale Order Line') open_order_line = self._getLatestOpenOrderPath()
if open_order_line is None: if open_order_line is None:
return None return None
return open_order_line.getSpecialise() return open_order_line.getSpecialise()
def getSpecialiseList(self): def getSpecialiseList(self):
open_order_line = self.getAggregateRelatedValue(portal_type='Open Sale Order Line') open_order_line = self._getLatestOpenOrderPath()
if open_order_line is None: if open_order_line is None:
return [] return []
return open_order_line.getSpecialiseList() return open_order_line.getSpecialiseList()
def getSpecialiseValue(self): def getSpecialiseValue(self):
open_order_line = self.getAggregateRelatedValue(portal_type='Open Sale Order Line') open_order_line = self._getLatestOpenOrderPath()
if open_order_line is None: if open_order_line is None:
return None return None
return open_order_line.getSpecialiseValue() return open_order_line.getSpecialiseValue()
def getSpecialiseValueList(self): def getSpecialiseValueList(self):
open_order_line = self.getAggregateRelatedValue(portal_type='Open Sale Order Line') open_order_line = self._getLatestOpenOrderPath()
if open_order_line is None: if open_order_line is None:
return [] return []
return open_order_line.getSpecialiseValueList() return open_order_line.getSpecialiseValueList()
...@@ -275,10 +311,11 @@ class SubscriptionItem(Item, CompositionMixin, MovementGeneratorMixin, ...@@ -275,10 +311,11 @@ class SubscriptionItem(Item, CompositionMixin, MovementGeneratorMixin,
checked_permission=None, checked_permission=None,
**kw): **kw):
if category == 'specialise': if category == 'specialise':
open_order_line = self.getAggregateRelatedValue(portal_type='Open Sale Order Line') open_order_line = self._getLatestOpenOrderPath()
return open_order_line._getCategoryMembershipList(category, spec=spec, filter=filter, if open_order_line is not None:
portal_type=portal_type, base=base, keep_default=keep_default, return open_order_line._getCategoryMembershipList(category, spec=spec, filter=filter,
checked_permission=checked_permission, **kw) portal_type=portal_type, base=base, keep_default=keep_default,
checked_permission=checked_permission, **kw)
return Base._getCategoryMembershipList(self, category, spec=spec, filter=filter, return Base._getCategoryMembershipList(self, category, spec=spec, filter=filter,
portal_type=portal_type, base=base, keep_default=keep_default, portal_type=portal_type, base=base, keep_default=keep_default,
checked_permission=checked_permission, **kw) checked_permission=checked_permission, **kw)
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