Commit 21f40032 authored by Jean-Paul Smets's avatar Jean-Paul Smets

Business Path has beed splitted in 2 parts. A first part which is only used to...

Business Path has beed splitted in 2 parts. A first part which is only used to control completation of trade phases and build process. A second part which is only used to define arrows, quantity shares and dates on amounts generated by amount generators. The first part is a predicate but no longer a Path (no arrow, no quantity, no delay, etc.). It is thus renamed to Business Link. The second part is a Path since it defines an Arrow, a quantity, a lead time, etc. It is thus renamed to Trade Model Path. 
It is now time to review in detail all interfaces. In particular those interfaces on Business Link related to time management many no longer be needed since it is simpler to lookup simulation. However, time management must be handled at Business Process level as a helper method for rules which need to calculate dates based on Business Links and/or Trade Model Path.

git-svn-id: https://svn.erp5.org/repos/public/erp5/sandbox/amount_generator@36465 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent b1f4f161
# -*- coding: utf-8 -*-
# -*- coding: shift_jis -*-
##############################################################################
#
# Copyright (c) 2009 Nexedi SA and Contributors. All Rights Reserved.
......@@ -43,6 +43,7 @@ class SelectMethodError(Exception): pass
class BPMBuilder(Alarm):
"""Top class for builders.
XXX-JPS Wrong Naming - Abbreviation (BPM)
WARNING: This is BPM evaluation of building approach.
WARNING: Do NOT use it in production environment.
......@@ -100,10 +101,10 @@ class BPMBuilder(Alarm):
# Select movements
if input_movement_list is None:
if not select_method_dict.has_key('causality_uid'):
business_path_value_list = self.getRelatedBusinessPathValueList()
if len(business_path_value_list) > 0:
# use only Business Path related movements
select_method_dict['causality_uid'] = [q.getUid() for q in business_path_value_list]
business_link_value_list = self.getRelatedBusinessLinkValueList()
if len(business_link_value_list) > 0:
# use only Business Link related movements
select_method_dict['causality_uid'] = [q.getUid() for q in business_link_value_list]
# do search
input_movement_value_list = self.searchMovementList(
delivery_relative_url_list=existing_delivery_list,
......@@ -220,10 +221,10 @@ class BPMBuilder(Alarm):
input_movement.edit(delivery_value=delivery_movement,
activate_kw=activate_kw)
def getRelatedBusinessPathValueList(self):
def getRelatedBusinessLinkValueList(self):
return self.getDeliveryBuilderRelatedValueList(
portal_type='Business Path') + self.getOrderBuilderRelatedValueList(
portal_type='Business Path')
portal_type='Business Link') + self.getOrderBuilderRelatedValueList(
portal_type='Business Link')
def callBeforeBuildingScript(self):
"""
......
This diff is collapsed.
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2010 Nexedi SA and Contributors. All Rights Reserved.
......@@ -44,7 +45,7 @@ class DeliveryRootSimulationRule(DeliveryRule):
security.declareObjectProtected(Permissions.AccessContentsInformation)
def _getExpandablePropertyUpdateDict(self, applied_rule, movement,
business_path, current_property_dict):
business_link, current_property_dict):
"""Order rule specific update dictionary"""
return {
'delivery': movement.getRelativeUrl(),
......
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2010 Nexedi SA and Contributors. All Rights Reserved.
......@@ -44,7 +45,7 @@ class InvoiceRootSimulationRule(InvoiceRule):
security.declareObjectProtected(Permissions.AccessContentsInformation)
def _getExpandablePropertyUpdateDict(self, applied_rule, movement,
business_path, current_property_dict):
business_link, current_property_dict):
"""Order rule specific update dictionary"""
return {
'delivery': movement.getRelativeUrl(),
......
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2002, 2005 Nexedi SARL and Contributors. All Rights Reserved.
......@@ -47,7 +48,7 @@ class OrderRootSimulationRule(OrderRule):
security.declareObjectProtected(Permissions.AccessContentsInformation)
def _getExpandablePropertyUpdateDict(self, applied_rule, movement,
business_path, current_property_dict):
business_link, current_property_dict):
"""Order rule specific update dictionary"""
return {
'delivery': movement.getRelativeUrl(),
......
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2002 Nexedi SARL and Contributors. All Rights Reserved.
......@@ -200,11 +201,11 @@ class PaySheetTransaction(Invoice):
movement_list_trade_phase_dic[trade_phase].append(movement)
for trade_phase in movement_list_trade_phase_dic.keys():
business_path_list = business_process.getPathValueList(trade_phase=\
business_link_list = business_process.getPathValueList(trade_phase=\
trade_phase)
for business_path in business_path_list:
for business_link in business_link_list:
builder_list = [portal.restrictedTraverse(url) for url in\
business_path.getDeliveryBuilderList()]
business_link.getDeliveryBuilderList()]
for builder in builder_list:
builder.build(delivery_relative_url_list=[self.getRelativeUrl(),],
movement_list = movement_list_trade_phase_dic[trade_phase])
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2005 Nexedi SARL and Contributors. All Rights Reserved.
......@@ -45,7 +46,7 @@ class ProductionOrderModelRootSimulationRule(ProductionOrderModelRule):
security.declareObjectProtected(Permissions.AccessContentsInformation)
def _getExpandablePropertyUpdateDict(self, applied_rule, movement,
business_path, current_property_dict):
business_link, current_property_dict):
"""Order rule specific update dictionary"""
return {
'delivery': movement.getRelativeUrl(),
......
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2005 Nexedi SARL and Contributors. All Rights Reserved.
......@@ -45,7 +46,7 @@ class ProductionOrderRootSimulationRule(ProductionOrderRule):
security.declareObjectProtected(Permissions.AccessContentsInformation)
def _getExpandablePropertyUpdateDict(self, applied_rule, movement,
business_path, current_property_dict):
business_link, current_property_dict):
"""Order rule specific update dictionary"""
return {
'delivery': movement.getRelativeUrl(),
......
......@@ -202,11 +202,11 @@ class SimulationMovement(Movement, PropertyRecordableMixin, ExplainableMixin):
simulation_state is in of completed state list defined on business path
"""
# only available in BPM, so fail totally in case of working without BPM
business_path = self.getCausalityValue(
portal_type=self.getPortalBusinessPathTypeList())
if business_path is None:
business_link = self.getCausalityValue(
portal_type=self.getPortalBusinessLinkTypeList())
if business_link is None:
return False
return self.getSimulationState() in business_path.getCompletedStateList()
return self.getSimulationState() in business_link.getCompletedStateList()
security.declareProtected(Permissions.AccessContentsInformation,
'isFrozen')
......@@ -214,9 +214,9 @@ class SimulationMovement(Movement, PropertyRecordableMixin, ExplainableMixin):
"""Lookup business path and, if any, return True whenever
simulation_state is in one of the frozen states defined on business path
"""
business_path = self.getCausalityValue(
portal_type=self.getPortalBusinessPathTypeList())
if business_path is None:
business_link = self.getCausalityValue(
portal_type=self.getPortalBusinessLinkTypeList())
if business_link is None:
# Legacy support - this should never happen
# XXX-JPS ADD WARNING
if self.getSimulationState() in ('stopped', 'delivered', 'cancelled'):
......@@ -224,7 +224,7 @@ class SimulationMovement(Movement, PropertyRecordableMixin, ExplainableMixin):
if self._baseIsFrozen() == 0:
self._baseSetFrozen(None)
return self._baseGetFrozen() or False
return self.getSimulationState() in business_path.getFrozenStateList()
return self.getSimulationState() in business_link.getFrozenStateList()
security.declareProtected( Permissions.AccessContentsInformation,
'isAccountable')
......@@ -580,32 +580,32 @@ class SimulationMovement(Movement, PropertyRecordableMixin, ExplainableMixin):
return False
# might be buildable - business path depended
business_path = self.getCausalityValue(portal_type='Business Path')
business_link = self.getCausalityValue(portal_type='Business Link')
explanation_value = self.getExplanationValue()
if business_path is None or explanation_value is None:
if business_link is None or explanation_value is None:
return True
predecessor = business_path.getPredecessorValue()
predecessor = business_link.getPredecessorValue()
if predecessor is None:
# first one, can be built
return True # XXX-JPS wrong cause root is marked
for successor_related in predecessor.getSuccessorRelatedValueList(): # XXX-JPS wrong cause state shared by multi BPM
for business_path_movement in successor_related \
for business_link_movement in successor_related \
.getRelatedSimulationMovementValueList(explanation_value):
if successor_related.isMovementRelatedWithMovement(self,
business_path_movement):
business_path_movement_delivery = business_path_movement \
business_link_movement):
business_link_movement_delivery = business_link_movement \
.getDeliveryValue()
if business_path_movement_delivery is None:
if business_link_movement_delivery is None:
return False # related movement is not delivered yet
business_path_movement_delivery_document = \
business_path_movement_delivery.getExplanationValue()
business_link_movement_delivery_document = \
business_link_movement_delivery.getExplanationValue()
# here we can optimise somehow, as
# business_path_movement_delivery_document would repeat
# business_link_movement_delivery_document would repeat
if not successor_related.isCompleted(
business_path_movement_delivery_document):
business_link_movement_delivery_document):
# related movements delivery is not completed
return False
return True
......
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2002 Nexedi SARL and Contributors. All Rights Reserved.
......@@ -186,7 +187,7 @@ portal_supply_type_list = ('Purchase Supply','Sale Supply')
portal_supply_path_type_list = ('Supply Line','Supply Cell')
portal_business_process_type_list = ('Business Process',)
portal_business_path_type_list = ('Business Path',)
portal_business_link_type_list = ('Business Link',)
# This transaction lines are special because destination must be None.
portal_balance_transaction_line_type_list = ('Balance Transaction Line',)
......
......@@ -775,24 +775,6 @@ class ERP5Site(FolderMixIn, CMFSite):
return self._getPortalGroupedTypeList('supply_path') or \
self._getPortalConfiguration('portal_supply_path_type_list')
security.declareProtected(Permissions.AccessContentsInformation,
'getPortalBusinessProcessTypeList')
def getPortalBusinessProcessTypeList(self):
"""
Return business process types.
"""
return self._getPortalGroupedTypeList('business_process') or \
self._getPortalConfiguration('portal_business_process_type_list')
security.declareProtected(Permissions.AccessContentsInformation,
'getPortalBusinessPathTypeList')
def getPortalBusinessPathTypeList(self):
"""
Return business path types.
"""
return self._getPortalGroupedTypeList('business_path') or \
self._getPortalConfiguration('portal_business_path_type_list')
security.declareProtected(Permissions.AccessContentsInformation,
'getPortalAcquisitionMovementTypeList')
def getPortalAcquisitionMovementTypeList(self):
......@@ -1141,13 +1123,22 @@ class ERP5Site(FolderMixIn, CMFSite):
"""
return self._getPortalGroupedTypeList('business_process')
security.declareProtected(Permissions.AccessContentsInformation,
'getPortalBusinessPathTypeList')
def getPortalBusinessPathTypeList(self):
'getPortalBusinessLinkTypeList')
def getPortalBusinessLinkTypeList(self):
"""
Return amount generator line types.
Return business link types.
"""
return self._getPortalGroupedTypeList('business_link')
security.declareProtected(Permissions.AccessContentsInformation,
'getPortalTradeModelPathTypeList')
def getPortalTradeModelPathTypeList(self):
"""
Return trade model path types.
"""
return self._getPortalGroupedTypeList('business_path')
return self._getPortalGroupedTypeList('trade_model_path')
security.declareProtected(Permissions.AccessContentsInformation,
'getPortalCalendarPeriodTypeList')
......
......@@ -148,18 +148,18 @@ class ExplanationCache:
self.explanation_path_pattern_cache = result
return result
def getBusinessPathRelatedSimulationMovementValueList(self, business_path):
"""Returns the list of simulation movements caused by a business_path
def getBusinessLinkRelatedSimulationMovementValueList(self, business_link):
"""Returns the list of simulation movements caused by a business_link
in the context the our explanation.
"""
return self.getSimulationMovementValueList(causality_uid=business_path.getUid())
return self.getSimulationMovementValueList(causality_uid=business_link.getUid())
def getBusinessPathRelatedMovementValueList(self, business_path):
"""Returns the list of delivery movements related to a business_path
def getBusinessLinkRelatedMovementValueList(self, business_link):
"""Returns the list of delivery movements related to a business_link
in the context the our explanation.
"""
#XXXXXXXXXXX BAD
return self.getSimulationMovementValueList(causality_uid=business_path.getUid())
return self.getSimulationMovementValueList(causality_uid=business_link.getUid())
def getSimulationMovementValueList(self, **kw):
"""Search Simulation Movements related to our explanation.
......@@ -182,42 +182,42 @@ class ExplanationCache:
**kw)
return self.simulation_movement_cache[kw_tuple]
def getBusinessPathValueList(self, **kw):
def getBusinessLinkValueList(self, **kw):
"""Find all business path which are related to the simulation
trees defined by the explanation.
"""
business_type_list = self.getPortalBusinessPathTypeList()
business_type_list = self.getPortalBusinessLinkTypeList()
simulation_movement_list = self.getSimulationMovementValueList()
simulation_movement_uid_list = map(lambda x:x.uid, simulation_movement_list)
# We could use related keys instead of 2 queries
business_path_list = self.portal_catalog(
business_link_list = self.portal_catalog(
portal_type=business_type_list,
causality_related_uid=simulation_movement_uid_list,
**kw)
return business_path_list
return business_link_list
def getBusinessPathClosure(self, business_process, business_path):
"""Creates a Business Process by filtering out all Business Path
def getBusinessLinkClosure(self, business_process, business_link):
"""Creates a Business Process by filtering out all Business Link
in 'business_process' which are not related to a simulation movement
which is either a parent or a child of explanation simulations movements
caused by 'business_path'
caused by 'business_link'
NOTE: Business Path Closure must be at least as "big" as composed
NOTE: Business Link Closure must be at least as "big" as composed
business path. The appropriate calculation is still not clear.
Options are:
- take all path of composed business path (even not yet expanded)
- take all path of composed business path which phase is not yet expanded
"""
# Try to return cached value first
new_business_process = self.closure_cache.get(business_path, None)
new_business_process = self.closure_cache.get(business_link, None)
if new_business_process is not None:
return new_business_process
# Build a list of path patterns which apply to current business_path
# Build a list of path patterns which apply to current business_link
path_list = self.getSimulationPathPatternList()
path_list = map(lambda x:x[0:-1], path_list) # Remove trailing %
path_set = set()
for simulation_movement in business_path.\
for simulation_movement in business_link.\
_getExplanationRelatedSimulationMovementValueList(self.explanation):
simulation_path = simulation_movement.getPath()
for path in path_list:
......@@ -228,30 +228,30 @@ class ExplanationCache:
path_tuple = tuple(path_set) # XXX-JPS is the order guaranteed here ?
new_business_process = self.closure_cache.get(path_tuple, None)
if new_business_process is not None:
self.closure_cache[business_path] = new_business_process
self.closure_cache[business_link] = new_business_process
return new_business_process
# Build a new closure business process
def hasMatchingMovement(business_path):
def hasMatchingMovement(business_link):
return len(self.getSimulationMovementValueList(path=path_tuple,
causality_uid=business_path.getUid()))
causality_uid=business_link.getUid()))
module = business_process.getPortalObject().business_process_module # XXX-JPS
new_business_process = module.newContent(portal_type="Business Process",
temp_object=True) # XXX-JPS is this really OK with union business processes
i = 0
for business_path in business_process.getBusinessPathValueList():
if hasMatchingMovement(business_path):
for business_link in business_process.getBusinessLinkValueList():
if hasMatchingMovement(business_link):
i += 1
id = 'closure_path_%s' % i
new_business_process._setOb(id, business_path.asContext(id=id))
new_business_process._setOb(id, business_link.asContext(id=id))
self.closure_cache[business_path] = new_business_process
self.closure_cache[business_link] = new_business_process
self.closure_cache[path_tuple] = new_business_process
return new_business_process
def getUnionBusinessProcess(self):
"""Return a Business Process made of all Business Path
"""Return a Business Process made of all Business Link
which are the cause of Simulation Movements in the simulation
trees related to explanation.
"""
......@@ -264,10 +264,10 @@ class ExplanationCache:
from Products.ERP5Type.Document import newTempBusinessProcess
new_business_process = newTempBusinessProcess(self.explanation, 'union_business_process')
i = 0
for business_path in self.getBusinessPathValueList():
for business_link in self.getBusinessLinkValueList():
i += 1
id = 'union_path_%s' % i
new_business_process._setOb(id, business_path.asContext(id=id))
new_business_process._setOb(id, business_link.asContext(id=id))
# Keep it in cache and return
self.union_cache = new_business_process
......@@ -281,10 +281,10 @@ def _getExplanationCache(explanation):
tv['explanation_cache'] = ExplanationCache(explanation)
return tv.get('explanation_cache')
def _getBusinessPathClosure(business_process, explanation, business_path):
def _getBusinessLinkClosure(business_process, explanation, business_link):
"""Returns a closure Business Process for given
business_path and explanation. This Business Process
contains only those Business Path which are related to business_path
business_link and explanation. This Business Process
contains only those Business Link which are related to business_link
in the context of explanation.
"""
if explanation.getPortalType() == "Applied Rule":
......@@ -293,10 +293,10 @@ def _getBusinessPathClosure(business_process, explanation, business_path):
# closure might be smaller than expexted
return business_process
explanation_cache = _getExplanationCache(explanation)
return explanation_cache.getBusinessPathClosure(business_process, business_path)
return explanation_cache.getBusinessLinkClosure(business_process, business_link)
def _getUnionBusinessProcess(explanation):
"""Build a Business Process by taking the union of Business Path
"""Build a Business Process by taking the union of Business Link
which are involved in the simulation trees related to explanation
"""
explanation_cache = _getExplanationCache(explanation)
......
# -*- coding: utf-8 -*-
# -*- coding: shift_jis -*-
##############################################################################
#
# Copyright (c) 2009 Nexedi SA and Contributors. All Rights Reserved.
......@@ -47,11 +47,11 @@ class BuilderTool(BaseTool):
BuilderPortalType_selectDefaultMovement
business_process_list - optional Business Process list, if defined only
builders for Business Paths contained in those Business Process will
builders for Business Links contained in those Business Process will
be run
trade_phase_list - optional list of trade phases, if defined only
Business Paths for this trade phase will be used
Business Links for this trade phase will be used
existing_delivery_list - list of deliveries to which builder will *try*
add new/update existing movements and update delivery. It is not
......@@ -80,9 +80,9 @@ class BuilderTool(BaseTool):
method_id = getattr(self,method_id_dict[self.getPortalType()])
for business_process_url in business_process_list:
business_process = self.unrestrictedTraverse(business_process_url)
for business_path in business_process.getPathValueList(
for business_link in business_process.getPathValueList(
trade_phase=trade_phase_list):
builder_value_list.extend(getattr(business_path,method_id)())
builder_value_list.extend(getattr(business_link,method_id)())
# FIXME: what kind of sorting to use?
return sorted(builder_value_list)
......
......@@ -230,8 +230,8 @@ class SolverTool(BaseTool):
test_property = divergence_tester.getTestedProperty()
application_value_level = {}
for simulation_movement in movement.getDeliveryRelatedValueList():
business_path = simulation_movement.getCausalityValue()
for delivery_builder in business_path.getDeliveryBuilderValueList():
business_link = simulation_movement.getCausalityValue()
for delivery_builder in business_link.getDeliveryBuilderValueList():
for movement_group in delivery_builder.contentValues(): # filter missing
if test_property in movement_group.getTestedPropertyList():
application_value_level[movement_group.getCollectGroupOrder()] = None
......@@ -267,8 +267,8 @@ class SolverTool(BaseTool):
test_property = divergence_tester.getTestedProperty()
application_value_level = {}
for simulation_movement in movement.getDeliveryRelatedValueList():
business_path = simulation_movement.getCausalityValue()
for delivery_builder in business_path.getDeliveryBuilderValueList():
business_link = simulation_movement.getCausalityValue()
for delivery_builder in business_link.getDeliveryBuilderValueList():
for property_group in delivery_builder.contentValues(portal_type="Property group"):
if test_property in property_group.getTestedPropertyList():
application_value_level[property_group.getCollectGroupOrder()] = None
......
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2009 Nexedi SA and Contributors. All Rights Reserved.
# Jean-Paul Smets-Solanes <jp@nexedi.com>
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability 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
# garantees 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
"""
Products.ERP5.interfaces.business_path
"""
from zope.interface import Interface
class IBusinessPath(Interface):
"""Business Path interface specification
IBusinessPath provides a method to calculate the completion
date of existing movements based on business path properties.
It also provides methods to determine whether all related simulation
movements related to a given explanation are completed, partially
completed or frozen. Finally, it provides a method to invoke
delivery builders for all movements related to a given explanation.
"""
def getDeliveryBuilderValueList():
"""Return the list of delivery builders to invoke with
this Business Path.
NOTE: redundant with PropertySheet definition
"""
def getMovementCompletionDate(movement):
"""Returns the date of completion of the movemnet
based on paremeters of the business path. This completion date can be
the start date, the stop date, the date of a given workflow transition
on the explaining delivery, etc.
movement -- a Simulation Movement
"""
def getCompletionDate(explanation):
"""Returns the date of completion of business path in the
context of the explanation. The completion date of the Business
Path is the max date of all simulation movements which are
related to the Business Path and which are part of the explanation.
explanation -- the Order, Order Line, Delivery or Delivery Line which
implicitely defines a simulation subtree and a union
business process.
"""
def getExpectedQuantity(amount):
"""Returns the new quantity for the provided amount taking
into account the efficiency or the quantity defined on the business path.
This is used to implement payment conditions or splitting production
over multiple path. The total of getExpectedQuantity for all business
path which are applicable should never exceed the original quantity.
The implementation of this validation is left to rules.
"""
def isCompleted(explanation):
"""returns True if all related simulation movements for this explanation
document are in a simulation state which is considered as completed
according to the configuration of the current business path.
Completed means that it is possible to move to next step
of Business Process. This method does not check however whether previous
trade states of a given business process are completed or not.
Use instead IBusinessPathProcess.isBusinessPathCompleted for this purpose.
explanation -- the Order, Order Line, Delivery or Delivery Line which
implicitely defines a simulation subtree and a union
business process.
NOTE: simulation movements can be completed (ex. in 'started' state) but
not yet frozen (ex. in 'delivered' state).
"""
def isPartiallyCompleted(explanation):
"""returns True if some related simulation movements for this explanation
document are in a simulation state which is considered as completed
according to the configuration of the current business path.
Completed means that it is possible to move to next step
of Business Process. This method does not check however whether previous
trade states of a given business process are completed or not.
Use instead IBusinessPathProcess.isBusinessPathCompleted for this purpose.
explanation -- the Order, Order Line, Delivery or Delivery Line which
implicitely defines a simulation subtree and a union
business process.
"""
def isFrozen(explanation):
"""returns True if all related simulation movements for this explanation
document are in a simulation state which is considered as frozen
according to the configuration of the current business path.
Frozen means that simulation movement cannot be modified.
This method does not check however whether previous
trade states of a given business process are completed or not.
Use instead IBusinessPathProcess.isBusinessPathCompleted for this purpose.
explanation -- the Order, Order Line, Delivery or Delivery Line which
implicitely defines a simulation subtree and a union
business process.
NOTE: simulation movements can be frozen (ex. in 'stopped' state) but
not yet completed (ex. in 'delivered' state).
"""
def isDelivered(explanation):
"""Returns True is all simulation movements related to this
Business Path in the context of given explanation are built
and related to a delivery through the 'delivery' category.
explanation -- the Order, Order Line, Delivery or Delivery Line which
implicitely defines a simulation subtree and a union
business process.
"""
def build(explanation):
"""Builds all related movements in the simulation using the builders
defined on the Business Path
explanation -- the Order, Order Line, Delivery or Delivery Line which
implicitely defines a simulation subtree and a union
business process.
"""
\ No newline at end of file
This diff is collapsed.
......@@ -27,7 +27,7 @@
#
##############################################################################
"""
Products.ERP5.interfaces.business_path
Products.ERP5.interfaces.explainable
"""
from zope.interface import Interface
......
......@@ -2,8 +2,7 @@
##############################################################################
#
# Copyright (c) 2009 Nexedi SA and Contributors. All Rights Reserved.
# Lukasz Nowak <luke@nexedi.com>
# Yusuke Muraoka <yusuke@nexedi.com>
# Jean-Paul Smets-Solanes <jp@nexedi.com>
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
......@@ -27,55 +26,28 @@
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
"""
Products.ERP5.interfaces.trade_model_path
"""
class BusinessPath:
"""
Business Path properties
from zope.interface import Interface
class ITradeModelPath(Interface):
"""Trade Model Path interface specification
ITradeModelPath provides a method to calculate the completion
date of existing movements based on business path properties.
It also provides methods to determine whether all related simulation
movements related to a given explanation are completed, partially
completed or frozen. Finally, it provides a method to invoke
delivery builders for all movements related to a given explanation.
"""
_properties = (
{ 'id' : 'deliverable', # XXX-JPS: same is in Simulation property sheet
'description' : 'If 1 it is related to root of simulation tree (root explanation)',
'type' : 'boolean',
'mode' : 'w' },
{ 'id' : 'source_method_id',
'description' : 'ID of method to get source list of categories',
'type' : 'string',
'mode' : 'w' },
{ 'id' : 'destination_method_id',
'description' : 'ID of method to get destination list of categories',
'type' : 'string',
'mode' : 'w' },
{ 'id' : 'completion_date_method_id',
'description' : 'ID of method to get source list of categories',
'type' : 'string',
'default' : 'getStartDate',
'mode' : 'w' },
{ 'id' : 'completed_state',
'description' : 'List of states for which related Simulation '
'Movement is considered as completed',
'type' : 'lines',
'default' : [],
'multivalued' : 1,
'mode' : 'w' },
{ 'id' : 'frozen_state',
'description' : 'List of states for which related Simulation '
'Movement is considered as frozen',
'type' : 'lines',
'default' : [],
'multivalued' : 1,
'mode' : 'w' },
# Legacy
{ 'id' : 'lead_time', # XXX-JPS use FlowCapacity instead (min_delay)
'description' : 'How much time shall be spent on path',
'default' : 0.0,
'type' : 'float',
'mode' : 'w' },
{ 'id' : 'wait_time', # XXX-JPS: duplicate with PaymentCondition
'description' : 'How much time to wait before initiating path',
'default' : 0.0,
'type' : 'float',
'mode' : 'w' },
)
_categories = ('delivery_builder', 'order_builder', 'end_of',
'trade_phase' , 'incoterm')
def getExpectedQuantity(amount):
"""Returns the new quantity for the provided amount taking
into account the efficiency or the quantity defined on the business path.
This is used to implement payment conditions or splitting production
over multiple path. The total of getExpectedQuantity for all business
path which are applicable should never exceed the original quantity.
The implementation of this validation is left to rules.
"""
This diff is collapsed.
# -*- coding: utf-8 -*-
# -*- coding: shift_jis -*-
##############################################################################
# Copyright (c) 2009 Nexedi SA and Contributors. All Rights Reserved.
# Łukasz Nowak <luke@nexedi.com>
......@@ -505,7 +505,7 @@ class TestBPMEvaluationDefaultProcessMixin:
referential_date='start_date')
self._setTradeStateList()
self.order_path = self.createBusinessPath(self.business_process,
self.order_path = self.createBusinessLink(self.business_process,
successor_value=self.ordered_state,
trade_phase='default/order',
deliverable=1,
......@@ -513,7 +513,7 @@ class TestBPMEvaluationDefaultProcessMixin:
frozen_state_list=['confirmed'],
)
self.delivery_path = self.createBusinessPath(self.business_process,
self.delivery_path = self.createBusinessLink(self.business_process,
predecessor_value=self.ordered_state,
successor_value=self.delivered_state,
trade_phase='default/delivery',
......@@ -523,7 +523,7 @@ class TestBPMEvaluationDefaultProcessMixin:
delivery_builder='portal_deliveries/bpm_sale_packing_list_builder',
)
self.invoice_path = self.createBusinessPath(self.business_process,
self.invoice_path = self.createBusinessLink(self.business_process,
predecessor_value=self.delivered_state,
successor_value=self.invoiced_state,
completed_state_list=['delivered'],
......@@ -531,14 +531,14 @@ class TestBPMEvaluationDefaultProcessMixin:
delivery_builder='portal_deliveries/bpm_sale_invoice_builder',
trade_phase='default/invoicing')
self.account_path = self.createBusinessPath(self.business_process,
self.account_path = self.createBusinessLink(self.business_process,
predecessor_value=self.invoiced_state,
successor_value=self.accounted_state,
completed_state_list=['delivered'],
frozen_state_list=['stopped', 'delivered'],
trade_phase='default/accounting')
self.pay_path = self.createBusinessPath(self.business_process,
self.pay_path = self.createBusinessLink(self.business_process,
predecessor_value=self.invoiced_state,
successor_value=self.accounted_state,
completed_state_list=['delivered'],
......@@ -553,7 +553,7 @@ class TestBPMEvaluationDifferentProcessMixin:
referential_date='start_date')
self._setTradeStateList()
self.order_path = self.createBusinessPath(self.business_process,
self.order_path = self.createBusinessLink(self.business_process,
successor_value=self.ordered_state,
trade_phase='default/order',
deliverable=1,
......@@ -561,28 +561,28 @@ class TestBPMEvaluationDifferentProcessMixin:
frozen_state_list=['confirmed'],
)
self.invoice_path = self.createBusinessPath(self.business_process,
self.invoice_path = self.createBusinessLink(self.business_process,
predecessor_value=self.ordered_state,
successor_value=self.invoiced_state,
completed_state_list=['delivered'],
frozen_state_list=['stopped', 'delivered'],
trade_phase='default/invoicing')
self.account_path = self.createBusinessPath(self.business_process,
self.account_path = self.createBusinessLink(self.business_process,
predecessor_value=self.invoiced_state,
successor_value=self.accounted_state,
completed_state_list=['delivered'],
frozen_state_list=['stopped', 'delivered'],
trade_phase='default/accounting')
self.pay_path = self.createBusinessPath(self.business_process,
self.pay_path = self.createBusinessLink(self.business_process,
predecessor_value=self.accounted_state,
successor_value=self.paid_state,
completed_state_list=['delivered'],
frozen_state_list=['stopped', 'delivered'],
trade_phase='default/payment')
self.delivery_path = self.createBusinessPath(self.business_process,
self.delivery_path = self.createBusinessLink(self.business_process,
predecessor_value=self.paid_state,
successor_value=self.delivered_state,
trade_phase='default/delivery',
......
# -*- coding: utf-8 -*-
# -*- coding: shift_jis -*-
##############################################################################
# Copyright (c) 2009 Nexedi SA and Contributors. All Rights Reserved.
# Łukasz Nowak <luke@nexedi.com>
......@@ -35,9 +35,9 @@ import unittest
# manually and treated as reference to what implements what
implements_tuple_list = [
(('Products.ERP5Type.Document.RoleDefinition', 'RoleDefinition'), 'ILocalRoleGenerator'),
(('Products.ERP5Type.Document.BusinessPath','BusinessPath'), 'IArrowBase'),
(('Products.ERP5Type.Document.BusinessPath','BusinessPath'), 'IBusinessPath'),
(('Products.ERP5Type.Document.BusinessPath','BusinessPath'), 'ICategoryAccessProvider'),
(('Products.ERP5Type.Document.BusinessLink','BusinessLink'), 'IArrowBase'),
(('Products.ERP5Type.Document.BusinessLink','BusinessLink'), 'IBusinessLink'),
(('Products.ERP5Type.Document.BusinessLink','BusinessLink'), 'ICategoryAccessProvider'),
(('Products.ERP5Type.Document.TradeCondition','TradeCondition'), 'IAmountGenerator'),
(('Products.ERP5Type.Document.TradeModelCell','TradeModelCell'), 'IAmountGenerator'),
(('Products.ERP5Type.Document.TradeModelCell','TradeModelCell'), 'IVariated'),
......@@ -84,8 +84,8 @@ addTestMethodDynamically(TestERP5Interfaces, implements_tuple_list)
for failing_method in [
'test_Products.ERP5.AggregatedAmountList_AggregatedAmountList_implements_IAmountList',
'test_Products.ERP5Type.Document.BusinessPath_BusinessPath_implements_IBusinessPath',
'test_Products.ERP5Type.Document.BusinessPath_BusinessPath_implements_ICategoryAccessProvider',
'test_Products.ERP5Type.Document.BusinessLink_BusinessLink_implements_IBusinessLink',
'test_Products.ERP5Type.Document.BusinessLink_BusinessLink_implements_ICategoryAccessProvider',
'test_Products.ERP5Type.Document.TradeCondition_TradeCondition_implements_IAmountGenerator',
'test_Products.ERP5Type.Document.TradeModelCell_TradeModelCell_implements_IAmountGenerator',
'test_Products.ERP5Type.Document.TradeModelCell_TradeModelCell_implements_IVariated',
......
......@@ -57,9 +57,9 @@ class TestERP5SimulationMixin(TestInvoiceMixin):
def setUpBusinessProcess(self):
business_process = self.portal.business_process_module.erp5_default_business_process
pay_business_path = business_process['pay']
pay_business_path.setSource('account_module/bank')
pay_business_path.setDestination('account_module/bank')
pay_business_link = business_process['pay']
pay_business_link.setSource('account_module/bank')
pay_business_link.setDestination('account_module/bank')
@UnrestrictedMethod
def createInvoiceTransactionRule(self, resource=None):
......
......@@ -158,8 +158,8 @@ class TestMRPMixin(TestBPMMixin):
ready -------- partial_produced ------- done
"""
business_process = self.createBusinessProcess()
business_path_p2 = self.createBusinessPath(business_process)
business_path_p3 = self.createBusinessPath(business_process)
business_link_p2 = self.createBusinessLink(business_process)
business_link_p3 = self.createBusinessLink(business_process)
business_state_ready = self.createBusinessState(business_process)
business_state_partial = self.createBusinessState(business_process)
business_state_done = self.createBusinessState(business_process)
......@@ -171,7 +171,7 @@ class TestMRPMixin(TestBPMMixin):
destination = self.createOrganisation(title='destination')
business_process.edit(referential_date='stop_date')
business_path_p2.edit(id='p2',
business_link_p2.edit(id='p2',
predecessor_value=business_state_ready,
successor_value=business_state_partial,
quantity=1,
......@@ -181,7 +181,7 @@ class TestMRPMixin(TestBPMMixin):
destination_section_value=destination_section,
destination_value=destination,
)
business_path_p3.edit(id='p3',
business_link_p3.edit(id='p3',
predecessor_value=business_state_partial,
successor_value=business_state_done,
quantity=1,
......@@ -201,8 +201,8 @@ class TestMRPMixin(TestBPMMixin):
mrp/p3
"""
business_process = self.createBusinessProcess()
business_path_p2 = self.createBusinessPath(business_process)
business_path_p3 = self.createBusinessPath(business_process)
business_link_p2 = self.createBusinessLink(business_process)
business_link_p3 = self.createBusinessLink(business_process)
business_state_ready = self.createBusinessState(business_process)
business_state_partial = self.createBusinessState(business_process)
......@@ -213,7 +213,7 @@ class TestMRPMixin(TestBPMMixin):
destination = self.createOrganisation(title='destination')
business_process.edit(referential_date='stop_date')
business_path_p2.edit(id='p2',
business_link_p2.edit(id='p2',
predecessor_value=business_state_ready,
successor_value=business_state_partial,
quantity=1,
......@@ -223,7 +223,7 @@ class TestMRPMixin(TestBPMMixin):
destination_section_value=destination_section,
destination_value=destination,
)
business_path_p3.edit(id='p3',
business_link_p3.edit(id='p3',
predecessor_value=business_state_ready,
successor_value=business_state_partial,
quantity=1,
......@@ -280,7 +280,7 @@ class TestMRPImplementation(TestMRPMixin, ERP5TypeTestCase):
# organisations
path = business_process.objectValues(
portal_type=self.portal.getPortalBusinessPathTypeList())[0]
portal_type=self.portal.getPortalBusinessLinkTypeList())[0]
source_section = path.getSourceSection()
source = path.getSource()
destination_section = path.getDestinationSection()
......@@ -344,7 +344,7 @@ class TestMRPImplementation(TestMRPMixin, ERP5TypeTestCase):
# organisations
path = business_process.objectValues(
portal_type=self.portal.getPortalBusinessPathTypeList())[0]
portal_type=self.portal.getPortalBusinessLinkTypeList())[0]
source_section = path.getSourceSection()
source = path.getSource()
destination_section = path.getDestinationSection()
......@@ -413,7 +413,7 @@ class TestMRPImplementation(TestMRPMixin, ERP5TypeTestCase):
# organisations
path = business_process.objectValues(
portal_type=self.portal.getPortalBusinessPathTypeList())[0]
portal_type=self.portal.getPortalBusinessLinkTypeList())[0]
source_section = path.getSourceSection()
source = path.getSource()
destination_section = path.getDestinationSection()
......
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2009-2010 Nexedi SA and Contributors. All Rights Reserved.
......@@ -36,9 +37,9 @@ import transaction
class TestPayrollMixin(ERP5ReportTestCase, TestTradeModelLineMixin):
BUSINESS_PATH_CREATION_SEQUENCE_STRING = """
CreateBusinessProcess
CreateBusinessPath
CreateBusinessLink
CreateUrssafRoubaixOrganisation
ModifyBusinessPathTradePhase
ModifyBusinessLinkTradePhase
ModelSpecialiseBusinessProcess
Tic
"""
......@@ -841,14 +842,14 @@ class TestPayrollMixin(ERP5ReportTestCase, TestTradeModelLineMixin):
node.edit(title='Urssaf de Roubaix Tourcoing')
sequence.edit(urssaf_roubaix = node)
def stepModifyBusinessPathTradePhase(self, sequence=None, **kw):
business_path = sequence.get('business_path')
business_path.setTradePhaseList(['payroll/france/urssaf',
def stepModifyBusinessLinkTradePhase(self, sequence=None, **kw):
business_link = sequence.get('business_link')
business_link.setTradePhaseList(['payroll/france/urssaf',
'payroll/france/labour'])
business_path.setSourceValue(sequence.get('urssaf_roubaix'))
business_path.setSourceSectionValue(sequence.get('urssaf_roubaix'))
business_path.setDeliveryBuilderList(('portal_deliveries/pay_sheet_builder',))
sequence.edit(business_path=business_path)
business_link.setSourceValue(sequence.get('urssaf_roubaix'))
business_link.setSourceSectionValue(sequence.get('urssaf_roubaix'))
business_link.setDeliveryBuilderList(('portal_deliveries/pay_sheet_builder',))
sequence.edit(business_link=business_link)
def stepModelSpecialiseBusinessProcess(self, sequence=None, **kw):
model = sequence.get('model')
......@@ -3240,9 +3241,9 @@ class TestPayroll(TestPayrollMixin):
CreatePriceCurrency
CreateLabourOutputService
CreateBusinessProcess
CreateBusinessPath
CreateBusinessLink
CreateUrssafRoubaixOrganisation
ModifyBusinessPathTradePhase
ModifyBusinessLinkTradePhase
Tic
CheckModelWithoutRefValidity
"""
......@@ -3260,9 +3261,9 @@ class TestPayroll(TestPayrollMixin):
CreatePriceCurrency
CreateLabourOutputService
CreateBusinessProcess
CreateBusinessPath
CreateBusinessLink
CreateUrssafRoubaixOrganisation
ModifyBusinessPathTradePhase
ModifyBusinessLinkTradePhase
Tic
CheckModelWithoutDateValidity
"""
......@@ -3278,9 +3279,9 @@ class TestPayroll(TestPayrollMixin):
CreatePriceCurrency
CreateLabourOutputService
CreateBusinessProcess
CreateBusinessPath
CreateBusinessLink
CreateUrssafRoubaixOrganisation
ModifyBusinessPathTradePhase
ModifyBusinessLinkTradePhase
Tic
CheckModelDateValidity
"""
......@@ -3295,9 +3296,9 @@ class TestPayroll(TestPayrollMixin):
sequence_string = """
CreatePriceCurrency
CreateBusinessProcess
CreateBusinessPath
CreateBusinessLink
CreateUrssafRoubaixOrganisation
ModifyBusinessPathTradePhase
ModifyBusinessLinkTradePhase
Tic
CheckModelVersioning
"""
......
# -*- coding: utf-8 -*-
# -*- coding: shift_jis -*-
##############################################################################
# Copyright (c) 2009 Nexedi SA and Contributors. All Rights Reserved.
# Łukasz Nowak <luke@nexedi.com>
......@@ -56,9 +56,9 @@ class TestTradeModelLineMixin(TestBPMMixin):
sequence.edit(business_process=self.createBusinessProcess(
title=self.id()))
def stepCreateBusinessPath(self, sequence=None, **kw):
def stepCreateBusinessLink(self, sequence=None, **kw):
business_process = sequence.get('business_process')
sequence.edit(business_path=self.createBusinessPath(business_process))
sequence.edit(business_link=self.createBusinessLink(business_process))
class TestTradeModelLine(TestTradeModelLineMixin):
quiet = True
......@@ -101,10 +101,10 @@ class TestTradeModelLine(TestTradeModelLineMixin):
AGGREGATED_AMOUNT_LIST_COMMON_SEQUENCE_STRING = \
COMMON_DOCUMENTS_CREATION_SEQUENCE_STRING + """
CreateBusinessProcess
CreateBusinessPath
ModifyBusinessPathTaxing
CreateBusinessPath
ModifyBusinessPathDiscounting
CreateBusinessLink
ModifyBusinessLinkTaxing
CreateBusinessLink
ModifyBusinessLinkDiscounting
CreateTradeCondition
SpecialiseTradeConditionWithBusinessProcess
CreateTradeModelLine
......@@ -195,35 +195,35 @@ class TestTradeModelLine(TestTradeModelLineMixin):
portal_type='Trade Model Line',
**kw)
def stepModifyBusinessPathDiscounting(self, sequence=None, **kw):
def stepModifyBusinessLinkDiscounting(self, sequence=None, **kw):
category_tool = self.getCategoryTool()
predecessor = category_tool.trade_state.invoiced
successor = category_tool.trade_state.taxed
business_path = sequence.get('business_path')
business_link = sequence.get('business_link')
self.assertNotEqual(None, predecessor)
self.assertNotEqual(None, successor)
business_path.edit(
business_link.edit(
predecessor_value = predecessor,
successor_value = successor,
trade_phase = 'default/discount'
)
sequence.edit(business_path=None, business_path_discounting=business_path)
sequence.edit(business_link=None, business_link_discounting=business_link)
def stepModifyBusinessPathTaxing(self, sequence=None, **kw):
def stepModifyBusinessLinkTaxing(self, sequence=None, **kw):
category_tool = self.getCategoryTool()
predecessor = category_tool.trade_state.invoiced
successor = category_tool.trade_state.taxed
business_path = sequence.get('business_path')
business_link = sequence.get('business_link')
self.assertNotEqual(None, predecessor)
self.assertNotEqual(None, successor)
business_path.edit(
business_link.edit(
predecessor_value = predecessor,
successor_value = successor,
trade_phase = 'default/tax'
)
sequence.edit(business_path=None, business_path_taxing=business_path)
sequence.edit(business_link=None, business_link_taxing=business_link)
def stepAcceptDecisionQuantityInvoice(self, sequence=None, **kw):
invoice = sequence.get('invoice')
......@@ -506,15 +506,15 @@ class TestTradeModelLine(TestTradeModelLineMixin):
def stepCheckOrderLineDiscountedTaxedSimulation(self, sequence=None, **kw):
order_line = sequence.get('order_line_discounted_taxed')
business_path_discounting = sequence.get('business_path_discounting')
business_path_taxing = sequence.get('business_path_taxing')
business_link_discounting = sequence.get('business_link_discounting')
business_link_taxing = sequence.get('business_link_taxing')
price_currency = sequence.get('price_currency')
service_tax = sequence.get('service_tax')
service_discount = sequence.get('service_discount')
self.assertNotEqual(None, business_path_discounting)
self.assertNotEqual(None, business_path_taxing)
self.assertNotEqual(None, business_link_discounting)
self.assertNotEqual(None, business_link_taxing)
self.assertNotEqual(None, price_currency)
for trade_model_simulation_movement_list in \
......@@ -537,7 +537,7 @@ class TestTradeModelLine(TestTradeModelLineMixin):
)
self.assertEqual(
business_path_discounting,
business_link_discounting,
trade_model_simulation_movement_discount_complex.getCausalityValue()
)
......@@ -578,7 +578,7 @@ class TestTradeModelLine(TestTradeModelLineMixin):
)
self.assertEqual(
business_path_taxing,
business_link_taxing,
trade_model_simulation_movement_tax_complex.getCausalityValue()
)
......@@ -606,15 +606,15 @@ class TestTradeModelLine(TestTradeModelLineMixin):
def stepCheckOrderLineDiscountedSimulation(self, sequence=None, **kw):
order_line = sequence.get('order_line_discounted')
business_path_discounting = sequence.get('business_path_discounting')
business_path_taxing = sequence.get('business_path_taxing')
business_link_discounting = sequence.get('business_link_discounting')
business_link_taxing = sequence.get('business_link_taxing')
price_currency = sequence.get('price_currency')
service_tax = sequence.get('service_tax')
service_discount = sequence.get('service_discount')
self.assertNotEqual(None, business_path_discounting)
self.assertNotEqual(None, business_path_taxing)
self.assertNotEqual(None, business_link_discounting)
self.assertNotEqual(None, business_link_taxing)
self.assertNotEqual(None, price_currency)
for trade_model_simulation_movement_list in \
......@@ -637,7 +637,7 @@ class TestTradeModelLine(TestTradeModelLineMixin):
)
self.assertEqual(
business_path_discounting,
business_link_discounting,
trade_model_simulation_movement_discount_only.getCausalityValue()
)
......@@ -671,7 +671,7 @@ class TestTradeModelLine(TestTradeModelLineMixin):
trade_model_simulation_movement_tax_only.getTotalPrice())
self.assertEqual(
business_path_taxing,
business_link_taxing,
trade_model_simulation_movement_tax_only.getCausalityValue()
)
......@@ -700,9 +700,9 @@ class TestTradeModelLine(TestTradeModelLineMixin):
def stepCheckOrderLineTaxedSimulation(self, sequence=None, **kw):
order_line = sequence.get('order_line_taxed')
business_path = sequence.get('business_path_taxing')
business_link = sequence.get('business_link_taxing')
price_currency = sequence.get('price_currency')
self.assertNotEqual(None, business_path)
self.assertNotEqual(None, business_link)
self.assertNotEqual(None, price_currency)
for trade_model_simulation_movement_list in \
self.getTradeModelSimulationMovementList(order_line):
......@@ -717,7 +717,7 @@ class TestTradeModelLine(TestTradeModelLineMixin):
)
self.assertEqual(
business_path,
business_link,
trade_model_simulation_movement.getCausalityValue()
)
......@@ -1447,10 +1447,10 @@ class TestTradeModelLine(TestTradeModelLineMixin):
ORDER_SPECIALISE_AGGREGATED_AMOUNT_COMMON_SEQUENCE_STRING = \
COMMON_DOCUMENTS_CREATION_SEQUENCE_STRING + """
CreateBusinessProcess
CreateBusinessPath
ModifyBusinessPathTaxing
CreateBusinessPath
ModifyBusinessPathDiscounting
CreateBusinessLink
ModifyBusinessLinkTaxing
CreateBusinessLink
ModifyBusinessLinkDiscounting
CreateTradeCondition
SpecialiseTradeConditionWithBusinessProcess
CreateTradeModelLine
......@@ -1876,10 +1876,10 @@ class TestTradeModelLine(TestTradeModelLineMixin):
sequence_list = SequenceList()
sequence_string = self.COMMON_DOCUMENTS_CREATION_SEQUENCE_STRING + """
CreateBusinessProcess
CreateBusinessPath
ModifyBusinessPathTaxing
CreateBusinessPath
ModifyBusinessPathDiscounting
CreateBusinessLink
ModifyBusinessLinkTaxing
CreateBusinessLink
ModifyBusinessLinkDiscounting
CreateTradeCondition
SpecialiseTradeConditionWithBusinessProcess
CreateTradeModelLine
......@@ -1937,10 +1937,10 @@ class TestTradeModelLine(TestTradeModelLineMixin):
sequence_list = SequenceList()
sequence_string = self.COMMON_DOCUMENTS_CREATION_SEQUENCE_STRING + """
CreateBusinessProcess
CreateBusinessPath
ModifyBusinessPathTaxing
CreateBusinessPath
ModifyBusinessPathDiscounting
CreateBusinessLink
ModifyBusinessLinkTaxing
CreateBusinessLink
ModifyBusinessLinkDiscounting
CreateTradeCondition
SpecialiseTradeConditionWithBusinessProcess
CreateTradeModelLine
......@@ -1970,7 +1970,7 @@ class TestTradeModelLine(TestTradeModelLineMixin):
def test_BuildTradeModelLineAndAccountingFromOrder(self):
business_process = self.createBusinessProcess()
business_path = self.createBusinessPath(business_process,
business_link = self.createBusinessLink(business_process,
trade_phase='default/tax')
product = self.createResource('Product',
......@@ -2070,7 +2070,7 @@ class TestTradeModelLine(TestTradeModelLineMixin):
def test_BuildTradeModelLineAndAccountingFromInvoice(self):
business_process = self.createBusinessProcess()
business_path = self.createBusinessPath(business_process,
business_link = self.createBusinessLink(business_process,
trade_phase='default/tax')
product = self.createResource('Product',
......
......@@ -267,7 +267,7 @@ class ERP5TypeInformation(XMLObject,
'divergence_tester', 'target_solver',
'amount_generator', 'amount_generator_line', 'amount_generator_cell',
# Business Processes
'business_path', 'business_process',
'trade_model_path', 'business_link', 'business_process',
# Movement Group
'movement_group',
# Calendar
......
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