Commit e666cb6f authored by Sebastien Robin's avatar Sebastien Robin

* update getRemainingTradePhaseList API, trade_phase_list parameter

  is removed because it is not used, and anyway the name of this
  parameter is not good
* review code of getRemainingTradePhaseList in order to match API,
  we do not take into account an "explanation" argument any more
* update unit tests in order to test what the API describe. Also
  simplify unit test

git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@44376 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent 3f4134ff
......@@ -30,6 +30,7 @@
from AccessControl import ClassSecurityInfo
from Products.ERP5Type import Permissions, PropertySheet, interfaces
from Products.ERP5Type.TransactionalVariable import getTransactionalVariable
from Products.ERP5Type.XMLObject import XMLObject
from Products.ERP5.Document.Path import Path
from Products.ERP5.ExplanationCache import _getExplanationCache, _getBusinessLinkClosure
......@@ -594,8 +595,9 @@ class BusinessProcess(Path, XMLObject):
return False
return True
security.declareProtected(Permissions.AccessContentsInformation, 'getRemainingTradePhaseList')
def getRemainingTradePhaseList(self, explanation, business_link, trade_phase_list=None):
security.declareProtected(Permissions.AccessContentsInformation,
'getRemainingTradePhaseList')
def getRemainingTradePhaseList(self, business_link):
"""Returns the list of remaining trade phases which to be achieved
as part of a business process. This list is calculated by analysing
the graph of business link and trade states, starting from a given
......@@ -608,11 +610,6 @@ class BusinessProcess(Path, XMLObject):
business_link -- a Business Link document
trade_phase_list -- if provided, the result is filtered by it after
being collected - XXX-JPS - is this really useful ?
NOTE: this code has not been reviewed and needs review
NOTE: explanation is not involved here because we consider here that
self is the result of asUnionBusinessProcess and thus only contains
applicable Business Link to a given simulation subtree. Since the list
......@@ -622,25 +619,39 @@ class BusinessProcess(Path, XMLObject):
"""
remaining_trade_phase_list = []
trade_state = business_link.getSuccessor()
for link in [x for x in self.objectValues(portal_type="Business Link") \
if x.getPredecessor() == trade_state]:
# XXX When no simulations related to link, what should link.isCompleted return?
# if True we don't have way to add remaining trade phases to new movement
if not (link.getRelatedSimulationMovementValueList(explanation) and
link.isCompleted(explanation)):
remaining_trade_phase_list += link.getTradePhaseValueList()
tv = getTransactionalVariable(self)
# We might need a key which depends on the explanation
key = 'BusinessProcess_predecessor_successor_%s' % self.getRelativeUrl()
predecessor_successor_dict = tv.get(key, None)
if predecessor_successor_dict is None:
predecessor_successor_dict = {'predecessor':{},
'successor':{}}
for business_link in self.objectValues(portal_type="Business Link"):
for property_name in ('predecessor', 'successor'):
property_value = business_link.getProperty(property_name)
if property_value:
business_link_list = predecessor_successor_dict[property_name].\
setdefault(property_value, [])
business_link_list.append(business_link)
tv[key] = predecessor_successor_dict
business_link_list = predecessor_successor_dict['predecessor'].\
get(trade_state, [])
assert len(business_link_list) <= 1, \
"code is not able yet to manage this case"
for link in business_link_list:
remaining_trade_phase_list += link.getTradePhaseValueList()
# collect to successor direction recursively
state = link.getSuccessorValue()
state = link.getSuccessor()
if state is not None:
next_business_link_list = predecessor_successor_dict['successor'].\
get(state, [])
assert len(next_business_link_list) == 1, \
"code is not able yet to manage this case"
remaining_trade_phase_list.extend(
self.getRemainingTradePhaseList(explanation, state, None))
# filter just at once if given
if trade_phase_list is not None:
remaining_trade_phase_list = filter(
lambda x : x.getLogicalPath() in trade_phase_list,
remaining_trade_phase_list)
self.getRemainingTradePhaseList(
next_business_link_list[0]))
return remaining_trade_phase_list
......
......@@ -356,7 +356,7 @@ class ITradePhaseProcess(Interface):
trade_phase -- a Trade Phase category
"""
def getRemainingTradePhaseList(business_link, trade_phase_list=None):
def getRemainingTradePhaseList(business_link):
"""Returns the list of remaining trade phases which to be achieved
as part of a business process. This list is calculated by analysing
the graph of business link and trade states, starting from a given
......@@ -366,9 +366,6 @@ class ITradePhaseProcess(Interface):
business_link -- a Business Link document
trade_phase_list -- if provided, the result is filtered by it after
being collected - ???? useful ? XXX-JPS ?
NOTE: explanation is not involved here because we consider here that
self is the result of asUnionBusinessProcess and thus only contains
applicable Business Link to a given simulation subtree. Since the list
......@@ -491,4 +488,4 @@ class IBusinessProcess(ITradeModelPathProcess, IBusinessLinkProcess, IBuildableB
include_partially_buildable -- if set to True, also build partially
buildable business link. Else
only build strictly buildable link.
"""
\ No newline at end of file
"""
......@@ -302,129 +302,42 @@ class TestBPMImplementation(TestBPMMixin):
self.assertEquals('something',
business_path.getSource(context=context_movement, default='something'))
@newSimulationExpectedFailure
def test_BusinessState_getRemainingTradePhaseList(self):
"""
This test case is described for what trade_phase is remaining after the state.
In this case, root explanation is path of between "b" and "d", and
path of between "a" and "b" has a condition which simulation state of
explanation must be "ordered" to pass the path. (*1)
But this test case will be passed the condition.
(root explanation)
default/discount default/invoicing default/accounting
a ------------------ b ------------------- d -------------------- e
(cond="ordered") \ /
\ /
default/delivery \ / default/payment
\ /
\ /
\ /
\ /
\ /
\ /
\ /
c
This test case is described for what trade_phase is remaining after the
given business link.
"""
# define business process
category_tool = self.getCategoryTool()
business_process = self.createBusinessProcess()
business_link_a_b = self.createBusinessLink(business_process)
business_link_b_c = self.createBusinessLink(business_process)
business_link_b_d = self.createBusinessLink(business_process)
business_link_c_d = self.createBusinessLink(business_process)
business_link_d_e = self.createBusinessLink(business_process)
business_state_a = category_tool.trade_state.state_a
business_state_b = category_tool.trade_state.state_b
business_state_c = category_tool.trade_state.state_c
business_state_d = category_tool.trade_state.state_d
business_state_e = category_tool.trade_state.state_e
business_link_a_b.setPredecessorValue(business_state_a)
business_link_b_c.setPredecessorValue(business_state_b)
business_link_b_d.setPredecessorValue(business_state_b)
business_link_c_d.setPredecessorValue(business_state_c)
business_link_d_e.setPredecessorValue(business_state_d)
business_link_a_b.setSuccessorValue(business_state_b)
business_link_b_c.setSuccessorValue(business_state_c)
business_link_b_d.setSuccessorValue(business_state_d)
business_link_c_d.setSuccessorValue(business_state_d)
business_link_d_e.setSuccessorValue(business_state_e)
# set title for debug
business_link_a_b.edit(title="a_b")
business_link_b_c.edit(title="b_c")
business_link_b_d.edit(title="b_d")
business_link_c_d.edit(title="c_d")
business_link_d_e.edit(title="d_e")
# set trade_phase
business_link_a_b.edit(trade_phase=['default/discount'],
completed_state=['ordered']) # (*1)
business_link_b_c.edit(trade_phase=['default/delivery'])
business_link_b_d.edit(trade_phase=['default/invoicing'])
business_link_c_d.edit(trade_phase=['default/payment'])
business_link_d_e.edit(trade_phase=['default/accounting'])
# mock order
order = self.portal.sale_order_module.newContent(portal_type="Sale Order")
order_line = order.newContent(portal_type="Sale Order Line", quantity=1)
# make simulation
order.order()
self.stepTic()
applied_rule = order.getCausalityRelatedValue()
sm = applied_rule.contentValues(portal_type="Simulation Movement")[0]
sm.edit(causality_value=business_link_a_b)
# make other movements for each business path
applied_rule.newContent(portal_type="Simulation Movement",
causality_value=business_link_b_c,
order_value=order_line)
applied_rule.newContent(portal_type="Simulation Movement",
causality_value=business_link_b_d,
order_value=order_line)
applied_rule.newContent(portal_type="Simulation Movement",
causality_value=business_link_c_d,
order_value=order_line)
applied_rule.newContent(portal_type="Simulation Movement",
causality_value=business_link_d_e,
order_value=order_line)
self.stepTic()
trade_phase = self.portal.portal_categories.trade_phase.default
# assertion which getRemainingTradePhaseList must return category which will be passed
# discount is passed, business_link_a_b is already completed, because simulation state is "ordered"
self.assertEquals(set([trade_phase.delivery,
trade_phase.invoicing,
trade_phase.payment,
trade_phase.accounting]),
set(business_process.getRemainingTradePhaseList(order,
business_state_a)))
self.assertEquals(set([trade_phase.delivery,
trade_phase.invoicing,
trade_phase.payment,
trade_phase.accounting]),
set(business_process.getRemainingTradePhaseList(order,
business_state_b)))
self.assertEquals(set([trade_phase.payment,
trade_phase.accounting]),
set(business_process.getRemainingTradePhaseList(order,
business_state_c)))
self.assertEquals(set([trade_phase.accounting]),
set(business_process.getRemainingTradePhaseList(order,
business_state_d)))
# when trade_phase_list is defined in arguments, the result is filtered by base category.
self.assertEquals(set([trade_phase.delivery,
trade_phase.accounting]),
set(business_process\
.getRemainingTradePhaseList(order, business_state_a,
trade_phase_list=['default/delivery',
'default/accounting'])))
business_link_order = self.createBusinessLink(business_process,
title='order', id='order',
trade_phase='default/order')
business_link_deliver = self.createBusinessLink(business_process,
title='deliver', id='deliver',
trade_phase='default/delivery')
business_link_invoice = self.createBusinessLink(business_process,
title='invoice', id='invoice',
trade_phase='default/invoicing')
trade_state = category_tool.trade_state
business_link_order.setSuccessorValue(trade_state.ordered)
business_link_deliver.setPredecessorValue(trade_state.ordered)
business_link_deliver.setSuccessorValue(trade_state.delivered)
business_link_invoice.setPredecessorValue(trade_state.delivered)
business_link_invoice.setSuccessorValue(trade_state.invoiced)
trade_phase = category_tool.trade_phase.default
self.assertEquals([trade_phase.delivery,
trade_phase.invoicing],
business_process.getRemainingTradePhaseList(
business_process.order))
self.assertEquals([trade_phase.invoicing],
business_process.getRemainingTradePhaseList(
business_process.deliver))
self.assertEquals([],
business_process.getRemainingTradePhaseList(
business_process.invoice))
@newSimulationExpectedFailure
def test_BusinessLink_calculateExpectedDate(self):
......
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