LotSizingDataModel.Core 2.0.1
Core domain model, shared abstractions and XML-serializable entities.
Loading...
Searching...
No Matches
SupplyChainQueries.cs
Go to the documentation of this file.
1using System;
2using System.Collections.Generic;
3using System.Linq;
9
11
12/// <summary>
13/// Provides high-level read-only queries over a supply-chain model.
14///
15/// Entity references are resolved through <see cref="SupplyChainIndex"/>.
16/// Relationship collections are queried directly from the current
17/// supply-chain model.
18/// </summary>
19public sealed class SupplyChainQueries
20{
21 /// <summary>
22 /// Initializes query services for a supply chain and creates
23 /// a new entity index.
24 /// </summary>
25 public SupplyChainQueries(SupplyChain supplyChain)
26 : this(new SupplyChainIndex(
27 supplyChain ??
28 throw new ArgumentNullException(nameof(supplyChain))))
29 {
30 }
31
32 /// <summary>
33 /// Initializes query services using an existing index.
34 /// </summary>
36 {
37 Index = index ??
38 throw new ArgumentNullException(nameof(index));
39
41 }
42
43 /// <summary>
44 /// Gets the queried supply chain.
45 /// </summary>
46 public SupplyChain SupplyChain { get; }
47
48 /// <summary>
49 /// Gets the entity index used to resolve references.
50 /// </summary>
51 public SupplyChainIndex Index { get; }
52
53 /// <summary>
54 /// Rebuilds the underlying entity index.
55 ///
56 /// Call this method after directly adding or removing entities
57 /// from the supply-chain collections.
58 /// </summary>
59 public void RebuildIndex()
60 {
61 Index.Rebuild();
62 }
63
64 #region Inventory queries
65
66 /// <summary>
67 /// Finds the inventory associated with an item and a warehouse.
68 ///
69 /// Returns null when the relationship does not exist.
70 /// </summary>
72 int itemId,
73 WarehouseReference warehouse)
74 {
75 ArgumentNullException.ThrowIfNull(warehouse);
76
77 return SupplyChain.Inventories.FirstOrDefault(
78 inventory =>
79 inventory.ItemId == itemId &&
80 SameWarehouse(
81 inventory.Warehouse,
82 warehouse));
83 }
84
85 /// <summary>
86 /// Gets the inventory associated with an item and a warehouse.
87 /// </summary>
88 /// <exception cref="KeyNotFoundException">
89 /// Thrown when the inventory relationship does not exist.
90 /// </exception>
92 int itemId,
93 WarehouseReference warehouse)
94 {
95 ArgumentNullException.ThrowIfNull(warehouse);
96
97 return FindInventory(itemId, warehouse) ??
98 throw new KeyNotFoundException(
99 $"No inventory exists for item {itemId} and " +
100 $"warehouse {FormatWarehouse(warehouse)}.");
101 }
102
103 /// <summary>
104 /// Gets all inventories defined for an item.
105 /// </summary>
106 public IReadOnlyList<Inventory> GetInventoriesForItem(
107 int itemId)
108 {
109 Index.GetRequiredItem(itemId);
110
112 .Where(inventory => inventory.ItemId == itemId)
113 .ToArray();
114 }
115
116 /// <summary>
117 /// Gets all inventories defined in a warehouse.
118 /// </summary>
119 public IReadOnlyList<Inventory> GetInventoriesForWarehouse(
120 WarehouseReference warehouse)
121 {
122 ArgumentNullException.ThrowIfNull(warehouse);
123
124 Index.GetRequiredWarehouse(warehouse);
125
127 .Where(
128 inventory =>
129 SameWarehouse(
130 inventory.Warehouse,
131 warehouse))
132 .ToArray();
133 }
134
135 /// <summary>
136 /// Gets the items that can be stored in a warehouse.
137 /// </summary>
138 public IReadOnlyList<Item> GetItemsStoredInWarehouse(
139 WarehouseReference warehouse)
140 {
141 return GetInventoriesForWarehouse(warehouse)
142 .Select(
143 inventory =>
144 Index.GetRequiredItem(inventory.ItemId))
145 .ToArray();
146 }
147
148 #endregion
149
150 #region Production-routing queries
151
152 /// <summary>
153 /// Finds a production routing by its identifier.
154 /// </summary>
156 int routingId)
157 {
158 return SupplyChain.ProductionRoutings.FirstOrDefault(
159 routing => routing.Id == routingId);
160 }
161
162 /// <summary>
163 /// Gets a production routing by its identifier.
164 /// </summary>
166 int routingId)
167 {
168 return FindProductionRouting(routingId) ??
169 throw new KeyNotFoundException(
170 $"Production routing {routingId} does not exist.");
171 }
172
173 /// <summary>
174 /// Gets all production routings available for an item.
175 /// </summary>
176 public IReadOnlyList<ProductionRouting>
178 {
179 Index.GetRequiredItem(itemId);
180
182 .Where(routing => routing.ItemId == itemId)
183 .ToArray();
184 }
185
186 /// <summary>
187 /// Gets all production routings belonging to a plant.
188 /// </summary>
189 public IReadOnlyList<ProductionRouting>
191 {
192 Index.GetRequiredPlant(plantId);
193
195 .Where(routing => routing.PlantId == plantId)
196 .ToArray();
197 }
198
199 /// <summary>
200 /// Gets all production routings for an item in a plant.
201 /// </summary>
202 public IReadOnlyList<ProductionRouting>
204 int itemId,
205 int plantId)
206 {
207 Index.GetRequiredItem(itemId);
208 Index.GetRequiredPlant(plantId);
209
211 .Where(
212 routing =>
213 routing.ItemId == itemId &&
214 routing.PlantId == plantId)
215 .ToArray();
216 }
217
218 #endregion
219
220 #region Production-characteristic queries
221
222 /// <summary>
223 /// Finds the production characteristic associated with
224 /// an item and a work center.
225 /// </summary>
228 int itemId,
229 WorkCenterReference workCenter)
230 {
231 ArgumentNullException.ThrowIfNull(workCenter);
232
234 .FirstOrDefault(
235 characteristic =>
236 characteristic.ItemId == itemId &&
237 SameWorkCenter(
238 characteristic.WorkCenter,
239 workCenter));
240 }
241
242 /// <summary>
243 /// Gets the production characteristic associated with
244 /// an item and a work center.
245 /// </summary>
248 int itemId,
249 WorkCenterReference workCenter)
250 {
251 ArgumentNullException.ThrowIfNull(workCenter);
252
254 itemId,
255 workCenter) ??
256 throw new KeyNotFoundException(
257 $"No production characteristic exists for " +
258 $"item {itemId} and work center " +
259 $"{FormatWorkCenter(workCenter)}.");
260 }
261
262 /// <summary>
263 /// Gets all production characteristics defined for an item.
264 /// </summary>
265 public IReadOnlyList<ProductionCharacteristic>
267 {
268 Index.GetRequiredItem(itemId);
269
271 .Where(
272 characteristic =>
273 characteristic.ItemId == itemId)
274 .ToArray();
275 }
276
277 /// <summary>
278 /// Gets all production characteristics using a work center.
279 /// </summary>
280 public IReadOnlyList<ProductionCharacteristic>
282 WorkCenterReference workCenter)
283 {
284 ArgumentNullException.ThrowIfNull(workCenter);
285
286 Index.GetRequiredWorkCenter(workCenter);
287
289 .Where(
290 characteristic =>
291 SameWorkCenter(
292 characteristic.WorkCenter,
293 workCenter))
294 .ToArray();
295 }
296
297 /// <summary>
298 /// Gets all items that may be produced on a work center.
299 /// </summary>
300 public IReadOnlyList<Item> GetItemsProducedByWorkCenter(
301 WorkCenterReference workCenter)
302 {
304 workCenter)
305 .Select(
306 characteristic =>
307 Index.GetRequiredItem(
308 characteristic.ItemId))
309 .ToArray();
310 }
311
312 #endregion
313
314 #region Demand queries
315
316 /// <summary>
317 /// Finds the demand associated with an item and
318 /// a distribution center.
319 /// </summary>
321 int itemId,
322 int distributionCenterId)
323 {
324 return SupplyChain.Demands.FirstOrDefault(
325 demand =>
326 demand.ItemId == itemId &&
327 demand.DistributionCenterId ==
328 distributionCenterId);
329 }
330
331 /// <summary>
332 /// Gets the demand associated with an item and
333 /// a distribution center.
334 /// </summary>
336 int itemId,
337 int distributionCenterId)
338 {
339 return FindDemand(
340 itemId,
341 distributionCenterId) ??
342 throw new KeyNotFoundException(
343 $"No demand exists for item {itemId} and " +
344 $"distribution center {distributionCenterId}.");
345 }
346
347 /// <summary>
348 /// Gets all demands for an item.
349 /// </summary>
350 public IReadOnlyList<Demand> GetDemandsForItem(
351 int itemId)
352 {
353 Index.GetRequiredItem(itemId);
354
356 .Where(demand => demand.ItemId == itemId)
357 .ToArray();
358 }
359
360 /// <summary>
361 /// Gets all demands expressed by a distribution center.
362 /// </summary>
363 public IReadOnlyList<Demand>
365 int distributionCenterId)
366 {
367 Index.GetRequiredDistributionCenter(
368 distributionCenterId);
369
371 .Where(
372 demand =>
373 demand.DistributionCenterId ==
374 distributionCenterId)
375 .ToArray();
376 }
377
378 /// <summary>
379 /// Gets the demand quantity for a specific period.
380 /// </summary>
381 public double GetDemandQuantity(
382 int itemId,
383 int distributionCenterId,
384 int period)
385 {
386 ValidatePeriod(period);
387
388 return GetRequiredDemand(
389 itemId,
390 distributionCenterId)
391 .GetQuantity(period);
392 }
393
394 #endregion
395
396 #region Distribution-center sourcing queries
397
398 /// <summary>
399 /// Gets all warehouse sourcing options available for
400 /// an item and a distribution center.
401 /// </summary>
402 public IReadOnlyList<DistributionCenterSourcing>
404 int distributionCenterId,
405 int itemId)
406 {
407 Index.GetRequiredDistributionCenter(
408 distributionCenterId);
409
410 Index.GetRequiredItem(itemId);
411
413 .Where(
414 sourcing =>
415 sourcing.DistributionCenterId ==
416 distributionCenterId &&
417 sourcing.ItemId == itemId)
418 .ToArray();
419 }
420
421 /// <summary>
422 /// Gets all sourcing relationships using a warehouse.
423 /// </summary>
424 public IReadOnlyList<DistributionCenterSourcing>
426 WarehouseReference warehouse)
427 {
428 ArgumentNullException.ThrowIfNull(warehouse);
429
430 Index.GetRequiredWarehouse(warehouse);
431
433 .Where(
434 sourcing =>
435 SameWarehouse(
436 sourcing.Warehouse,
437 warehouse))
438 .ToArray();
439 }
440
441 /// <summary>
442 /// Gets the warehouses that can supply an item to
443 /// a distribution center.
444 /// </summary>
445 public IReadOnlyList<Warehouse>
447 int distributionCenterId,
448 int itemId)
449 {
450 return GetSourcingOptions(
451 distributionCenterId,
452 itemId)
453 .Select(
454 sourcing =>
455 Index.GetRequiredWarehouse(
456 sourcing.Warehouse))
457 .ToArray();
458 }
459
460 #endregion
461
462 #region Supplier-delivery queries
463
464 /// <summary>
465 /// Gets all delivery possibilities offered by a supplier.
466 /// </summary>
467 public IReadOnlyList<SupplierDelivery>
469 {
470 Index.GetRequiredSupplier(supplierId);
471
473 .Where(
474 delivery =>
475 delivery.SupplierId == supplierId)
476 .ToArray();
477 }
478
479 /// <summary>
480 /// Gets all supplier deliveries available for an item.
481 /// </summary>
482 public IReadOnlyList<SupplierDelivery>
484 {
485 Index.GetRequiredItem(itemId);
486
488 .Where(delivery => delivery.ItemId == itemId)
489 .ToArray();
490 }
491
492 /// <summary>
493 /// Gets all supplier deliveries whose destination is
494 /// the specified warehouse.
495 /// </summary>
496 public IReadOnlyList<SupplierDelivery>
498 WarehouseReference warehouse)
499 {
500 ArgumentNullException.ThrowIfNull(warehouse);
501
502 Index.GetRequiredWarehouse(warehouse);
503
505 .Where(
506 delivery =>
507 SameWarehouse(
508 delivery.Warehouse,
509 warehouse))
510 .ToArray();
511 }
512
513 /// <summary>
514 /// Gets all suppliers able to deliver an item
515 /// to a warehouse.
516 /// </summary>
517 public IReadOnlyList<Supplier>
519 int itemId,
520 WarehouseReference warehouse)
521 {
522 GetRequiredInventory(itemId, warehouse);
523
525 .Where(
526 delivery =>
527 delivery.ItemId == itemId &&
528 SameWarehouse(
529 delivery.Warehouse,
530 warehouse))
531 .Select(
532 delivery =>
533 Index.GetRequiredSupplier(
534 delivery.SupplierId))
535 .ToArray();
536 }
537
538 #endregion
539
540 #region Transport-characteristic queries
541
542 /// <summary>
543 /// Finds the transport characteristic associated with
544 /// an item and a transport resource.
545 /// </summary>
548 int itemId,
549 int transportResourceId)
550 {
552 .FirstOrDefault(
553 characteristic =>
554 characteristic.ItemId == itemId &&
555 characteristic.TransportResourceId ==
556 transportResourceId);
557 }
558
559 /// <summary>
560 /// Gets the transport characteristic associated with
561 /// an item and a transport resource.
562 /// </summary>
565 int itemId,
566 int transportResourceId)
567 {
569 itemId,
570 transportResourceId) ??
571 throw new KeyNotFoundException(
572 $"No transport characteristic exists for " +
573 $"item {itemId} and transport resource " +
574 $"{transportResourceId}.");
575 }
576
577 /// <summary>
578 /// Gets all transport characteristics available for an item.
579 /// </summary>
580 public IReadOnlyList<TransportCharacteristic>
582 {
583 Index.GetRequiredItem(itemId);
584
586 .Where(
587 characteristic =>
588 characteristic.ItemId == itemId)
589 .ToArray();
590 }
591
592 /// <summary>
593 /// Gets all items compatible with a transport resource.
594 /// </summary>
595 public IReadOnlyList<Item>
597 int transportResourceId)
598 {
599 Index.GetRequiredTransportResource(
600 transportResourceId);
601
603 .Where(
604 characteristic =>
605 characteristic.TransportResourceId ==
606 transportResourceId)
607 .Select(
608 characteristic =>
609 Index.GetRequiredItem(
610 characteristic.ItemId))
611 .ToArray();
612 }
613
614 #endregion
615
616 #region Transport-lane queries
617
618 /// <summary>
619 /// Gets all direct transport options leaving a warehouse.
620 /// </summary>
621 public IReadOnlyList<DirectTransportOption>
623 WarehouseReference origin)
624 {
625 ArgumentNullException.ThrowIfNull(origin);
626
627 Index.GetRequiredWarehouse(origin);
628
629 return EnumerateTransportOptions()
630 .Where(
631 option =>
632 SameWarehouse(
633 option.Lane.Origin,
634 origin))
635 .ToArray();
636 }
637
638 /// <summary>
639 /// Gets all direct transport options arriving at a warehouse.
640 /// </summary>
641 public IReadOnlyList<DirectTransportOption>
643 WarehouseReference destination)
644 {
645 ArgumentNullException.ThrowIfNull(destination);
646
647 Index.GetRequiredWarehouse(destination);
648
649 return EnumerateTransportOptions()
650 .Where(
651 option =>
652 SameWarehouse(
653 option.Lane.Destination,
654 destination))
655 .ToArray();
656 }
657
658 /// <summary>
659 /// Gets all direct transport options between two warehouses.
660 /// </summary>
661 public IReadOnlyList<DirectTransportOption>
663 WarehouseReference origin,
664 WarehouseReference destination)
665 {
666 ArgumentNullException.ThrowIfNull(origin);
667 ArgumentNullException.ThrowIfNull(destination);
668
669 Index.GetRequiredWarehouse(origin);
670 Index.GetRequiredWarehouse(destination);
671
672 return EnumerateTransportOptions()
673 .Where(
674 option =>
675 SameWarehouse(
676 option.Lane.Origin,
677 origin) &&
678 SameWarehouse(
679 option.Lane.Destination,
680 destination))
681 .ToArray();
682 }
683
684 /// <summary>
685 /// Determines whether at least one direct transport option
686 /// exists between two warehouses.
687 /// </summary>
689 WarehouseReference origin,
690 WarehouseReference destination)
691 {
692 ArgumentNullException.ThrowIfNull(origin);
693 ArgumentNullException.ThrowIfNull(destination);
694
696 origin,
697 destination).Count > 0;
698 }
699
700 /// <summary>
701 /// Gets the direct transport options that can carry
702 /// a specified item.
703 /// </summary>
704 public IReadOnlyList<DirectTransportOption>
706 int itemId,
707 WarehouseReference origin,
708 WarehouseReference destination)
709 {
710 Index.GetRequiredItem(itemId);
711
712 // Build the set of transport resources compatible with the item.
713 HashSet<int> compatibleResourceIds =
715 .Where(
716 characteristic =>
717 characteristic.ItemId == itemId)
718 .Select(
719 characteristic =>
720 characteristic.TransportResourceId)
721 .ToHashSet();
722
724 origin,
725 destination)
726 .Where(
727 option =>
728 compatibleResourceIds.Contains(
729 option.TransportResource.Id))
730 .ToArray();
731 }
732
733 private IEnumerable<DirectTransportOption>
734 EnumerateTransportOptions()
735 {
736 foreach (TransportResource resource
738 {
739 foreach (AssignedTransportLane lane in SupplyChain.GetTransportLanes(resource.Id))
740 {
741 yield return new DirectTransportOption(
742 resource,
743 lane);
744 }
745 }
746 }
747
748 #endregion
749
750 #region Capacity queries
751
752 /// <summary>
753 /// Gets the capacity available on a work center
754 /// during a planning period.
755 /// </summary>
757 WorkCenterReference workCenter,
758 int period)
759 {
760 ArgumentNullException.ThrowIfNull(workCenter);
761 ValidatePeriod(period);
762
763 WorkCenter resource =
764 Index.GetRequiredWorkCenter(workCenter);
765
766 return CreateCapacitySnapshot(
767 resource.CapacityConstraint,
768 resource.AdditionalCapacity,
769 period,
770 isItemSpecific: false);
771 }
772
773 /// <summary>
774 /// Gets the global capacity of a warehouse
775 /// during a planning period.
776 /// </summary>
778 WarehouseReference warehouse,
779 int period)
780 {
781 ArgumentNullException.ThrowIfNull(warehouse);
782 ValidatePeriod(period);
783
784 Warehouse resource =
785 Index.GetRequiredWarehouse(warehouse);
786
787 return CreateCapacitySnapshot(
788 resource.CapacityConstraint,
789 resource.AdditionalCapacity,
790 period,
791 isItemSpecific: false);
792 }
793
794 /// <summary>
795 /// Gets the capacity applicable to a specific inventory.
796 ///
797 /// An item-specific capacity is used when it exists.
798 /// Otherwise, the global warehouse capacity is returned.
799 /// </summary>
801 int itemId,
802 WarehouseReference warehouse,
803 int period)
804 {
805 ArgumentNullException.ThrowIfNull(warehouse);
806 ValidatePeriod(period);
807
808 Inventory inventory =
810 itemId,
811 warehouse);
812
813 // Use item-specific capacity if defined; otherwise fall back to global warehouse capacity.
814 if (inventory.CapacityConstraint is not null)
815 {
816 return CreateCapacitySnapshot(
817 inventory.CapacityConstraint,
818 inventory.AdditionalCapacity,
819 period,
820 isItemSpecific: true);
821 }
822
824 warehouse,
825 period);
826 }
827
828 /// <summary>
829 /// Gets the global capacity of a transport resource
830 /// during a planning period.
831 /// </summary>
833 int transportResourceId,
834 int period)
835 {
836 ValidatePeriod(period);
837
838 TransportResource resource =
839 Index.GetRequiredTransportResource(
840 transportResourceId);
841
842 return CreateCapacitySnapshot(
843 resource.CapacityConstraint,
844 resource.AdditionalCapacity,
845 period,
846 isItemSpecific: false);
847 }
848
849 /// <summary>
850 /// Gets the capacity applicable to an item transported
851 /// by a transport resource.
852 ///
853 /// An item-specific capacity is used when it exists.
854 /// Otherwise, the global transport-resource capacity is returned.
855 /// </summary>
857 int itemId,
858 int transportResourceId,
859 int period)
860 {
861 ValidatePeriod(period);
862
863 TransportCharacteristic characteristic =
865 itemId,
866 transportResourceId);
867
868 // Use item-specific capacity if defined; otherwise fall back to global resource capacity.
869 if (characteristic.CapacityConstraint is not null)
870 {
871 return CreateCapacitySnapshot(
872 characteristic.CapacityConstraint,
873 characteristic.AdditionalCapacity,
874 period,
875 isItemSpecific: true);
876 }
877
879 transportResourceId,
880 period);
881 }
882
883 private static CapacitySnapshot CreateCapacitySnapshot(
884 CapacityConstraint? regularCapacity,
885 AdditionalCapacity? additionalCapacity,
886 int period,
887 bool isItemSpecific)
888 {
889 double? maximumRegularCapacity =
890 regularCapacity?.GetMaximumCapacity(period);
891
892 double? maximumAdditionalCapacity =
893 additionalCapacity
895
896 return new CapacitySnapshot(
897 maximumRegularCapacity,
898 maximumAdditionalCapacity,
899 isItemSpecific);
900 }
901
902 #endregion
903
904 #region Helpers
905
906 private void ValidatePeriod(int period)
907 {
908 if (period < 1 ||
910 {
911 throw new ArgumentOutOfRangeException(
912 nameof(period),
913 period,
914 $"The period must be between 1 and " +
915 $"{SupplyChain.PlanningHorizon}.");
916 }
917 }
918
919 private static bool SameWarehouse(
920 WarehouseReference? first,
921 WarehouseReference? second)
922 {
923 // Null-safe: both null = equal, only one null = not equal.
924 if (first is null || second is null)
925 {
926 return first is null && second is null;
927 }
928
929 return first.Kind == second.Kind &&
930 first.ReferenceId == second.ReferenceId;
931 }
932
933 private static bool SameWorkCenter(
934 WorkCenterReference? first,
935 WorkCenterReference? second)
936 {
937 // Null-safe: both null = equal, only one null = not equal.
938 if (first is null || second is null)
939 {
940 return first is null && second is null;
941 }
942
943 return first.PlantId == second.PlantId &&
944 first.WorkCenterId == second.WorkCenterId;
945 }
946
947 private static string FormatWarehouse(
948 WarehouseReference reference)
949 {
950 return $"{reference.Kind}:{reference.ReferenceId}";
951 }
952
953 private static string FormatWorkCenter(
954 WorkCenterReference reference)
955 {
956 return
957 $"{reference.PlantId}:{reference.WorkCenterId}";
958 }
959
960 #endregion
961
962 /// <summary>
963 /// Represents one direct transport possibility between
964 /// two warehouses.
965 /// </summary>
966 public sealed class DirectTransportOption
967 {
968 /// <summary>
969 /// Initializes a direct transport option associating
970 /// a transport resource with one of its lanes.
971 /// </summary>
972 /// <param name="transportResource">
973 /// Transport resource performing the movement.
974 /// </param>
975 /// <param name="lane">
976 /// Directed transport lane used by the option.
977 /// </param>
979 TransportResource transportResource,
981 {
982 TransportResource = transportResource ??
983 throw new ArgumentNullException(
984 nameof(transportResource));
985
986 Lane = lane ??
987 throw new ArgumentNullException(nameof(lane));
988 }
989
990 /// <summary>
991 /// Gets the transport resource performing the movement.
992 /// </summary>
994
995 /// <summary>
996 /// Gets the origin, destination and lead time.
997 /// </summary>
999
1000 /// <summary>
1001 /// Gets the direct-transport lead time.
1002 /// </summary>
1003 public int LeadTime => Lane.LeadTime;
1004
1005 /// <inheritdoc/>
1006 public override string ToString()
1007 {
1008 return
1009 $"{TransportResource.Name}: " +
1010 $"{FormatWarehouse(Lane.Origin)} -> " +
1011 $"{FormatWarehouse(Lane.Destination)} " +
1012 $"({LeadTime} period(s))";
1013 }
1014 }
1015
1016 /// <summary>
1017 /// Represents the maximum regular and additional capacity
1018 /// available during one planning period.
1019 /// </summary>
1020 public sealed class CapacitySnapshot
1021 {
1022 /// <summary>
1023 /// Initializes a capacity snapshot for one resource
1024 /// and one planning period.
1025 /// </summary>
1026 /// <param name="maximumRegularCapacity">
1027 /// Maximum regular capacity,
1028 /// or null when no regular-capacity constraint exists.
1029 /// </param>
1030 /// <param name="maximumAdditionalCapacity">
1031 /// Maximum additional capacity,
1032 /// or null when no additional capacity is defined.
1033 /// </param>
1034 /// <param name="isItemSpecific">
1035 /// Indicates whether the capacity belongs to an
1036 /// item-specific relationship.
1037 /// </param>
1039 double? maximumRegularCapacity,
1040 double? maximumAdditionalCapacity,
1041 bool isItemSpecific)
1042 {
1044 maximumRegularCapacity;
1045
1047 maximumAdditionalCapacity;
1048
1049 IsItemSpecific = isItemSpecific;
1050 }
1051
1052 /// <summary>
1053 /// Gets the regular-capacity limit.
1054 ///
1055 /// Null means that no regular-capacity constraint is defined.
1056 /// </summary>
1057 public double? MaximumRegularCapacity { get; }
1058
1059 /// <summary>
1060 /// Gets the additional-capacity limit.
1061 ///
1062 /// Null means that no additional capacity is defined.
1063 /// </summary>
1064 public double? MaximumAdditionalCapacity { get; }
1065
1066 /// <summary>
1067 /// Gets a value indicating whether the capacity is defined
1068 /// specifically for an item-resource relationship.
1069 /// </summary>
1070 public bool IsItemSpecific { get; }
1071
1072 /// <summary>
1073 /// Gets a value indicating whether a regular-capacity
1074 /// constraint is active.
1075 /// </summary>
1076 public bool HasRegularCapacity =>
1077 MaximumRegularCapacity.HasValue;
1078
1079 /// <summary>
1080 /// Gets a value indicating whether additional capacity
1081 /// is available.
1082 /// </summary>
1085
1086 /// <summary>
1087 /// Gets the total maximum capacity.
1088 ///
1089 /// Returns null when no regular-capacity constraint exists.
1090 /// </summary>
1091 public double? TotalMaximumCapacity =>
1092 MaximumRegularCapacity.HasValue
1093 ? MaximumRegularCapacity.Value +
1095 : null;
1096
1097 /// <inheritdoc/>
1098 public override string ToString()
1099 {
1100 if (!MaximumRegularCapacity.HasValue)
1101 {
1102 return "No capacity constraint";
1103 }
1104
1105 return
1106 $"Regular: {MaximumRegularCapacity.Value}; " +
1107 $"Additional: " +
1108 $"{MaximumAdditionalCapacity ?? 0.0}; " +
1109 $"Total: {TotalMaximumCapacity}";
1110 }
1111 }
1112}
int Id
Gets or sets the numerical identifier of the entity.
Represents the maximum additional capacity that may be used during each planning period.
double GetMaximumAdditionalCapacity(int period)
Gets the maximum additional capacity available during a planning period.
Represents a maximum-capacity constraint defined for each planning period.
double GetMaximumCapacity(int period)
Gets the maximum capacity available during a planning period.
Provides fast access to the entities contained in a supply chain.
SupplyChain SupplyChain
Gets the indexed supply chain.
A runtime join of the central lane and assignment; stores no copied business data.
A transport resource with its own shared capacities and costs.
AdditionalCapacity? AdditionalCapacity
Gets or sets the maximum additional capacity that may be allocated to the transport resource during e...
CapacityConstraint? CapacityConstraint
Gets or sets the maximum regular capacity available for the transport resource during each planning p...
Represents a warehouse in the supply chain.
Definition Warehouse.cs:19
AdditionalCapacity? AdditionalCapacity
Gets or sets the maximum additional storage capacity that may be allocated to the warehouse.
CapacityConstraint? CapacityConstraint
Gets or sets the maximum global storage capacity of the warehouse during each planning period.
Represents a serializable reference to a warehouse.
int ReferenceId
Gets or sets the referenced identifier.
Represents a production work center belonging to a plant.
Definition WorkCenter.cs:15
CapacityConstraint? CapacityConstraint
Gets or sets the maximum regular capacity available during each planning period.
AdditionalCapacity? AdditionalCapacity
Gets or sets the maximum additional capacity that may be allocated during each planning period.
Represents a serializable reference to a work center.
int WorkCenterId
Gets or sets the identifier of the referenced work center.
Represents the maximum regular and additional capacity available during one planning period.
bool HasRegularCapacity
Gets a value indicating whether a regular-capacity constraint is active.
bool IsItemSpecific
Gets a value indicating whether the capacity is defined specifically for an item-resource relationshi...
CapacitySnapshot(double? maximumRegularCapacity, double? maximumAdditionalCapacity, bool isItemSpecific)
Initializes a capacity snapshot for one resource and one planning period.
bool HasAdditionalCapacity
Gets a value indicating whether additional capacity is available.
DirectTransportOption(TransportResource transportResource, AssignedTransportLane lane)
Initializes a direct transport option associating a transport resource with one of its lanes.
AssignedTransportLane Lane
Gets the origin, destination and lead time.
TransportResource TransportResource
Gets the transport resource performing the movement.
IReadOnlyList< Supplier > GetSuppliersForInventory(int itemId, WarehouseReference warehouse)
Gets all suppliers able to deliver an item to a warehouse.
IReadOnlyList< SupplierDelivery > GetDeliveriesFromSupplier(int supplierId)
Gets all delivery possibilities offered by a supplier.
IReadOnlyList< Inventory > GetInventoriesForItem(int itemId)
Gets all inventories defined for an item.
Inventory GetRequiredInventory(int itemId, WarehouseReference warehouse)
Gets the inventory associated with an item and a warehouse.
IReadOnlyList< TransportCharacteristic > GetTransportCharacteristicsForItem(int itemId)
Gets all transport characteristics available for an item.
ProductionCharacteristic? FindProductionCharacteristic(int itemId, WorkCenterReference workCenter)
Finds the production characteristic associated with an item and a work center.
ProductionCharacteristic GetRequiredProductionCharacteristic(int itemId, WorkCenterReference workCenter)
Gets the production characteristic associated with an item and a work center.
IReadOnlyList< Demand > GetDemandsForItem(int itemId)
Gets all demands for an item.
SupplyChainQueries(SupplyChain supplyChain)
Initializes query services for a supply chain and creates a new entity index.
TransportCharacteristic? FindTransportCharacteristic(int itemId, int transportResourceId)
Finds the transport characteristic associated with an item and a transport resource.
IReadOnlyList< DirectTransportOption > GetDirectTransportOptionsForItem(int itemId, WarehouseReference origin, WarehouseReference destination)
Gets the direct transport options that can carry a specified item.
IReadOnlyList< ProductionRouting > GetProductionRoutingsForItem(int itemId)
Gets all production routings available for an item.
TransportCharacteristic GetRequiredTransportCharacteristic(int itemId, int transportResourceId)
Gets the transport characteristic associated with an item and a transport resource.
IReadOnlyList< Item > GetItemsProducedByWorkCenter(WorkCenterReference workCenter)
Gets all items that may be produced on a work center.
Demand? FindDemand(int itemId, int distributionCenterId)
Finds the demand associated with an item and a distribution center.
SupplyChainQueries(SupplyChainIndex index)
Initializes query services using an existing index.
void RebuildIndex()
Rebuilds the underlying entity index.
IReadOnlyList< ProductionCharacteristic > GetProductionCharacteristicsForWorkCenter(WorkCenterReference workCenter)
Gets all production characteristics using a work center.
ProductionRouting GetRequiredProductionRouting(int routingId)
Gets a production routing by its identifier.
SupplyChainIndex Index
Gets the entity index used to resolve references.
IReadOnlyList< DistributionCenterSourcing > GetSourcingsFromWarehouse(WarehouseReference warehouse)
Gets all sourcing relationships using a warehouse.
IReadOnlyList< SupplierDelivery > GetDeliveriesForItem(int itemId)
Gets all supplier deliveries available for an item.
CapacitySnapshot GetTransportResourceCapacity(int transportResourceId, int period)
Gets the global capacity of a transport resource during a planning period.
IReadOnlyList< ProductionCharacteristic > GetProductionCharacteristicsForItem(int itemId)
Gets all production characteristics defined for an item.
IReadOnlyList< SupplierDelivery > GetDeliveriesToWarehouse(WarehouseReference warehouse)
Gets all supplier deliveries whose destination is the specified warehouse.
CapacitySnapshot GetWorkCenterCapacity(WorkCenterReference workCenter, int period)
Gets the capacity available on a work center during a planning period.
IReadOnlyList< Demand > GetDemandsForDistributionCenter(int distributionCenterId)
Gets all demands expressed by a distribution center.
Inventory? FindInventory(int itemId, WarehouseReference warehouse)
Finds the inventory associated with an item and a warehouse.
IReadOnlyList< Item > GetItemsStoredInWarehouse(WarehouseReference warehouse)
Gets the items that can be stored in a warehouse.
IReadOnlyList< Warehouse > GetSupplyingWarehouses(int distributionCenterId, int itemId)
Gets the warehouses that can supply an item to a distribution center.
IReadOnlyList< DistributionCenterSourcing > GetSourcingOptions(int distributionCenterId, int itemId)
Gets all warehouse sourcing options available for an item and a distribution center.
CapacitySnapshot GetInventoryCapacity(int itemId, WarehouseReference warehouse, int period)
Gets the capacity applicable to a specific inventory.
IReadOnlyList< DirectTransportOption > GetIncomingTransportOptions(WarehouseReference destination)
Gets all direct transport options arriving at a warehouse.
IReadOnlyList< DirectTransportOption > GetOutgoingTransportOptions(WarehouseReference origin)
Gets all direct transport options leaving a warehouse.
CapacitySnapshot GetWarehouseCapacity(WarehouseReference warehouse, int period)
Gets the global capacity of a warehouse during a planning period.
Demand GetRequiredDemand(int itemId, int distributionCenterId)
Gets the demand associated with an item and a distribution center.
IReadOnlyList< ProductionRouting > GetProductionRoutingsForPlant(int plantId)
Gets all production routings belonging to a plant.
CapacitySnapshot GetTransportCapacity(int itemId, int transportResourceId, int period)
Gets the capacity applicable to an item transported by a transport resource.
ProductionRouting? FindProductionRouting(int routingId)
Finds a production routing by its identifier.
IReadOnlyList< DirectTransportOption > GetDirectTransportOptions(WarehouseReference origin, WarehouseReference destination)
Gets all direct transport options between two warehouses.
SupplyChain SupplyChain
Gets the queried supply chain.
IReadOnlyList< Item > GetItemsTransportedByResource(int transportResourceId)
Gets all items compatible with a transport resource.
IReadOnlyList< Inventory > GetInventoriesForWarehouse(WarehouseReference warehouse)
Gets all inventories defined in a warehouse.
IReadOnlyList< ProductionRouting > GetProductionRoutings(int itemId, int plantId)
Gets all production routings for an item in a plant.
bool HasDirectTransportConnection(WarehouseReference origin, WarehouseReference destination)
Determines whether at least one direct transport option exists between two warehouses.
double GetDemandQuantity(int itemId, int distributionCenterId, int period)
Gets the demand quantity for a specific period.
Represents the demand for an item issued by a distribution center.
Definition Demand.cs:22
double GetQuantity(int period)
Gets the demand quantity for a planning period.
Definition Demand.cs:168
Represents the inventory of an item in a warehouse.
Definition Inventory.cs:20
AdditionalCapacity? AdditionalCapacity
Gets or sets the maximum additional storage capacity available specifically for this item.
CapacityConstraint? CapacityConstraint
Gets or sets the maximum storage capacity reserved for this item during each planning period.
Represents the production characteristics of an item on a specific work center.
Represents a production routing used to manufacture an item in a plant through one or more work cente...
Represents the transport characteristics of an item for a specific transport resource.
AdditionalCapacity? AdditionalCapacity
Gets or sets the maximum additional transport capacity available specifically for this item.
CapacityConstraint? CapacityConstraint
Gets or sets the maximum transport capacity available specifically for this item during each planning...
Represents the complete supply-chain data model.
List< Inventory > Inventories
Gets the item-warehouse inventories.
List< TransportResource > TransportResources
Gets the transport resources in the supply chain.
List< SupplierDelivery > SupplierDeliveries
Gets the supplier delivery possibilities.
List< DistributionCenterSourcing > DistributionCenterSourcings
Gets the warehouse sourcing options available to distribution centers.
IEnumerable< AssignedTransportLane > GetTransportLanes(int resourceId)
List< ProductionCharacteristic > ProductionCharacteristics
Gets the item-work-center production characteristics.
int PlanningHorizon
Gets or sets the number of periods in the global planning horizon.
List< TransportCharacteristic > TransportCharacteristics
Gets the item-transport-resource characteristics.
List< ProductionRouting > ProductionRoutings
Gets the production routings.
List< Demand > Demands
Gets the demands expressed by distribution centers.