LotSizingDataModel.Core 2.0.1
Core domain model, shared abstractions and XML-serializable entities.
Loading...
Searching...
No Matches
Inventory.cs
Go to the documentation of this file.
1using System;
2using System.Xml.Serialization;
5
7
8/// <summary>
9/// Represents the inventory of an item in a warehouse.
10///
11/// This class is the association between an Item and a Warehouse.
12/// It corresponds to the UML class "Stock".
13///
14/// Its initial-inventory property corresponds to I[i,0]
15/// in the source model.
16/// </summary>
17[Serializable]
18[XmlType(TypeName = "inventory")]
19public sealed partial class Inventory : ModelObject
20{
21 private int _itemId;
22 private WarehouseReference _warehouse = new();
23 private double _initialInventory;
24
25 /// <summary>
26 /// Initializes an empty inventory association.
27 ///
28 /// This public parameterless constructor is required
29 /// by <see cref="XmlSerializer"/>.
30 /// </summary>
31 public Inventory()
32 {
33 }
34
35 /// <summary>
36 /// Initializes an inventory association.
37 /// </summary>
38 /// <param name="itemId">
39 /// Identifier of the item stored in the warehouse.
40 /// </param>
41 /// <param name="warehouse">
42 /// Reference to the warehouse storing the item.
43 /// </param>
44 /// <param name="initialInventory">
45 /// Initial inventory level I[i,0].
46 /// </param>
47 public Inventory(
48 int itemId,
49 WarehouseReference warehouse,
50 double initialInventory = 0.0)
51 {
52 // Initialize all inventory properties (validation occurs in setters)
53 ItemId = itemId;
54 Warehouse = warehouse;
55 InitialInventory = initialInventory;
56 }
57
58 /// <summary>
59 /// Initializes an inventory association for an item
60 /// stored in a standalone warehouse.
61 /// </summary>
62 /// <param name="itemId">
63 /// Identifier of the stored item.
64 /// </param>
65 /// <param name="standaloneWarehouseId">
66 /// Identifier e of the standalone warehouse.
67 /// </param>
68 /// <param name="initialInventory">
69 /// Initial inventory level I[i,0].
70 /// </param>
72 int itemId,
73 int standaloneWarehouseId,
74 double initialInventory = 0.0)
75 {
76 // Factory method: create inventory for a standalone warehouse
77 return new Inventory(
78 itemId,
80 standaloneWarehouseId),
81 initialInventory);
82 }
83
84 /// <summary>
85 /// Initializes an inventory association for an item
86 /// stored in a warehouse attached to a plant.
87 /// </summary>
88 /// <param name="itemId">
89 /// Identifier of the stored item.
90 /// </param>
91 /// <param name="plantId">
92 /// Identifier u of the plant owning the warehouse.
93 /// </param>
94 /// <param name="initialInventory">
95 /// Initial inventory level I[i,0].
96 /// </param>
98 int itemId,
99 int plantId,
100 double initialInventory = 0.0)
101 {
102 // Factory method: create inventory for a plant warehouse
103 return new Inventory(
104 itemId,
106 initialInventory);
107 }
108
109 /// <summary>
110 /// Gets or sets the identifier of the item
111 /// stored in the warehouse.
112 /// </summary>
113 [XmlAttribute("itemId")]
114 public int ItemId
115 {
116 get => _itemId;
117 set
118 {
119 // Validate that the item identifier is non-negative
120 if (value < 0)
121 {
122 throw new ArgumentOutOfRangeException(
123 nameof(value),
124 value,
125 "The item identifier cannot be negative.");
126 }
127
128 // Update the backing field and notify property change if value differs
129 SetProperty(ref _itemId, value);
130 }
131 }
132
133 /// <summary>
134 /// Gets or sets the warehouse storing the item.
135 ///
136 /// A plant warehouse is identified by its owning plant.
137 /// A standalone warehouse is identified by its own identifier.
138 /// </summary>
139 [XmlElement("warehouse")]
141 {
142 get => _warehouse;
143 set
144 {
145 // Validate that the warehouse reference is not null
146 ArgumentNullException.ThrowIfNull(value);
147
148 // Update and notify dependent properties if value changed
149 if (SetProperty(ref _warehouse, value))
150 {
151 OnPropertyChanged(nameof(WarehouseKind));
152 OnPropertyChanged(nameof(WarehouseReferenceId));
153 }
154 }
155 }
156
157 /// <summary>
158 /// Gets or sets the initial inventory level.
159 ///
160 /// Corresponds to I[i,0] in the source model.
161 /// </summary>
162 [XmlAttribute("initialInventory")]
163 public double InitialInventory
164 {
165 get => _initialInventory;
166 set
167 {
168 // Validate that the value is non-negative and finite
169 ValidateNonNegativeFiniteValue(
170 value,
171 nameof(value));
172
173 // Update the backing field and notify property change if value differs
174 SetProperty(
175 ref _initialInventory,
176 value);
177 }
178 }
179
180 /// <summary>
181 /// Gets the kind of referenced warehouse.
182 ///
183 /// This is a convenience property and is not serialized.
184 /// </summary>
185 [XmlIgnore]
187 Warehouse.Kind;
188
189 /// <summary>
190 /// Gets the identifier used to reference the warehouse.
191 ///
192 /// This is either the standalone-warehouse identifier
193 /// or the owning-plant identifier.
194 /// </summary>
195 [XmlIgnore]
197 Warehouse.ReferenceId;
198
199 /// <summary>
200 /// Determines whether this object represents the same
201 /// item/warehouse association as another inventory object.
202 /// </summary>
204 Inventory? other)
205 {
206 // Compare item ID and warehouse reference (kind and ID) for equality
207 return other is not null
208 && ItemId == other.ItemId
209 && Warehouse.Kind == other.Warehouse.Kind
210 && Warehouse.ReferenceId ==
212 }
213
214 /// <summary>
215 /// Determines whether this inventory concerns
216 /// the specified item.
217 /// </summary>
218 public bool ConcernsItem(int itemId)
219 {
220 return ItemId == itemId;
221 }
222
223 /// <summary>
224 /// Determines whether this inventory concerns
225 /// the specified warehouse.
226 /// </summary>
227 public bool ConcernsWarehouse(
228 WarehouseReference warehouse)
229 {
230 ArgumentNullException.ThrowIfNull(warehouse);
231
232 // Check if the warehouse reference matches both kind and ID
233 return Warehouse.Kind == warehouse.Kind
234 && Warehouse.ReferenceId ==
235 warehouse.ReferenceId;
236 }
237
238 /// <summary>
239 /// Validates that a double value is finite and non-negative.
240 /// </summary>
241 /// <param name="value">The value to validate.</param>
242 /// <param name="parameterName">The parameter name for error messages.</param>
243 /// <exception cref="ArgumentOutOfRangeException">
244 /// If the value is NaN, infinite, or negative.
245 /// </exception>
246 private static void ValidateNonNegativeFiniteValue(
247 double value,
248 string parameterName)
249 {
250 // Check if the value is finite (not NaN or Infinity)
251 if (double.IsNaN(value) ||
252 double.IsInfinity(value))
253 {
254 throw new ArgumentOutOfRangeException(
255 parameterName,
256 value,
257 "The initial inventory must be a finite number.");
258 }
259
260 // Check if the value is non-negative
261 if (value < 0.0)
262 {
263 throw new ArgumentOutOfRangeException(
264 parameterName,
265 value,
266 "The initial inventory cannot be negative.");
267 }
268 }
269}
Base class for model objects that notify listeners when one of their properties changes.
Represents a serializable reference to a warehouse.
int ReferenceId
Gets or sets the referenced identifier.
static WarehouseReference ForPlantWarehouse(int plantId)
Creates a reference to the warehouse attached to a plant.
static WarehouseReference ForStandaloneWarehouse(int warehouseId)
Creates a reference to a standalone warehouse.
WarehouseReferenceKind WarehouseKind
Gets the kind of referenced warehouse.
Definition Inventory.cs:186
Inventory()
Initializes an empty inventory association.
Definition Inventory.cs:31
static Inventory ForPlantWarehouse(int itemId, int plantId, double initialInventory=0.0)
Initializes an inventory association for an item stored in a warehouse attached to a plant.
Definition Inventory.cs:97
Inventory(int itemId, WarehouseReference warehouse, double initialInventory=0.0)
Initializes an inventory association.
Definition Inventory.cs:47
int ItemId
Gets or sets the identifier of the item stored in the warehouse.
Definition Inventory.cs:115
bool ConcernsWarehouse(WarehouseReference warehouse)
Determines whether this inventory concerns the specified warehouse.
Definition Inventory.cs:227
WarehouseReference Warehouse
Gets or sets the warehouse storing the item.
Definition Inventory.cs:141
static Inventory ForStandaloneWarehouse(int itemId, int standaloneWarehouseId, double initialInventory=0.0)
Initializes an inventory association for an item stored in a standalone warehouse.
Definition Inventory.cs:71
double InitialInventory
Gets or sets the initial inventory level.
Definition Inventory.cs:164
int WarehouseReferenceId
Gets the identifier used to reference the warehouse.
Definition Inventory.cs:196
bool ConcernsItem(int itemId)
Determines whether this inventory concerns the specified item.
Definition Inventory.cs:218
bool RefersToSameInventory(Inventory? other)
Determines whether this object represents the same item/warehouse association as another inventory ob...
Definition Inventory.cs:203
WarehouseReferenceKind
Identifies the type of warehouse referenced by a relationship.