Commit 317395ad authored by Xiaowu Zhang's avatar Xiaowu Zhang Committed by Cédric Le Ninivin

builder: add security stock management

use  "stock definition supply" which overwrite default parameter in
purchase supply for the date included in "valid from" et "valid until"
if the value is not defined in "stock defintion supply", the default
parameter is used
parent 3a51dd94
...@@ -293,37 +293,31 @@ class BuilderMixin(XMLObject, Amount, Predicate): ...@@ -293,37 +293,31 @@ class BuilderMixin(XMLObject, Amount, Predicate):
portal = self.getPortalObject() portal = self.getPortalObject()
if from_date is None: if from_date is None:
from_date = DateTime().earliestTime() from_date = DateTime().earliestTime()
#resource related variable
# Initiate Conditions taken from Yusei T. Original Script
# XXX to be cleaned
min_inventory = supply.getMinStock()
resource_value = supply.getResourceValue() resource_value = supply.getResourceValue()
default_quantity_unit_value = resource_value.getDefaultQuantityUnitValue() default_quantity_unit_value = resource_value.getDefaultQuantityUnitValue()
order_quantity_unit_value = supply.getOrderQuantityUnitValue()
flow_quantity_unit_value = supply.getFlowQuantityUnitValue()
time_quantity_unit_value = supply.getTimeQuantityUnitValue()
time_second_ratio = resource_value.getQuantityUnitDefinitionRatio(portal.portal_categories.quantity_unit.time.second) time_second_ratio = resource_value.getQuantityUnitDefinitionRatio(portal.portal_categories.quantity_unit.time.second)
min_delay = supply.getMinDelay() default_quantity_unit_relative_url = default_quantity_unit_value.getCategoryRelativeUrl()
max_delay = supply.getMaxDelay()
min_order_delay = supply.getMinOrderDelay()
max_order_delay = supply.getMaxOrderDelay()
min_order = supply.getMinOrderQuantity()
max_order = supply.getMaxOrderQuantity()
# Initiate conversions def getCorrectSupplyParameter(selected_supply, default_supply, method_id):
# XXX To be cleaned if selected_supply == default_supply:
return getattr(default_supply, method_id)()
selected_supply_method = getattr(selected_supply, method_id)
default_supply_method = getattr(default_supply, method_id)
return selected_supply_method() or default_supply_method()
def getMinMaxDelayAndOrderDelay(selected_supply, default_supply):
time_quantity_unit_value = getCorrectSupplyParameter(selected_supply, default_supply, 'getTimeQuantityUnitValue')
min_delay_second = 0 min_delay_second = 0
max_delay_second = 0 max_delay_second = 0
min_order_delay_second = 0 min_order_delay_second = 0
max_order_delay_second = 0 max_order_delay_second = 0
min_order_in_default_quantity_unit = 0
max_order_in_default_quantity_unit = float('inf')
default_quantity_unit_relative_url = default_quantity_unit_value.getCategoryRelativeUrl()
if time_quantity_unit_value is not None: if time_quantity_unit_value is not None:
min_delay = getCorrectSupplyParameter(selected_supply, default_supply, 'getMinDelay')
max_delay = getCorrectSupplyParameter(selected_supply, default_supply, 'getMaxDelay')
min_order_delay = getCorrectSupplyParameter(selected_supply, default_supply, 'getMinOrderDelay')
max_order_delay = getCorrectSupplyParameter(selected_supply, default_supply, 'getMaxOrderDelay')
time_second_conversion_ratio = resource_value.getQuantityUnitDefinitionRatio(time_quantity_unit_value) / time_second_ratio time_second_conversion_ratio = resource_value.getQuantityUnitDefinitionRatio(time_quantity_unit_value) / time_second_ratio
if min_delay: if min_delay:
min_delay_second = min_delay * time_second_conversion_ratio min_delay_second = min_delay * time_second_conversion_ratio
if max_delay: if max_delay:
...@@ -332,23 +326,40 @@ class BuilderMixin(XMLObject, Amount, Predicate): ...@@ -332,23 +326,40 @@ class BuilderMixin(XMLObject, Amount, Predicate):
min_order_delay_second = min_order_delay * time_second_conversion_ratio min_order_delay_second = min_order_delay * time_second_conversion_ratio
if max_delay: if max_delay:
max_order_delay_second = max_order_delay * time_second_conversion_ratio max_order_delay_second = max_order_delay * time_second_conversion_ratio
return min_delay_second, max_delay_second, min_order_delay_second, max_order_delay_second
min_delay_second, max_delay_second, min_order_delay_second, max_order_delay_second = getMinMaxDelayAndOrderDelay(supply, supply)
def getOrderQuantityUnitDefaultQuantityUnitConversionRatio(selected_supply, default_supply):
order_quantity_unit_value = getCorrectSupplyParameter(selected_supply, default_supply, 'getOrderQuantityUnitValue')
order_quantity_unit_default_quantity_unit_conversion_ratio = 1
#min_order_in_default_quantity_unit = 0
#max_order_in_default_quantity_unit = float('inf')
if order_quantity_unit_value is not None: if order_quantity_unit_value is not None:
order_quantity_unit_relative_url = order_quantity_unit_value.getCategoryRelativeUrl() order_quantity_unit_relative_url = order_quantity_unit_value.getCategoryRelativeUrl()
order_quantity_unit_default_quantity_unit_conversion_ratio = resource_value.convertQuantity(1, order_quantity_unit_relative_url, default_quantity_unit_relative_url) order_quantity_unit_default_quantity_unit_conversion_ratio = resource_value.convertQuantity(1, order_quantity_unit_relative_url, default_quantity_unit_relative_url)
"""
those are not used yet
min_order = supply.getMinOrderQuantity()
max_order = supply.getMaxOrderQuantity()
if min_order: if min_order:
min_order_in_default_quantity_unit = min_order * order_quantity_unit_default_quantity_unit_conversion_ratio min_order_in_default_quantity_unit = min_order * order_quantity_unit_default_quantity_unit_conversion_ratio
if max_order: if max_order:
max_order_in_default_quantity_unit = max_order * order_quantity_unit_default_quantity_unit_conversion_ratio max_order_in_default_quantity_unit = max_order * order_quantity_unit_default_quantity_unit_conversion_ratio
else: """
order_quantity_unit_default_quantity_unit_conversion_ratio = 1 return order_quantity_unit_default_quantity_unit_conversion_ratio
order_quantity_unit_default_quantity_unit_conversion_ratio = getOrderQuantityUnitDefaultQuantityUnitConversionRatio(supply, supply)
def getDefaultQuantityUnitFlowQuantityUnitConversionRatio(selected_supply, default_supply):
flow_quantity_unit_value = getCorrectSupplyParameter(selected_supply, default_supply, 'getFlowQuantityUnitValue')
default_quantity_unit_flow_quantity_unit_conversion_ratio = 1
if flow_quantity_unit_value is not None: if flow_quantity_unit_value is not None:
flow_quantity_unit_relative_url = flow_quantity_unit_value.getCategoryRelativeUrl() flow_quantity_unit_relative_url = flow_quantity_unit_value.getCategoryRelativeUrl()
flow_quantity_unit_default_quantity_unit_conversion_ratio = resource_value.convertQuantity(1, flow_quantity_unit_relative_url, default_quantity_unit_relative_url) flow_quantity_unit_default_quantity_unit_conversion_ratio = resource_value.convertQuantity(1, flow_quantity_unit_relative_url, default_quantity_unit_relative_url)
default_quantity_unit_flow_quantity_unit_conversion_ratio = 1 / flow_quantity_unit_default_quantity_unit_conversion_ratio default_quantity_unit_flow_quantity_unit_conversion_ratio = 1 / flow_quantity_unit_default_quantity_unit_conversion_ratio
else: return default_quantity_unit_flow_quantity_unit_conversion_ratio
default_quantity_unit_flow_quantity_unit_conversion_ratio = 1
default_quantity_unit_flow_quantity_unit_conversion_ratio = getDefaultQuantityUnitFlowQuantityUnitConversionRatio(supply, supply)
def getPreviousValidDate(date): def getPreviousValidDate(date):
# We suppose the system has not been configured to handled per hour commands # We suppose the system has not been configured to handled per hour commands
...@@ -359,23 +370,29 @@ class BuilderMixin(XMLObject, Amount, Predicate): ...@@ -359,23 +370,29 @@ class BuilderMixin(XMLObject, Amount, Predicate):
factor=-1)).earliestTime() factor=-1)).earliestTime()
# Function to define the minimal quantity to be ordered # Function to define the minimal quantity to be ordered
def minimalQuantity(quantity, date): def minimalQuantity(selected_supply,default_supply, quantity, date):
# Initiate variables to match original script from Yusei T. # Initiate variables to match original script from Yusei T.
# XXX To be cleaned # XXX To be cleaned
if selected_supply != default_supply:
delay_second = max_delay_second or min_delay_second or 0 local_min_delay_second, local_max_delay_second, local_min_order_delay_second, local_max_order_delay_second = getMinMaxDelayAndOrderDelay(selected_supply, default_supply)
local_order_quantity_unit_default_quantity_unit_conversion_ratio = getOrderQuantityUnitDefaultQuantityUnitConversionRatio(selected_supply, default_supply)
local_order_quantity_unit_value = getCorrectSupplyParameter(selected_supply, default_supply, 'getOrderQuantityUnitValue')
else:
local_min_delay_second, local_max_delay_second, local_min_order_delay_second, local_max_order_delay_second = min_delay_second, max_delay_second, min_order_delay_second, max_order_delay_second
local_order_quantity_unit_default_quantity_unit_conversion_ratio = order_quantity_unit_default_quantity_unit_conversion_ratio
local_order_quantity_unit_value = original_order_quantity_unit_value
delay_second = local_max_delay_second or local_min_delay_second or 0
limit_date = getPreviousValidDate(date) limit_date = getPreviousValidDate(date)
start_date = getPreviousValidDate( start_date = getPreviousValidDate(
addToDate(limit_date, second=-delay_second) addToDate(limit_date, second=-delay_second)
) )
stop_date = addToDate(start_date, second=delay_second).earliestTime() stop_date = addToDate(start_date, second=delay_second).earliestTime()
order_delay_second = max_order_delay_second or min_order_delay_second or 0 order_delay_second = local_max_order_delay_second or local_min_order_delay_second or 0
effective_date = addToDate(start_date, second=-order_delay_second) effective_date = addToDate(start_date, second=-order_delay_second)
order_quantity = ceil(quantity / local_order_quantity_unit_default_quantity_unit_conversion_ratio)
order_quantity = ceil(quantity / order_quantity_unit_default_quantity_unit_conversion_ratio) quantity = order_quantity * local_order_quantity_unit_default_quantity_unit_conversion_ratio
quantity = order_quantity * order_quantity_unit_default_quantity_unit_conversion_ratio return order_quantity, local_order_quantity_unit_value, effective_date, start_date, stop_date, quantity
return order_quantity, order_quantity_unit_value, effective_date, start_date, stop_date, quantity
resource_portal_type = resource_value.getPortalType() resource_portal_type = resource_value.getPortalType()
def newMovement(effective_date, start_date, stop_date, quantity, quantity_unit): def newMovement(effective_date, start_date, stop_date, quantity, quantity_unit):
...@@ -475,17 +492,42 @@ class BuilderMixin(XMLObject, Amount, Predicate): ...@@ -475,17 +492,42 @@ class BuilderMixin(XMLObject, Amount, Predicate):
node_uid=supply.getDestinationUid() node_uid=supply.getDestinationUid()
) + history_list ) + history_list
min_stock_value = supply.getMinOrderQuantity() / default_quantity_unit_flow_quantity_unit_conversion_ratio
factor = supply.getMinFlow()
next_period_history_list = [] next_period_history_list = []
#self.log(limit_date_list)
def chooseCorrectSupply(default_supply,start_date_range_min,start_date_range_max):
search_dict = {
'predicate.start_date_range_min':{'query':start_date_range_min, 'range':'ngt'},
'predicate.start_date_range_max':{'query':start_date_range_max, 'range':'nlt'},
}
stock_definition_supply_list = portal.portal_catalog(
portal_type=('Purchase Supply Cell', 'Purchase Supply Line'),
strict_resource_uid=resource_value.getUid(),
default_ledger_uid=portal.portal_categories.ledger.stock.definition.getUid(),
validation_state='validated',
**search_dict
)
if len(stock_definition_supply_list):
return stock_definition_supply_list[0]
return default_supply
original_min_stock_value = supply.getMinOrderQuantity() / default_quantity_unit_flow_quantity_unit_conversion_ratio
original_factor = supply.getMinFlow()
original_order_quantity_unit_value = supply.getOrderQuantityUnitValue()
# Create a movement per period # Create a movement per period
for period_start_date in limit_date_list: for period_start_date in limit_date_list:
# Prepare history list of the current period # Prepare history list of the current period
next_period_start_date = DateTime(supply.getNextPeriodicalDate( next_period_start_date = DateTime(supply.getNextPeriodicalDate(
period_start_date, period_start_date,
next_start_date=period_start_date)).earliestTime() next_start_date=period_start_date)).earliestTime()
selected_supply = chooseCorrectSupply(default_supply = supply, start_date_range_min = period_start_date, start_date_range_max = next_period_start_date)
#we found a stock definition supply
if selected_supply != supply:
min_stock_value = getCorrectSupplyParameter(selected_supply, supply, 'getMinOrderQuantity') / getDefaultQuantityUnitFlowQuantityUnitConversionRatio(selected_supply, supply)
factor = getCorrectSupplyParameter(selected_supply, supply, 'getMinFlow')
else:
min_stock_value = original_min_stock_value
factor = original_factor
period_history_list = [] period_history_list = []
if next_period_history_list and\ if next_period_history_list and\
...@@ -537,7 +579,7 @@ class BuilderMixin(XMLObject, Amount, Predicate): ...@@ -537,7 +579,7 @@ class BuilderMixin(XMLObject, Amount, Predicate):
if (week_consumption!= 0 or factor) and future_inventory_to_date < min_inventory: if (week_consumption!= 0 or factor) and future_inventory_to_date < min_inventory:
quantity = min_inventory - future_inventory_to_date quantity = min_inventory - future_inventory_to_date
ordered_quantity, ordered_unit, effective_date, start_date, delivery_date, quantity = minimalQuantity(quantity, period_start_date) ordered_quantity, ordered_unit, effective_date, start_date, delivery_date, quantity = minimalQuantity(selected_supply, supply, quantity, period_start_date)
# XXX CLN This is very naive, it has to be optimized # XXX CLN This is very naive, it has to be optimized
if start_date > supply.getStartDateRangeMax(): if start_date > supply.getStartDateRangeMax():
break break
......
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