diff --git a/bt5/erp5_base/MixinTemplateItem/portal_components/mixin.erp5.BuilderMixin.py b/bt5/erp5_base/MixinTemplateItem/portal_components/mixin.erp5.BuilderMixin.py index 6f8236316be5de49995aa100a78ca4eb8d8d7368..15f3a51e00508b76eac7e2225a2500a641b810cb 100644 --- a/bt5/erp5_base/MixinTemplateItem/portal_components/mixin.erp5.BuilderMixin.py +++ b/bt5/erp5_base/MixinTemplateItem/portal_components/mixin.erp5.BuilderMixin.py @@ -300,62 +300,73 @@ class BuilderMixin(XMLObject, Amount, Predicate): portal = self.getPortalObject() if from_date is None: from_date = DateTime().earliestTime() - - # Initiate Conditions taken from Yusei T. Original Script - # XXX to be cleaned - min_inventory = supply.getMinStock() + #resource related variable resource_value = supply.getResourceValue() 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) - min_delay = supply.getMinDelay() - max_delay = supply.getMaxDelay() - min_order_delay = supply.getMinOrderDelay() - max_order_delay = supply.getMaxOrderDelay() - min_order = supply.getMinOrderQuantity() - max_order = supply.getMaxOrderQuantity() - - # Initiate conversions - # XXX To be cleaned - min_delay_second = 0 - max_delay_second = 0 - min_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: - time_second_conversion_ratio = resource_value.getQuantityUnitDefinitionRatio(time_quantity_unit_value) / time_second_ratio - - if min_delay: - min_delay_second = min_delay * time_second_conversion_ratio - if max_delay: - max_delay_second = max_delay * time_second_conversion_ratio - if min_order_delay: - min_order_delay_second = min_order_delay * time_second_conversion_ratio - if max_delay: - max_order_delay_second = max_order_delay * time_second_conversion_ratio - - if order_quantity_unit_value is not None: - 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) - if min_order: - min_order_in_default_quantity_unit = min_order * order_quantity_unit_default_quantity_unit_conversion_ratio - if max_order: - max_order_in_default_quantity_unit = max_order * order_quantity_unit_default_quantity_unit_conversion_ratio - else: + def getCorrectSupplyParameter(selected_supply, default_supply, method_id): + 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 + max_delay_second = 0 + min_order_delay_second = 0 + max_order_delay_second = 0 + 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 + if min_delay: + min_delay_second = min_delay * time_second_conversion_ratio + if max_delay: + max_delay_second = max_delay * time_second_conversion_ratio + if min_order_delay: + min_order_delay_second = min_order_delay * time_second_conversion_ratio + if max_delay: + 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 - - if flow_quantity_unit_value is not None: - 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) - default_quantity_unit_flow_quantity_unit_conversion_ratio = 1 / flow_quantity_unit_default_quantity_unit_conversion_ratio - else: + #min_order_in_default_quantity_unit = 0 + #max_order_in_default_quantity_unit = float('inf') + if order_quantity_unit_value is not None: + 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) + """ + those are not used yet + min_order = supply.getMinOrderQuantity() + max_order = supply.getMaxOrderQuantity() + if min_order: + min_order_in_default_quantity_unit = min_order * order_quantity_unit_default_quantity_unit_conversion_ratio + if max_order: + max_order_in_default_quantity_unit = max_order * order_quantity_unit_default_quantity_unit_conversion_ratio + """ + 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: + 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) + default_quantity_unit_flow_quantity_unit_conversion_ratio = 1 / flow_quantity_unit_default_quantity_unit_conversion_ratio + return default_quantity_unit_flow_quantity_unit_conversion_ratio + + default_quantity_unit_flow_quantity_unit_conversion_ratio = getDefaultQuantityUnitFlowQuantityUnitConversionRatio(supply, supply) + def getPreviousValidDate(date): # We suppose the system has not been configured to handled per hour commands @@ -366,23 +377,29 @@ class BuilderMixin(XMLObject, Amount, Predicate): factor=-1)).earliestTime() # 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. # XXX To be cleaned - - delay_second = max_delay_second or min_delay_second or 0 + if selected_supply != default_supply: + 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) start_date = getPreviousValidDate( addToDate(limit_date, second=-delay_second) ) + 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) - - order_quantity = ceil(quantity / order_quantity_unit_default_quantity_unit_conversion_ratio) - quantity = order_quantity * order_quantity_unit_default_quantity_unit_conversion_ratio - - return order_quantity, order_quantity_unit_value, effective_date, start_date, stop_date, quantity + order_quantity = ceil(quantity / local_order_quantity_unit_default_quantity_unit_conversion_ratio) + quantity = order_quantity * local_order_quantity_unit_default_quantity_unit_conversion_ratio + return order_quantity, local_order_quantity_unit_value, effective_date, start_date, stop_date, quantity resource_portal_type = resource_value.getPortalType() def newMovement(effective_date, start_date, stop_date, quantity, quantity_unit): @@ -486,17 +503,42 @@ class BuilderMixin(XMLObject, Amount, Predicate): node_uid=supply.getDestinationUid() ) + history_list - min_stock_value = supply.getMinOrderQuantity() / default_quantity_unit_flow_quantity_unit_conversion_ratio - factor = supply.getMinFlow() 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 for period_start_date in limit_date_list: - # Prepare history list of the current period next_period_start_date = DateTime(supply.getNextPeriodicalDate( period_start_date, 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 = [] if next_period_history_list and\ @@ -548,7 +590,7 @@ class BuilderMixin(XMLObject, Amount, Predicate): if (week_consumption!= 0 or factor) and future_inventory_to_date < min_inventory: 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 if start_date > supply.getStartDateRangeMax(): break