2using System.Collections.Generic;
18 private readonly Dictionary<int, TransportLane> _transportLanes =
new();
22 public TransportLane GetRequiredTransportLane(
int laneId) => _transportLanes.TryGetValue(laneId, out var lane) ? lane :
throw new KeyNotFoundException($
"Transport lane {laneId} does not exist.");
25 private readonly Dictionary<int, Item> _items =
new();
26 private readonly Dictionary<int, Plant> _plants =
new();
28 private readonly Dictionary<int, StandaloneWarehouse>
29 _standaloneWarehouses =
new();
31 private readonly Dictionary<
35 private readonly Dictionary<
36 (
int PlantId,
int WorkCenterId),
39 private readonly Dictionary<int, Supplier> _suppliers =
new();
41 private readonly Dictionary<int, DistributionCenter>
42 _distributionCenters =
new();
44 private readonly Dictionary<int, TransportResource>
45 _transportResources =
new();
56 throw new ArgumentNullException(nameof(supplyChain));
96 _distributionCenters.Count;
102 _transportResources.Count;
117 IndexPlantsAndWorkCenters();
118 IndexStandaloneWarehouses();
120 IndexDistributionCenters();
121 IndexTransportResources();
122 foreach (var lane
in SupplyChain.TransportLanes) AddUnique(_transportLanes, lane.Id, lane,
"transport lane");
123 foreach (var assignment
in SupplyChain.TransportAssignments) AddUnique(_transportAssignments, (assignment.LaneId, assignment.TransportResourceId), assignment,
"transport assignment");
131 _transportLanes.Clear();
132 _transportAssignments.Clear();
135 _standaloneWarehouses.Clear();
137 _workCenters.Clear();
139 _distributionCenters.Clear();
140 _transportResources.Clear();
143 #region Item resolution
152 return _items.TryGetValue(
168 $
"Item {itemId} does not exist.");
173 #region Plant resolution
182 return _plants.TryGetValue(
195 $
"Plant {plantId} does not exist.");
200 #region Warehouse resolution
210 return _standaloneWarehouses.TryGetValue(
222 _standaloneWarehouses,
224 $
"Standalone warehouse {warehouseId} does not exist.");
238 if (reference is
null)
244 return _warehouses.TryGetValue(
245 CreateWarehouseKey(reference),
255 ArgumentNullException.ThrowIfNull(reference);
257 var key = CreateWarehouseKey(reference);
262 $
"Warehouse {FormatWarehouseKey(key)} does not exist.");
278 $
"The warehouse of plant {plantId} does not exist.");
282 throw new InvalidOperationException(
283 $
"Warehouse reference PlantWarehouse:{plantId} " +
284 "does not resolve to a plant warehouse.");
287 return plantWarehouse;
292 #region Work-center resolution
301 if (reference is
null)
322 return _workCenters.TryGetValue(
323 (plantId, workCenterId),
333 ArgumentNullException.ThrowIfNull(reference);
350 (plantId, workCenterId),
351 $
"Work center {plantId}:{workCenterId} does not exist.");
356 #region Supplier resolution
365 return _suppliers.TryGetValue(
378 $
"Supplier {supplierId} does not exist.");
383 #region Distribution-center resolution
390 int distributionCenterId,
393 return _distributionCenters.TryGetValue(
394 distributionCenterId,
395 out distributionCenter);
402 int distributionCenterId)
405 _distributionCenters,
406 distributionCenterId,
407 "Distribution center " +
408 $
"{distributionCenterId} does not exist.");
413 #region Transport-resource resolution
420 int transportResourceId,
423 return _transportResources.TryGetValue(
425 out transportResource);
432 int transportResourceId)
437 "Transport resource " +
438 $
"{transportResourceId} does not exist.");
443 #region Index construction
445 private void IndexItems()
457 private void IndexPlantsAndWorkCenters()
493 private void IndexStandaloneWarehouses()
500 _standaloneWarehouses,
503 "standalone warehouse");
517 private void IndexSuppliers()
519 foreach (Supplier supplier
in SupplyChain.Suppliers)
529 private void IndexDistributionCenters()
531 foreach (DistributionCenter distributionCenter
535 _distributionCenters,
536 distributionCenter.
Id,
538 "distribution center");
542 private void IndexTransportResources()
544 foreach (TransportResource transportResource
549 transportResource.
Id,
551 "transport resource");
562 CreateWarehouseKey(WarehouseReference reference)
570 private static string FormatWarehouseKey(
576 return $
"{key.Kind}:{key.ReferenceId}";
579 private static void AddUnique<TKey, TValue>(
580 IDictionary<TKey, TValue> dictionary,
587 ArgumentNullException.ThrowIfNull(value);
590 if (!dictionary.TryAdd(key, value))
592 throw new InvalidOperationException(
593 $
"Cannot build the supply-chain index because " +
594 $
"the {entityName} key '{key}' is duplicated.");
598 private static TValue GetRequired<TKey, TValue>(
599 IReadOnlyDictionary<TKey, TValue> dictionary,
605 if (dictionary.TryGetValue(
613 throw new KeyNotFoundException(errorMessage);
int Id
Gets or sets the numerical identifier of the entity.
int ItemCount
Gets the number of indexed items.
Plant GetRequiredPlant(int plantId)
Resolves a plant by its identifier.
bool TryGetWorkCenter(int plantId, int workCenterId, out WorkCenter? workCenter)
Attempts to resolve a work center from its plant and local work-center identifiers.
bool TryGetItem(int itemId, out Item? item)
Attempts to resolve an item by its identifier.
bool TryGetWarehouse(WarehouseReference? reference, out Warehouse? warehouse)
Attempts to resolve a warehouse from a warehouse reference.
bool TryGetWorkCenter(WorkCenterReference? reference, out WorkCenter? workCenter)
Attempts to resolve a work center from a reference.
WorkCenter GetRequiredWorkCenter(int plantId, int workCenterId)
Resolves a work center from its plant and local work-center identifiers.
int TransportResourceCount
Gets the number of indexed transport resources.
int WarehouseCount
Gets the number of indexed warehouses, including standalone warehouses and plant warehouses.
WorkCenter GetRequiredWorkCenter(WorkCenterReference reference)
Resolves a work center from a reference.
bool TryGetDistributionCenter(int distributionCenterId, out DistributionCenter? distributionCenter)
Attempts to resolve a distribution center by its identifier.
PlantWarehouse GetRequiredPlantWarehouse(int plantId)
Resolves the warehouse attached to a plant.
void Rebuild()
Rebuilds every index from the current content of the supply chain.
int PlantCount
Gets the number of indexed plants.
bool TryGetStandaloneWarehouse(int warehouseId, out StandaloneWarehouse? warehouse)
Attempts to resolve a standalone warehouse by its own identifier.
bool TryGetTransportAssignment(int laneId, int resourceId, out TransportAssignment? assignment)
bool TryGetTransportResource(int transportResourceId, out TransportResource? transportResource)
Attempts to resolve a transport resource by its identifier.
bool TryGetTransportLane(int laneId, out TransportLane? lane)
bool TryGetSupplier(int supplierId, out Supplier? supplier)
Attempts to resolve a supplier by its identifier.
bool TryGetPlant(int plantId, out Plant? plant)
Attempts to resolve a plant by its identifier.
SupplyChainIndex(SupplyChain supplyChain)
Initializes an index for the specified supply chain.
SupplyChain SupplyChain
Gets the indexed supply chain.
Supplier GetRequiredSupplier(int supplierId)
Resolves a supplier by its identifier.
Warehouse GetRequiredWarehouse(WarehouseReference reference)
Resolves a warehouse from a warehouse reference.
TransportResource GetRequiredTransportResource(int transportResourceId)
Resolves a transport resource by its identifier.
int WorkCenterCount
Gets the number of indexed work centers.
int DistributionCenterCount
Gets the number of indexed distribution centers.
StandaloneWarehouse GetRequiredStandaloneWarehouse(int warehouseId)
Resolves a standalone warehouse by its own identifier.
int SupplierCount
Gets the number of indexed suppliers.
TransportLane GetRequiredTransportLane(int laneId)
Item GetRequiredItem(int itemId)
Resolves an item by its identifier.
DistributionCenter GetRequiredDistributionCenter(int distributionCenterId)
Resolves a distribution center by its identifier.
Represents a finished or semi-finished item handled by the supply chain.
Represents a distribution center in the supply chain.
Represents a production plant.
List< WorkCenter > WorkCenters
Gets or sets the work centers belonging to the plant.
PlantWarehouse Warehouse
Gets or sets the warehouse attached to the plant.
Represents a warehouse attached to a plant.
Represents a standalone warehouse that is not attached to a plant.
int Id
Gets or sets the numerical identifier of the standalone warehouse.
Represents a supplier in the supply chain.
An authorized lane-resource pair, with its delay in periods.
Represents a transport lane between two warehouses.
A transport resource with its own shared capacities and costs.
Represents a warehouse in the supply chain.
Represents a serializable reference to a warehouse.
int ReferenceId
Gets or sets the referenced identifier.
WarehouseReferenceKind Kind
Gets or sets the kind of warehouse being referenced.
Represents a production work center belonging to a plant.
Represents a serializable reference to a work center.
int PlantId
Gets or sets the identifier of the plant owning the referenced work center.
int WorkCenterId
Gets or sets the identifier of the referenced work center.
Represents the complete supply-chain data model.
List< Plant > Plants
Gets the plants in the supply chain.
List< Item > Items
Gets the items present in the supply chain.
WarehouseReferenceKind
Identifies the type of warehouse referenced by a relationship.
@ StandaloneWarehouse
The reference identifies a standalone warehouse through its own warehouse identifier e.