2using System.ComponentModel;
4using System.Xml.Serialization;
5using LotSizingDataModel.Core.Common;
6using LotSizingDataModel.Core.PhysicalModel;
22[XmlType(TypeName =
"inventoryDecision")]
29 private WarehouseReference _warehouse =
32 private DoubleTimeSeries _levels =
35 private DoubleTimeSeries _safetyStockViolations =
38 private IntegerTimeSeries _setups =
41 private DoubleTimeSeries _additionalCapacityUsed =
53 SubscribeToObject(_warehouse);
54 SubscribeToObject(_levels);
55 SubscribeToObject(_safetyStockViolations);
56 SubscribeToObject(_setups);
57 SubscribeToObject(_additionalCapacityUsed);
75 WarehouseReference warehouse,
81 throw new ArgumentOutOfRangeException(
84 "The item identifier must be strictly positive.");
87 ArgumentNullException.ThrowIfNull(warehouse);
89 if (planningHorizon <= 0)
91 throw new ArgumentOutOfRangeException(
92 nameof(planningHorizon),
94 "The planning horizon must be strictly positive.");
106 [XmlAttribute(
"itemId")]
119 throw new ArgumentOutOfRangeException(
122 "The item identifier cannot be negative.");
135 [XmlElement(
"warehouse")]
141 ArgumentNullException.ThrowIfNull(value);
150 UnsubscribeFromObject(_warehouse);
156 SubscribeToObject(_warehouse);
158 NotifyDerivedProperties();
169 [XmlElement(
"levels")]
175 ArgumentNullException.ThrowIfNull(value);
184 UnsubscribeFromObject(_levels);
190 SubscribeToObject(_levels);
192 NotifyDerivedProperties();
206 [XmlElement(
"safetyStockViolations")]
209 get => _safetyStockViolations;
212 ArgumentNullException.ThrowIfNull(value);
215 _safetyStockViolations,
221 UnsubscribeFromObject(
222 _safetyStockViolations);
225 ref _safetyStockViolations,
229 _safetyStockViolations);
231 NotifyDerivedProperties();
242 [XmlElement(
"setups")]
248 ArgumentNullException.ThrowIfNull(value);
257 UnsubscribeFromObject(_setups);
263 SubscribeToObject(_setups);
265 NotifyDerivedProperties();
279 [XmlElement(
"additionalCapacityUsed")]
282 get => _additionalCapacityUsed;
285 ArgumentNullException.ThrowIfNull(value);
288 _additionalCapacityUsed,
294 UnsubscribeFromObject(
295 _additionalCapacityUsed);
298 ref _additionalCapacityUsed,
302 _additionalCapacityUsed);
304 NotifyDerivedProperties();
322 SafetyStockViolations.PeriodCount ==
324 Setups.PeriodCount ==
326 AdditionalCapacityUsed.PeriodCount ==
337 double.IsFinite(level) &&
348 double.IsFinite(violation) &&
369 double.IsFinite(capacity) &&
417 ValidateNonNegativeFiniteValue(
452 ValidateNonNegativeFiniteValue(
472 return Setups[period] == 1;
524 ValidateNonNegativeFiniteValue(
547 throw new ArgumentOutOfRangeException(
550 "The period count cannot be negative.");
569 NotifyDerivedProperties();
583 NotifyDerivedProperties();
589 double maximumLevel =
594 double totalSafetyStockViolation =
598 $
"Item {ItemId}, warehouse " +
599 $
"{Warehouse.Kind}:{Warehouse.ReferenceId}: " +
600 $
"maximum level {maximumLevel}; " +
601 $
"safety-stock violation " +
602 $
"{totalSafetyStockViolation}";
605 private void SubscribeToObject(
606 ModelObject modelObject)
608 modelObject.PropertyChanged +=
609 OnNestedPropertyChanged;
612 private void UnsubscribeFromObject(
613 ModelObject modelObject)
615 modelObject.PropertyChanged -=
616 OnNestedPropertyChanged;
619 private void OnNestedPropertyChanged(
621 PropertyChangedEventArgs eventArgs)
623 NotifyDerivedProperties();
626 private void NotifyDerivedProperties()
650 private static void ValidateNonNegativeFiniteValue(
652 string parameterName)
654 if (!
double.IsFinite(value) ||
657 throw new ArgumentOutOfRangeException(
660 "The value must be finite and non-negative.");
int ItemId
Gets or sets the identifier of the stored item.
DoubleTimeSeries SafetyStockViolations
Gets or sets the quantities by which the safety-stock requirement is violated during each planning pe...
bool HasValidLevels
Gets a value indicating whether every inventory level is finite and non-negative.
bool HasConsistentPlanningHorizon
Gets a value indicating whether every decision series uses the same planning horizon.
double GetAdditionalCapacityUsed(int period)
Gets the item-specific additional capacity used during a planning period.
DoubleTimeSeries Levels
Gets or sets the inventory levels recorded during each planning period.
double InitialInventoryLevel
Gets or sets the optimized stock available before period 1.
void SetAdditionalCapacityUsed(int period, double capacity)
Sets the item-specific additional capacity used during a planning period.
void SetSetupActivated(int period, bool isActivated)
Sets the item-specific inventory activation for a planning period.
InventoryDecision()
Initializes an empty inventory decision.
void SetSafetyStockViolation(int period, double violation)
Sets the safety-stock violation for a planning period.
bool HasValidSetupValues
Gets a value indicating whether every setup value is equal to zero or one.
override string ToString()
void Clear()
Resets every inventory decision value to zero.
double GetLevel(int period)
Gets the inventory level for a planning period.
bool HasValidAdditionalCapacityValues
Gets a value indicating whether every additional-capacity value is finite and non-negative.
void SetLevel(int period, double level)
Sets the inventory level for a planning period.
double GetSafetyStockViolation(int period)
Gets the safety-stock violation for a planning period.
WarehouseReference Warehouse
Gets or sets the reference to the warehouse associated with the inventory decision.
bool HasValidSafetyStockViolations
Gets a value indicating whether every safety-stock violation is finite and non-negative.
IntegerTimeSeries Setups
Gets or sets the binary item-specific inventory-activation decisions.
void ResizeTimeSeries(int periodCount)
Resizes every decision series to the specified planning horizon.
bool IsSetupActivated(int period)
Determines whether the item-specific inventory activity is activated during a planning period.
InventoryDecision(int itemId, WarehouseReference warehouse, int planningHorizon)
Initializes an inventory decision for an item, a warehouse and a planning horizon.
int PlanningHorizon
Gets the number of planning periods represented by the inventory-level series.
DoubleTimeSeries AdditionalCapacityUsed
Gets or sets the item-specific additional capacity used during each planning period.
bool IsInternallyValid
Gets a value indicating whether the inventory decision is internally consistent.