2using System.Collections.Generic;
28 throw new ArgumentNullException(
29 nameof(supplyChain))))
39 throw new ArgumentNullException(nameof(index));
68 #region Production costs
81 bool resourceActivated,
82 double additionalCapacityUsed)
84 ArgumentNullException.ThrowIfNull(
87 ValidatePeriod(period);
90 additionalCapacityUsed,
91 nameof(additionalCapacityUsed));
93 ValidateResourceActivation(
95 additionalCapacityUsed);
98 Index.GetRequiredWorkCenter(
101 double fixedUsageCost =
108 double additionalCapacityCost =
110 additionalCapacityUsed,
114 "work-center additional-capacity cost");
117 fixedUsageCost: fixedUsageCost,
118 additionalCapacityCost:
119 additionalCapacityCost);
132 double productionQuantity,
135 ArgumentNullException.ThrowIfNull(
136 workCenterReference);
138 ValidatePeriod(period);
142 nameof(productionQuantity));
145 Queries.GetRequiredProductionCharacteristic(
147 workCenterReference);
149 double fixedSetupCost =
156 double unitUsageCost =
162 "production unit-usage cost");
165 fixedSetupCost: fixedSetupCost,
166 unitUsageCost: unitUsageCost);
171 #region Storage costs
183 bool warehouseActivated,
184 double additionalCapacityUsed)
186 ArgumentNullException.ThrowIfNull(
189 ValidatePeriod(period);
192 additionalCapacityUsed,
193 nameof(additionalCapacityUsed));
195 ValidateResourceActivation(
197 additionalCapacityUsed);
200 Index.GetRequiredWarehouse(
203 double fixedUsageCost =
210 double additionalCapacityCost =
212 additionalCapacityUsed,
216 "warehouse additional-capacity cost");
219 fixedUsageCost: fixedUsageCost,
220 additionalCapacityCost:
221 additionalCapacityCost);
234 double inventoryQuantity,
236 double itemAdditionalCapacityUsed,
237 double safetyStockViolationQuantity)
239 ArgumentNullException.ThrowIfNull(
242 ValidatePeriod(period);
246 nameof(inventoryQuantity));
249 itemAdditionalCapacityUsed,
250 nameof(itemAdditionalCapacityUsed));
253 safetyStockViolationQuantity,
254 nameof(safetyStockViolationQuantity));
261 double fixedSetupCost =
268 double unitUsageCost =
274 "inventory unit-usage cost");
276 double additionalCapacityCost =
278 itemAdditionalCapacityUsed,
282 "item-specific storage additional-capacity cost");
284 double safetyStockViolationCost =
286 safetyStockViolationQuantity,
290 "safety-stock violation cost");
293 additionalCapacityCost:
294 additionalCapacityCost,
295 fixedSetupCost: fixedSetupCost,
296 unitUsageCost: unitUsageCost,
297 safetyStockViolationCost:
298 safetyStockViolationCost);
303 #region Transport costs
313 int transportResourceId,
315 bool resourceActivated,
316 double additionalCapacityUsed)
318 ValidatePeriod(period);
321 additionalCapacityUsed,
322 nameof(additionalCapacityUsed));
324 ValidateResourceActivation(
326 additionalCapacityUsed);
329 Index.GetRequiredTransportResource(
330 transportResourceId);
332 double fixedUsageCost =
339 double additionalCapacityCost =
341 additionalCapacityUsed,
345 "transport-resource additional-capacity cost");
348 fixedUsageCost: fixedUsageCost,
349 additionalCapacityCost:
350 additionalCapacityCost);
361 int transportResourceId,
363 double transportedQuantity,
365 double itemAdditionalCapacityUsed)
367 ValidatePeriod(period);
371 nameof(transportedQuantity));
374 itemAdditionalCapacityUsed,
375 nameof(itemAdditionalCapacityUsed));
378 Queries.GetRequiredTransportCharacteristic(
380 transportResourceId);
382 double fixedSetupCost =
389 double unitUsageCost =
395 "transport unit-usage cost");
397 double additionalCapacityCost =
399 itemAdditionalCapacityUsed,
403 "item-specific transport additional-capacity cost");
406 additionalCapacityCost:
407 additionalCapacityCost,
408 fixedSetupCost: fixedSetupCost,
409 unitUsageCost: unitUsageCost);
414 #region Distribution costs and revenue
424 double backlogQuantity,
425 double shortageQuantity)
427 ArgumentNullException.ThrowIfNull(sourcing);
429 ValidatePeriod(period);
433 nameof(soldQuantity));
437 nameof(backlogQuantity));
441 nameof(shortageQuantity));
445 Index.GetRequiredDistributionCenter(
448 Index.GetRequiredWarehouse(
459 double shortageCost =
476 backlogCost: backlogCost,
477 shortageCost: shortageCost,
483 #region Purchase costs
492 double purchasedQuantity)
494 ArgumentNullException.ThrowIfNull(delivery);
496 ValidatePeriod(period);
500 nameof(purchasedQuantity));
505 Index.GetRequiredWarehouse(
508 double purchaseCost =
517 purchaseCost: purchaseCost);
528 IEnumerable<CostBreakdown> costs)
530 ArgumentNullException.ThrowIfNull(costs);
539 throw new ArgumentException(
540 "The cost collection cannot contain null.",
544 total = total.Add(cost);
552 #region Validation and calculation helpers
554 private void ValidatePeriod(
int period)
559 throw new ArgumentOutOfRangeException(
562 $
"The period must be between 1 and " +
563 $
"{SupplyChain.PlanningHorizon}.");
567 private static void ValidateResourceActivation(
568 bool resourceActivated,
569 double additionalCapacityUsed)
571 if (!resourceActivated &&
572 additionalCapacityUsed > 0.0)
574 throw new InvalidOperationException(
575 "Additional capacity cannot be used when " +
576 "the resource is not activated.");
580 private static void ValidateQuantity(
582 string parameterName)
584 if (!
double.IsFinite(quantity) ||
587 throw new ArgumentOutOfRangeException(
590 "The quantity must be finite and non-negative.");
594 private static double GetCostValue(
596 string parameterName)
598 double value = cost ?? 0.0;
600 if (!
double.IsFinite(value) ||
603 throw new InvalidOperationException(
604 $
"The cost parameter '{parameterName}' must " +
605 "be finite and non-negative.");
611 private static double Multiply(
614 string calculationName)
619 if (!
double.IsFinite(result))
621 throw new InvalidOperationException(
622 $
"The {calculationName} exceeds the " +
623 "supported numerical range.");
673 double fixedUsageCost = 0.0,
674 double additionalCapacityCost = 0.0,
675 double fixedSetupCost = 0.0,
676 double unitUsageCost = 0.0,
677 double safetyStockViolationCost = 0.0,
678 double backlogCost = 0.0,
679 double shortageCost = 0.0,
680 double purchaseCost = 0.0,
681 double revenue = 0.0)
685 nameof(fixedUsageCost));
688 additionalCapacityCost,
689 nameof(additionalCapacityCost));
693 nameof(fixedSetupCost));
697 nameof(unitUsageCost));
700 safetyStockViolationCost,
701 nameof(safetyStockViolationCost));
705 nameof(backlogCost));
709 nameof(shortageCost));
713 nameof(purchaseCost));
722 additionalCapacityCost;
728 safetyStockViolationCost;
737 additionalCapacityCost,
740 safetyStockViolationCost,
749 throw new InvalidOperationException(
750 "The net cost exceeds the supported " +
832 ArgumentNullException.ThrowIfNull(other);
840 additionalCapacityCost:
855 safetyStockViolationCost:
885 $
"Total cost: {TotalCost}; " +
886 $
"revenue: {Revenue}; " +
887 $
"net cost: {NetCost}; " +
891 private static void ValidateCost(
893 string parameterName)
895 if (!
double.IsFinite(cost) ||
898 throw new ArgumentOutOfRangeException(
901 "The cost must be finite and non-negative.");
905 private static double AddFinite(
909 double result = first + second;
911 if (!
double.IsFinite(result))
913 throw new InvalidOperationException(
914 "The aggregated cost exceeds the " +
915 "supported numerical range.");
921 private static double SumFinite(
922 params
double[] values)
926 foreach (
double value
in values)
Represents a detailed cost and revenue calculation.
double FixedUsageCost
Gets the fixed resource-usage cost.
double Margin
Gets the margin, defined as revenue minus costs.
double PurchaseCost
Gets the purchase cost.
double FixedSetupCost
Gets the fixed setup cost.
bool IsEmpty
Gets a value indicating whether the calculation contains neither cost nor revenue.
double Revenue
Gets the sales revenue.
double BacklogCost
Gets the backlog cost.
CostBreakdown(double fixedUsageCost=0.0, double additionalCapacityCost=0.0, double fixedSetupCost=0.0, double unitUsageCost=0.0, double safetyStockViolationCost=0.0, double backlogCost=0.0, double shortageCost=0.0, double purchaseCost=0.0, double revenue=0.0)
Initializes a detailed cost and revenue breakdown.
double ShortageCost
Gets the shortage cost.
double UnitUsageCost
Gets the unit resource-usage cost.
override string ToString()
double SafetyStockViolationCost
Gets the safety-stock violation cost.
double NetCost
Gets total costs minus sales revenue.
double AdditionalCapacityCost
Gets the additional-capacity cost.
static CostBreakdown Empty
Gets an empty cost breakdown.
double TotalCost
Gets the sum of all costs before revenue.
CostBreakdown Add(CostBreakdown other)
Returns a new breakdown containing the sum of the current calculation and another calculation.
CostBreakdown CalculateDistributionCost(DistributionCenterSourcing sourcing, int period, double soldQuantity, double backlogQuantity, double shortageQuantity)
Calculates the distribution penalties and sales revenue associated with a sourcing relationship.
CostBreakdown Aggregate(IEnumerable< CostBreakdown > costs)
Aggregates several cost calculations.
CostBreakdown CalculateTransportActivityCost(int itemId, int transportResourceId, int period, double transportedQuantity, bool setupActivated, double itemAdditionalCapacityUsed)
Calculates the item-specific transport cost during one planning period.
CostAnalyzer(SupplyChainIndex index)
Initializes a cost analyzer using an existing index.
CostBreakdown CalculateWorkCenterResourceCost(WorkCenterReference workCenterReference, int period, bool resourceActivated, double additionalCapacityUsed)
Calculates the global cost of using a work center during one planning period.
CostBreakdown CalculatePurchaseCost(SupplierDelivery delivery, int period, double purchasedQuantity)
Calculates the purchase cost associated with a supplier delivery during one planning period.
CostBreakdown CalculateTransportResourceCost(int transportResourceId, int period, bool resourceActivated, double additionalCapacityUsed)
Calculates the global cost of using a transport resource during one planning period.
SupplyChain SupplyChain
Gets the analyzed supply chain.
CostBreakdown CalculateWarehouseResourceCost(WarehouseReference warehouseReference, int period, bool warehouseActivated, double additionalCapacityUsed)
Calculates the global cost of using a warehouse during one planning period.
SupplyChainIndex Index
Gets the entity index used by the analyzer.
CostBreakdown CalculateProductionActivityCost(int itemId, WorkCenterReference workCenterReference, int period, double productionQuantity, bool setupActivated)
Calculates the item-specific production cost on a work center during one planning period.
void RebuildIndex()
Rebuilds the underlying entity index.
CostBreakdown CalculateInventoryActivityCost(int itemId, WarehouseReference warehouseReference, int period, double inventoryQuantity, bool setupActivated, double itemAdditionalCapacityUsed, double safetyStockViolationQuantity)
Calculates the item-specific storage cost during one planning period.
CostAnalyzer(SupplyChain supplyChain)
Initializes a cost analyzer and creates a new supply-chain index.
SupplyChainQueries Queries
Gets the query service used to resolve relationships.
Provides fast access to the entities contained in a supply chain.
SupplyChain SupplyChain
Gets the indexed supply chain.
A transport resource with its own shared capacities and costs.
AdditionalCapacityCost? AdditionalCapacityCost
Gets or sets the cost of using one unit of additional transport capacity during each planning period.
FixedUsageCost? FixedUsageCost
Gets or sets the fixed cost incurred when the transport resource is used during a planning period.
Represents a warehouse in the supply chain.
FixedUsageCost? FixedUsageCost
Gets or sets the fixed cost incurred when the warehouse is used during a planning period.
AdditionalCapacityCost? AdditionalCapacityCost
Gets or sets the cost of using one unit of global additional warehouse capacity.
Represents a serializable reference to a warehouse.
Represents a production work center belonging to a plant.
FixedUsageCost? FixedUsageCost
Gets or sets the fixed cost incurred when the work center is used during a planning period.
AdditionalCapacityCost? AdditionalCapacityCost
Gets or sets the cost of using one unit of additional capacity during each planning period.
Represents a serializable reference to a work center.
Provides high-level read-only queries over a supply-chain model.
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...
SellingPrice? SellingPrice
Gets or sets the unit selling price of the item supplied by the warehouse to the distribution center ...
ShortageCost? ShortageCost
Gets or sets the unit cost applied to each item unit permanently lost as shortage.
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.
BacklogCost? BacklogCost
Gets or sets the unit cost applied to each item unit remaining in backlog during a planning period.
Represents the inventory of an item in a warehouse.
FixedSetupCost? FixedSetupCost
Gets or sets the fixed preparation cost associated with storing this item.
AdditionalCapacityCost? AdditionalCapacityCost
Gets or sets the cost of using one unit of additional storage capacity for this item.
SafetyStockViolationCost? SafetyStockViolationCost
Gets or sets the cost incurred for each unit missing from the required safety-stock level.
UnitUsageCost? UnitUsageCost
Gets or sets the cost of storing one unit of the item during each planning period.
Represents the production characteristics of an item on a specific work center.
UnitUsageCost? UnitUsageCost
Gets or sets the cost of producing one unit of the item on the work center during each planning perio...
FixedSetupCost? FixedSetupCost
Gets or sets the fixed cost incurred when the work center is prepared to produce the item during a pl...
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.
PurchasePrice? PurchasePrice
Gets or sets the unit purchase price of the item for each planning period.
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.
UnitUsageCost? UnitUsageCost
Gets or sets the cost of transporting one unit of the item during each planning period.
FixedSetupCost? FixedSetupCost
Gets or sets the fixed cost incurred when the transport resource is prepared for this item.
AdditionalCapacityCost? AdditionalCapacityCost
Gets or sets the unit cost of additional transport capacity allocated to this item.
Represents the complete supply-chain data model.
int PlanningHorizon
Gets or sets the number of periods in the global planning horizon.