2using System.Collections.Generic;
64 throw new ArgumentNullException(
67 _validator = validator ??
68 throw new ArgumentNullException(
73 throw new ArgumentOutOfRangeException(
76 "The planning horizon must be strictly positive.");
101 if (planningHorizon <= 0)
103 throw new ArgumentOutOfRangeException(
104 nameof(planningHorizon),
106 "The planning horizon must be strictly positive.");
115 #region Logical subsystem
123 ArgumentNullException.ThrowIfNull(item);
137 int billOfMaterialsLevel = 0)
143 billOfMaterialsLevel));
155 ArgumentNullException.ThrowIfNull(requirement);
157 _index.GetRequiredItem(
160 _index.GetRequiredItem(
166 throw new InvalidOperationException(
167 "An item cannot be its own component.");
172 throw new ArgumentOutOfRangeException(
175 "A component quantity must be strictly positive.");
195 ParentItemId = parentItemId,
196 ComponentItemId = componentItemId,
203 #region Physical subsystem
214 ArgumentNullException.ThrowIfNull(plant);
229 if (
string.IsNullOrWhiteSpace(name))
231 throw new ArgumentException(
232 "The plant name cannot be empty.",
251 ArgumentNullException.ThrowIfNull(workCenter);
254 _index.GetRequiredPlant(plantId);
288 ArgumentNullException.ThrowIfNull(warehouse);
316 ArgumentNullException.ThrowIfNull(supplier);
342 ArgumentNullException.ThrowIfNull(
374 ArgumentNullException.ThrowIfNull(
404 ValidateTransportLane(lane);
419 #region Production relationships
431 ArgumentNullException.ThrowIfNull(routing);
433 _index.GetRequiredItem(routing.
ItemId);
435 _index.GetRequiredPlant(routing.
PlantId);
438 in routing.WorkCenters)
440 if (reference.
PlantId != routing.PlantId)
442 throw new InvalidOperationException(
443 "Every work center referenced by a routing " +
444 "must belong to the routing plant.");
447 _index.GetRequiredWorkCenter(reference);
464 ArgumentNullException.ThrowIfNull(
467 _index.GetRequiredItem(
472 throw new InvalidOperationException(
473 "A production characteristic must reference " +
477 _index.GetRequiredWorkCenter(
488 #region Inventory relationships
498 ArgumentNullException.ThrowIfNull(inventory);
500 _index.GetRequiredItem(inventory.
ItemId);
502 ValidateWarehouseReference(
512 #region Transport relationships
523 ArgumentNullException.ThrowIfNull(
526 _index.GetRequiredItem(
529 _index.GetRequiredTransportResource(
540 #region Demand and distribution relationships
550 ArgumentNullException.ThrowIfNull(demand);
552 _index.GetRequiredItem(demand.
ItemId);
554 _index.GetRequiredDistributionCenter(
572 ArgumentNullException.ThrowIfNull(sourcing);
574 _index.GetRequiredItem(sourcing.
ItemId);
576 _index.GetRequiredDistributionCenter(
579 ValidateWarehouseReference(
582 EnsureInventoryExists(
594 #region Supplier relationships
606 ArgumentNullException.ThrowIfNull(delivery);
608 _index.GetRequiredSupplier(
611 _index.GetRequiredItem(
614 ValidateWarehouseReference(
617 EnsureInventoryExists(
629 #region Validation and build
634 public IReadOnlyList<
676 return Build(validate:
true);
681 #region Private helpers
683 private void RebuildIndex()
688 private void ValidateTransportLane(
691 ArgumentNullException.ThrowIfNull(lane);
693 ValidateWarehouseReference(lane.
Origin);
700 throw new InvalidOperationException(
701 "A transport lane must connect two " +
702 "different warehouses.");
707 private void ValidateWarehouseReference(
710 if (reference is
null)
712 throw new InvalidOperationException(
713 "A warehouse reference is required.");
716 _index.GetRequiredWarehouse(reference);
719 private void EnsureInventoryExists(
721 WarehouseReference warehouse)
723 bool inventoryExists =
726 inventory.ItemId == itemId &&
731 if (!inventoryExists)
733 throw new InvalidOperationException(
734 $
"No inventory exists for item {itemId} " +
735 $
"and warehouse {FormatWarehouse(warehouse)}.");
739 private static bool SameWarehouse(
740 WarehouseReference? first,
741 WarehouseReference? second)
743 if (first is
null || second is
null)
745 return first is
null &&
749 return first.Kind == second.Kind &&
753 private static string FormatWarehouse(
754 WarehouseReference warehouse)
757 $
"{warehouse.Kind}:{warehouse.ReferenceId}";
Provides a fluent and controlled way to construct a complete supply-chain model.
SupplyChainModelBuilder AddComponentRequirement(ComponentRequirement requirement)
Adds a bill-of-material component requirement.
SupplyChainModelBuilder AddDistributionCenterSourcing(DistributionCenterSourcing sourcing)
Adds a distribution-center sourcing relationship.
SupplyChainModelBuilder(SupplyChain supplyChain)
Initializes a builder for an existing supply chain.
SupplyChainModelBuilder AddPlant(int id, string name)
Creates and adds an empty plant.
SupplyChainModelBuilder SetPlanningHorizon(int planningHorizon)
Changes the global planning horizon.
SupplyChainModelBuilder AddTransportLane(TransportLane lane)
Adds a central directed lane.
SupplyChainModelBuilder AddTransportCharacteristic(TransportCharacteristic characteristic)
Adds an item-transport-resource characteristic.
SupplyChainModelBuilder AddProductionRouting(ProductionRouting routing)
Adds a production routing.
int PlanningHorizon
Gets the current global planning horizon.
SupplyChain BuildValidated()
Synchronizes, validates and returns the model.
SupplyChainModelBuilder AddProductionCharacteristic(ProductionCharacteristic characteristic)
Adds an item-work-center production characteristic.
SupplyChainModelBuilder(int planningHorizon)
Initializes an empty supply-chain builder.
SupplyChainModelBuilder AddDistributionCenter(int id, string name)
Creates and adds a distribution center.
SupplyChainModelBuilder AddSupplier(Supplier supplier)
Adds a supplier.
SupplyChainModelBuilder AddItem(Item item)
Adds an item to the logical subsystem.
SupplyChainModelBuilder AddSupplierDelivery(SupplierDelivery delivery)
Adds a supplier-delivery relationship.
SupplyChainModelBuilder AddInventory(Inventory inventory)
Adds an item-warehouse inventory.
SupplyChainModelBuilder AddPlant(Plant plant)
Adds a plant.
SupplyChainModelBuilder AddStandaloneWarehouse(StandaloneWarehouse warehouse)
Adds a standalone warehouse.
SupplyChainModelBuilder AddDistributionCenter(DistributionCenter distributionCenter)
Adds a distribution center.
SupplyChainModelBuilder AddSupplier(int id, string name)
Creates and adds a supplier.
SupplyChainModelBuilder(SupplyChain supplyChain, SupplyChainValidator validator)
Initializes a builder with a supply chain and a custom validator.
SupplyChain SupplyChain
Gets the supply chain currently being constructed.
SupplyChainModelBuilder AddItem(int id, string name, int billOfMaterialsLevel=0)
Creates and adds an item.
IReadOnlyList< SupplyChainValidator.ValidationIssue > Validate()
Validates the current state of the model.
SupplyChainModelBuilder AddComponentRequirement(int parentItemId, int componentItemId, int quantity)
Creates and adds a bill-of-material requirement.
SupplyChainModelBuilder AddTransportAssignment(int laneId, int resourceId, int leadTime)
SupplyChainModelBuilder AddWorkCenter(int plantId, int workCenterId, string name)
Creates and adds a work center to an existing plant.
SupplyChainModelBuilder AddDemand(Demand demand)
Adds a demand.
SupplyChainModelBuilder AddStandaloneWarehouse(int id, string name)
Creates and adds a standalone warehouse.
SupplyChainModelBuilder AddTransportResource(TransportResource transportResource)
Adds a transport resource.
bool IsValid()
Gets a value indicating whether the current model contains no validation error.
SupplyChainModelBuilder AddTransportResource(int id, string name)
Creates and adds an empty transport resource.
SupplyChainModelBuilder AddWorkCenter(int plantId, WorkCenter workCenter)
Adds a work center to an existing plant.
SupplyChain Build(bool validate=true)
Synchronizes all time series and returns the model.
Provides fast access to the entities contained in a supply chain.
Represents a bill-of-materials relationship between two items.
int ParentItemId
Gets or sets the identifier of the item being manufactured.
int ComponentItemId
Gets or sets the identifier of the required component.
int Quantity
Gets or sets the quantity of the component required to manufacture one unit of the parent item.
Represents a finished or semi-finished item handled by the supply chain.
Represents a distribution center in the supply chain.
Represents a production plant.
void AddWorkCenter(WorkCenter workCenter)
Adds a work center to the plant.
Represents a standalone warehouse that is not attached to a plant.
Represents a supplier in the supply chain.
An authorized lane-resource pair, with its delay in periods.
Represents a transport lane between two warehouses.
WarehouseReference Destination
Gets or sets the destination warehouse.
WarehouseReference Origin
Gets or sets the origin warehouse.
A transport resource with its own shared capacities and costs.
Represents a serializable reference to a warehouse.
int ReferenceId
Gets or sets the referenced identifier.
Represents a production work center belonging to a plant.
void ResizeTimeSeries(int periodCount)
Resizes every active period-dependent parameter.
Represents a serializable reference to a work center.
int PlantId
Gets or sets the identifier of the plant owning the referenced work center.
Represents the demand for an item issued by a distribution center.
int ItemId
Gets or sets the identifier of the requested item.
int DistributionCenterId
Gets or sets the identifier of the distribution center issuing the demand.
Represents the ability of a distribution center to source a given item from a given warehouse invento...
int DistributionCenterId
Gets or sets the identifier of the distribution center that can obtain the item from the referenced i...
WarehouseReference Warehouse
Gets or sets the warehouse holding the inventory from which the distribution center can obtain the it...
int ItemId
Gets or sets the identifier of the item contained in the referenced inventory.
Represents the inventory of an item in a warehouse.
int ItemId
Gets or sets the identifier of the item stored in the warehouse.
WarehouseReference Warehouse
Gets or sets the warehouse storing the item.
Represents the production characteristics of an item on a specific work center.
WorkCenterReference WorkCenter
Gets or sets the referenced work center.
int ItemId
Gets or sets the identifier of the item manufactured on the referenced work center.
Represents a production routing used to manufacture an item in a plant through one or more work cente...
int ItemId
Gets or sets the identifier of the item manufactured through this routing.
int PlantId
Gets or sets the identifier of the plant in which this routing is available.
Represents the ability of a supplier to deliver a given item to a given warehouse inventory.
int SupplierId
Gets or sets the identifier of the supplier.
int ItemId
Gets or sets the identifier of the delivered item.
WarehouseReference Warehouse
Gets or sets the warehouse receiving the item.
Represents the transport characteristics of an item for a specific transport resource.
int ItemId
Gets or sets the identifier of the item transported by the referenced transport resource.
int TransportResourceId
Gets or sets the identifier of the transport resource associated with the item.
int PlanningHorizon
Gets or sets the number of periods in the global planning horizon.
Represents one issue detected during validation.
Validates the structural, referential and decision-model consistency of a complete supply chain.
@ StandaloneWarehouse
The reference identifies a standalone warehouse through its own warehouse identifier e.