Commit 356bfc19 authored by Romain Courteaud's avatar Romain Courteaud

Add a new functionality to the configuration of the SupplyChain.

Now, if a resource is associated to a Supply Link representing a production, no
sourcing will be generated for this resource.


git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@4135 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent 7abbf29c
......@@ -88,6 +88,55 @@ class SupplyChain(Path, XMLObject):
str(self.getRelativeUrl())
return result
security.declareProtected(Permissions.View,
'getNextSupplyLinkList')
def getNextSupplyLinkList(self, current_supply_link):
"""
Return the previous SupplyLink list.
"""
supply_link_list = self.objectValues(
portal_type=self.supply_link_portal_type)
# Search next link
next_node_value = current_supply_link.getNextNodeValue()
next_supply_link_list = [x for x in supply_link_list if \
x.getCurrentNodeValue() == next_node_value]
# Prevent infinite loop
if current_supply_link in next_supply_link_list:
next_supply_link_list.remove(current_supply_link)
# Get only production node in the list, or return the entire list
next_production_list = [x for x in next_supply_link_list \
if x.isProductionSupplyLink()]
if next_production_list != []:
next_supply_link_list = next_production_list
return next_supply_link_list
security.declareProtected(Permissions.View,
'getNextProductionSupplyLinkList')
def getNextProductionSupplyLinkList(self, current_supply_link):
"""
Return the next SupplyLink which represents a production,
if there is one.
No recursion is done.
"""
next_supply_link_list = self.getNextSupplyLinkList(current_supply_link)
return [x for x in next_supply_link_list if x.isProductionSupplyLink()]
security.declareProtected(Permissions.View,
'getNextProductionIndustrialPhaseList')
def getNextProductionIndustrialPhaseList(self, current_supply_link):
"""
Return all next industrial phase representing a production.
"""
ind_phase_dict = {}
for link in self.getNextProductionSupplyLinkList(current_supply_link):
for ind_phase in link.getIndustrialPhaseValueList():
ind_phase_dict[ind_phase] = 1
# Remove None value, and generate the list
ind_phase_dict.pop(None, None)
return ind_phase_dict.keys()
security.declareProtected(Permissions.View,
'getPreviousSupplyLinkList')
def getPreviousSupplyLinkList(self, current_supply_link):
"""
Return the previous SupplyLink list.
......@@ -100,7 +149,7 @@ class SupplyChain(Path, XMLObject):
current_node_value = current_supply_link.getCurrentNodeValue()
previous_supply_link_list = [
x for x in supply_link_list if\
x.getDestinationValue() == current_node_value]
x.getNextNodeValue() == current_node_value]
# Prevent infinite loop
if current_supply_link in previous_supply_link_list:
previous_supply_link_list.remove(current_supply_link)
......
......@@ -97,46 +97,65 @@ class SupplyLink(Path, XMLObject):
node = self.getSourceValue()
return node
security.declareProtected(Permissions.View, 'getNextNodeValue')
def getNextNodeValue(self):
"""
Return the node used to find the next SupplyLink
"""
return self.getDestinationValue()
security.declareProtected(Permissions.View, 'test')
def test(self, movement, concurrent_supply_link_list):
"""
Test if the current link can expand this movement.
Futur implementation have to return properties value
(like quantity) calculated.
This method is called only on packing list supply link.
"""
# XXX This method has to be rewritten.
# Predicate must be used.
# Current implementation is enough now for customers.
result = 0
resource = movement.getResource()
if resource.find('operation/') == -1:
# XXX reject operation
if concurrent_supply_link_list == []:
result = 1
# Test if the movement correspond to the resource to produced
ind_phase_list = movement.getIndustrialPhaseValueList()
if ind_phase_list != []:
# Is this SupplyLink in the route to the previous production node ?
supply_chain = self.getParent()
previous_ind_phase_list =\
supply_chain.getPreviousProductionIndustrialPhaseList(self)
for ind_phase in ind_phase_list:
if ind_phase in previous_ind_phase_list:
result = 1
break
else:
# How to delivered raw materials ?
# XXX This method has to be rewritten.
# Predicate must be used.
if len(concurrent_supply_link_list) > 1:
raise "SupplyChainError",\
"SupplyChain unable to find route."
else:
# Test if the movement correspond to the resource to produced
ind_phase_list = movement.getIndustrialPhaseValueList()
if ind_phase_list != []:
# Is this SupplyLink in the route to the previous production node ?
# Check if raw material is create by a production link or a packing
# list link.
supply_chain = self.getParent()
next_industrial_phase_list = \
supply_chain.getNextProductionIndustrialPhaseList(self)
ind_phase_id_list = [x.getId() for x in next_industrial_phase_list]
# Get the transformation to use
applied_rule = movement.getParent()
rule = applied_rule.getSpecialiseValue()
transformation = rule.getTransformation(applied_rule)
# Call getAggregatedAmountList
amount_list = transformation.getAggregatedAmountList(
movement.getParent().getParent(),
ind_phase_id_list=ind_phase_id_list)
resource_list = [x.getResourceValue() for x in amount_list]
current_resource = movement.getResourceValue()
if current_resource not in resource_list:
# We can delivered this resource
supply_chain = self.getParent()
previous_ind_phase_list =\
supply_chain.getPreviousProductionIndustrialPhaseList(self)
for ind_phase in ind_phase_list:
if ind_phase in previous_ind_phase_list:
result = 1
break
else:
# How to delivered raw materials ?
# First dirty implementation...
if len(concurrent_supply_link_list) > 1:
raise "SupplyChainError",\
"SupplyChain unable to find route."
else:
supply_chain = self.getParent()
previous_ind_phase_list =\
supply_chain.getPreviousProductionIndustrialPhaseList(self)
if len(previous_ind_phase_list) == 0:
result = 1
if len(previous_ind_phase_list) == 0:
result = 1
return result
security.declareProtected(Permissions.View, 'getStartDate')
......
......@@ -264,22 +264,7 @@ class TransformationRule(Rule):
category_list = parent_movement.getVariationCategoryList(
base_category_list=base_category_list)
# Get the transformation to use
production_order_movement = applied_rule.getRootSimulationMovement().\
getOrderValue()
# XXX Acquisition can be use instead
parent_uid = production_order_movement.getParent().getUid()
explanation_uid = production_order_movement.getExplanationUid()
if parent_uid == explanation_uid:
production_order_line = production_order_movement
else:
production_order_line = production_order_movement.getParent()
line_transformation = production_order_line.objectValues(
portal_type=self.getPortalTransformationTypeList())
if len(line_transformation)==1:
transformation = line_transformation[0]
else:
transformation = production_order_line.getSpecialiseValue(
portal_type=self.getPortalTransformationTypeList())
transformation = self.getTransformation(applied_rule)
# Generate the fake context
tmp_context = parent_movement.asContext(
context=parent_movement,
......
......@@ -92,6 +92,29 @@ class TransformationSourcingRuleMixin(ExtensionClass.Base):
# Update movement properties
movement.edit(**(movement_dict[movement_id]))
security.declareProtected(Permissions.View, 'getTransformation')
def getTransformation(self, applied_rule):
"""
Get transformation related to used by the applied rule.
"""
production_order_movement = applied_rule.getRootSimulationMovement().\
getOrderValue()
# XXX Acquisition can be use instead
parent_uid = production_order_movement.getParent().getUid()
explanation_uid = production_order_movement.getExplanationUid()
if parent_uid == explanation_uid:
production_order_line = production_order_movement
else:
production_order_line = production_order_movement.getParent()
line_transformation = production_order_line.objectValues(
portal_type=self.getPortalTransformationTypeList())
if len(line_transformation)==1:
transformation = line_transformation[0]
else:
transformation = production_order_line.getSpecialiseValue(
portal_type=self.getPortalTransformationTypeList())
return transformation
class TransformationSourcingRule(Rule):
"""
Transformation Sourcing Rule object make sure
......
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