Commit 43856635 authored by Sebastien Robin's avatar Sebastien Robin

Order Builders: remove the whole testOrderBuilder passing

So all newSimulation expected failures are removed. Make
generateMovementListForStockOptimisation looking min_flow and max_delay
on supply lines.

Introduce a getNextAlertInventoryDate in addition to
getNextNegativeInventoryDate. This allows to know when an inventory
will be below a reference quantity. This is particularly helpful
to know when an inventory is below the minimal admitted stock
parent b9782cda
......@@ -565,12 +565,22 @@ class Resource(XMLObject, XMLMatrix, VariatedMixin):
'getNextNegativeInventoryDate')
def getNextNegativeInventoryDate(self, **kw):
"""
Returns list of inventory grouped by section or site
Returns next date where the inventory will be negative
"""
return self.getNextAlertInventoryDate(
reference_quantity=0, **kw)
security.declareProtected(Permissions.AccessContentsInformation,
'getNextNegativeInventoryDate')
def getNextAlertInventoryDate(self, reference_quantity=0, **kw):
"""
Returns next date where the inventory will be below reference
quantity
"""
kw['resource_uid'] = self.getUid()
portal_simulation = self.getPortalObject().portal_simulation
return portal_simulation.getNextNegativeInventoryDate(**kw)
return portal_simulation.getNextAlertInventoryDate(
reference_quantity=reference_quantity, **kw)
# Asset Price API
security.declareProtected(Permissions.AccessContentsInformation,
......
......@@ -2048,29 +2048,41 @@ class SimulationTool(BaseTool):
assert len(inventory_list) == 1
return inventory_list[0]
security.declareProtected(Permissions.AccessContentsInformation,
'getNextDeficientInventoryDate')
def getNextAlertInventoryDate(self, reference_quantity=0, src__=0, **kw):
"""
Give the next date where the quantity is lower than the
reference quantity.
"""
result = None
# First look at current inventory, we might have already an inventory
# lower than reference_quantity
current_inventory = self.getCurrentInventory(**kw)
if current_inventory < reference_quantity:
result = DateTime()
else:
result = self.getInventoryList(src__=src__,
sort_on = (('date', 'ascending'),), group_by_movement=1, **kw)
if src__ :
return result
total_inventory = 0.
for inventory in result:
if inventory['inventory'] is not None:
total_inventory += inventory['inventory']
if total_inventory < reference_quantity:
result = inventory['date']
break
return result
security.declareProtected(Permissions.AccessContentsInformation,
'getNextNegativeInventoryDate')
def getNextNegativeInventoryDate(self, src__=0, **kw):
def getNextNegativeInventoryDate(self, **kw):
"""
Returns statistics of inventory grouped by section or site
Deficient Inventory with a reference_quantity of 0, so when the
stock will be negative
"""
#sql_kw = self._generateSQLKeywordDict(order_by_expression='stock.date', **kw)
#sql_kw['group_by_expression'] = 'stock.uid'
#sql_kw['order_by_expression'] = 'stock.date'
result = self.getInventoryList(src__=src__,
sort_on = (('date', 'ascending'),), group_by_movement=1, **kw)
if src__ :
return result
total_inventory = 0.
for inventory in result:
if inventory['inventory'] is not None:
total_inventory += inventory['inventory']
if total_inventory < 0:
return inventory['date']
return None
return self.getNextAlertInventoryDate(reference_quantity=0, **kw)
#######################################################
# Traceability management
......
......@@ -183,6 +183,18 @@ class BuilderMixin(XMLObject, Amount, Predicate):
group_by_section=0,
**kw)
id_count = 0
# min_flow and max_delay are stored on a supply line. By default
# we can get them through a method having the right supply type prefix
# like getPurchaseSupplyLineMinFlow. So we need to guess the supply prefix
supply_prefix = ''
delivery_type = self.getDeliveryPortalType()
portal = self.getPortalObject()
if delivery_type in portal.getPortalPurchaseTypeList():
supply_prefix = 'purchase'
elif delivery_type in portal.getPortalSaleTypeList():
supply_prefix = 'sale'
else:
supply_prefix = 'internal'
for inventory_item in sql_list:
if (inventory_item.inventory is not None):
dumb_movement = inventory_item.getObject()
......@@ -191,27 +203,29 @@ class BuilderMixin(XMLObject, Amount, Predicate):
str(id_count))
id_count += 1
resource_portal_type = self.getResourcePortalType()
resource = portal.portal_catalog.getObject(inventory_item.resource_uid)
assert resource.getPortalType() == resource_portal_type
movement.edit(
resource=inventory_item.resource_relative_url,
variation_category_list=dumb_movement.getVariationCategoryList(),
destination_value=self.getDestinationValue(),
resource_portal_type=resource_portal_type,
destination_section_value=self.getDestinationSectionValue())
# We can do other test on inventory here
# XXX It is better if it can be sql parameters
#resource_portal_type = self.getResourcePortalType()
resource = movement.getResourceValue()
# FIXME: XXX Those properties are defined on a supply line !!
# min_flow, max_delay
min_flow = resource.getMinFlow(0)
assert resource.getPortalType() == resource_portal_type
if round(inventory_item.inventory, 5) < min_flow:
stop_date = resource.getNextNegativeInventoryDate(
# Get min_flow, max_delay on supply line
min_flow = 0
max_delay = 0
min_stock = 0
if supply_prefix:
min_flow = resource.getProperty(supply_prefix + '_supply_line_min_flow', 0)
max_delay = resource.getProperty(supply_prefix + '_supply_line_max_delay', 0)
min_stock = resource.getProperty(supply_prefix + '_supply_line_min_stock', 0)
if round(inventory_item.inventory, 5) < min_stock:
stop_date = resource.getNextAlertInventoryDate(
reference_quantity=min_stock,
variation_text=movement.getVariationText(),
from_date=DateTime(),
**kw)
if stop_date is None:
stop_date = DateTime()
assert stop_date is not None
max_delay = resource.getMaxDelay(0)
movement.edit(
start_date=DateTime(((stop_date-max_delay).Date())),
......
......@@ -55,8 +55,8 @@ class TestOrderBuilderMixin(TestOrderMixin):
# defaults
decrease_quantity = 1.0
max_delay = 4.0
min_flow = 7.0
max_delay = 0.0
min_flow = 0.0
def afterSetUp(self):
"""
......@@ -76,7 +76,7 @@ class TestOrderBuilderMixin(TestOrderMixin):
Sets min_flow on resource
"""
resource = sequence.get('resource')
resource.edit(min_flow=self.min_flow)
resource.edit(purchase_supply_line_min_flow=self.min_flow)
def stepFillOrderBuilder(self, sequence):
"""
......@@ -169,7 +169,7 @@ class TestOrderBuilderMixin(TestOrderMixin):
# XXX: ... and for more lines/cells too
order_line, = order.contentValues(portal_type=self.order_line_portal_type)
self.assertEqual(order_line.getResourceValue(), resource)
self.assertEqual(order_line.getTotalQuantity(), self.min_flow)
self.assertEqual(order_line.getTotalQuantity(), self.wanted_quantity)
def stepBuildOrderBuilder(self, sequence):
"""
......@@ -204,7 +204,7 @@ class TestOrderBuilderMixin(TestOrderMixin):
packing_list = packing_list_module.newContent(
portal_type = self.packing_list_portal_type,
source_value = organisation,
start_date = self.datetime,
start_date = self.datetime+10,
specialise = self.business_process,
)
......@@ -214,6 +214,13 @@ class TestOrderBuilderMixin(TestOrderMixin):
quantity = self.decrease_quantity,
)
self.decrease_quantity_matrix = {
'variation/%s/blue' % resource.getRelativeUrl() : 1.0,
'variation/%s/green' % resource.getRelativeUrl() : 2.0,
}
self.wanted_quantity_matrix = self.decrease_quantity_matrix.copy()
packing_list_line.setVariationCategoryList(
self.decrease_quantity_matrix.keys(),
)
......@@ -251,7 +258,7 @@ class TestOrderBuilderMixin(TestOrderMixin):
packing_list = packing_list_module.newContent(
portal_type = self.packing_list_portal_type,
source_value = organisation,
start_date = self.datetime+14,
start_date = self.datetime+10,
specialise = self.business_process,
)
......@@ -263,6 +270,23 @@ class TestOrderBuilderMixin(TestOrderMixin):
packing_list.confirm()
def stepCreateVariatedResource(self, sequence=None, sequence_list=None, \
**kw):
"""
Create a resource with variation
"""
portal = self.getPortal()
resource_module = portal.getDefaultModule(self.resource_portal_type)
resource = resource_module.newContent(portal_type=self.resource_portal_type)
resource.edit(
title = "VariatedResource%s" % resource.getId(),
variation_base_category_list = ['variation'],
)
for color in ['blue', 'green']:
resource.newContent(portal_type='Product Individual Variation',
id=color, title=color)
sequence.edit(resource=resource)
class TestOrderBuilder(TestOrderBuilderMixin, ERP5TypeTestCase):
"""
Test Order Builder functionality
......@@ -301,14 +325,12 @@ class TestOrderBuilder(TestOrderBuilderMixin, ERP5TypeTestCase):
str(self.datetime.earliestTime()
+ self.order_builder_hardcoded_time_diff))
# We add 4 days to start date to reflect delays
self.wanted_stop_date = self.wanted_start_date + 4
self.wanted_stop_date = self.wanted_start_date
sequence_list = SequenceList()
sequence_list.addSequenceString(self.common_sequence_string)
sequence_list.play(self)
@newSimulationExpectedFailure
def test_01a_simpleOrderBuilderVariatedResource(self, quiet=0, run=run_all_test):
"""
Test simple Order Builder for Variated Resource
......@@ -338,25 +360,17 @@ class TestOrderBuilder(TestOrderBuilderMixin, ERP5TypeTestCase):
self.wanted_stop_date = self.wanted_start_date
self.decrease_quantity_matrix = {
'size/Man' : 1.0,
'size/Woman' : 2.0,
}
self.wanted_quantity_matrix = self.decrease_quantity_matrix.copy()
sequence_list = SequenceList()
sequence_list.addSequenceString(sequence_string)
sequence_list.play(self)
@newSimulationExpectedFailure
def test_02_maxDelayResourceOrderBuilder(self, quiet=0, run=run_all_test):
"""
Test max_delay impact on generated order start date
"""
if not run: return
self.max_delay = 14.0
self.max_delay = 4.0
self.wanted_quantity = 1.0
self.wanted_start_date = DateTime(
......@@ -372,7 +386,6 @@ class TestOrderBuilder(TestOrderBuilderMixin, ERP5TypeTestCase):
sequence_list.addSequenceString(self.common_sequence_string)
sequence_list.play(self)
@newSimulationExpectedFailure
def test_03_minFlowResourceOrderBuilder(self, quiet=0, run=run_all_test):
"""
Test min_flow impact on generated order line quantity
......@@ -390,20 +403,9 @@ class TestOrderBuilder(TestOrderBuilderMixin, ERP5TypeTestCase):
sequence_list.addSequenceString(self.common_sequence_string)
# case when min_flow > decreased_quantity
self.min_flow = 144.0
self.wanted_quantity = self.min_flow + self.decrease_quantity
# why to order more than needed?
# self.wanted_quantity = self.min_flow
sequence_list.play(self)
# case when min_flow < decreased_quantity
self.min_flow = 15.0
self.decrease_quantity = 20.0
self.wanted_quantity = self.min_flow + self.decrease_quantity
# why to order more than needed?
# self.wanted_quantity = self.decreased_quantity
self.wanted_quantity = self.min_flow
sequence_list.play(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