LotSizingDataModel.Solution 2.0.1
Solution objects for production, setup, inventory and related decisions.
Loading...
Searching...
No Matches
WorkCenterSchedulingDecision.cs
Go to the documentation of this file.
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Xml.Serialization;
5using LotSizingDataModel.Core.Common;
6using LotSizingDataModel.Core.PhysicalModel;
7
9
10[Serializable]
11[XmlType(TypeName = "workCenterSchedulingDecision")]
12public sealed class WorkCenterSchedulingDecision :
13 ModelObject,
14 IPlanningHorizonAware
15{
16 private WorkCenterReference _workCenter = new();
17 private int _planningHorizon;
18
20 {
21 }
22
24 WorkCenterReference workCenter,
25 int planningHorizon)
26 {
27 WorkCenter = workCenter ??
28 throw new ArgumentNullException(nameof(workCenter));
29 PlanningHorizon = planningHorizon;
30 }
31
32 [XmlElement("workCenter")]
33 public WorkCenterReference WorkCenter
34 {
35 get => _workCenter;
36 set
37 {
38 ArgumentNullException.ThrowIfNull(value);
39 SetProperty(ref _workCenter, value);
40 }
41 }
42
43 [XmlAttribute("planningHorizon")]
44 public int PlanningHorizon
45 {
46 get => _planningHorizon;
47 set => ResizeTimeSeries(value);
48 }
49
50 [XmlArray("microPeriods")]
51 [XmlArrayItem("microPeriodDecision")]
52 public List<ProductionMicroPeriodDecision> MicroPeriods { get; } = new();
53
54 [XmlIgnore]
56
57 [XmlIgnore]
60 .Select(decision =>
61 (
62 decision.MicroPeriod.MacroPeriod,
63 decision.MicroPeriod.MicroPeriodIndex
64 ))
65 .Distinct()
66 .Count() ==
67 MicroPeriods.Count;
68
69 [XmlIgnore]
70 public bool IsInternallyValid =>
71 WorkCenter.PlantId > 0 &&
72 WorkCenter.WorkCenterId > 0 &&
73 PlanningHorizon > 0 &&
74 MicroPeriods.All(decision =>
75 decision.IsInternallyValid &&
76 decision.MicroPeriod.MacroPeriod <= PlanningHorizon) &&
78
79 public IReadOnlyList<ProductionMicroPeriodDecision>
80 GetMicroPeriods(int macroPeriod)
81 {
82 if (macroPeriod <= 0 || macroPeriod > PlanningHorizon)
83 throw new ArgumentOutOfRangeException(
84 nameof(macroPeriod),
85 macroPeriod,
86 "The macro period is outside the scheduling horizon.");
87
88 return MicroPeriods
89 .Where(decision =>
90 decision.MicroPeriod.MacroPeriod == macroPeriod)
91 .OrderBy(decision =>
92 decision.MicroPeriod.MicroPeriodIndex)
93 .ToArray();
94 }
95
98 {
99 ArgumentNullException.ThrowIfNull(decision);
100
101 if (!decision.IsInternallyValid)
102 throw new ArgumentException(
103 "The micro-period decision is not internally valid.",
104 nameof(decision));
105
106 if (decision.MicroPeriod.MacroPeriod > PlanningHorizon)
107 throw new ArgumentException(
108 "The micro-period macro index exceeds the scheduling horizon.",
109 nameof(decision));
110
111 if (MicroPeriods.Any(existing =>
112 existing.RefersToSameMicroPeriod(decision)))
113 throw new InvalidOperationException(
114 $"A micro-period decision already exists for {decision.MicroPeriod}.");
115
116 MicroPeriods.Add(decision);
117 OnPropertyChanged(nameof(MicroPeriods));
118 OnPropertyChanged(nameof(MicroPeriodDecisionCount));
119 OnPropertyChanged(nameof(HasUniqueMicroPeriodKeys));
120 OnPropertyChanged(nameof(IsInternallyValid));
121 }
122
123 public void ResizeTimeSeries(int periodCount)
124 {
125 if (periodCount < 0)
126 throw new ArgumentOutOfRangeException(
127 nameof(periodCount),
128 periodCount,
129 "The planning horizon cannot be negative.");
130
131 SetProperty(
132 ref _planningHorizon,
133 periodCount,
134 nameof(PlanningHorizon));
135
136 MicroPeriods.RemoveAll(decision =>
137 decision.MicroPeriod.MacroPeriod > periodCount);
138
139 OnPropertyChanged(nameof(MicroPeriods));
140 OnPropertyChanged(nameof(MicroPeriodDecisionCount));
141 OnPropertyChanged(nameof(IsInternallyValid));
142 }
143}
IReadOnlyList< ProductionMicroPeriodDecision > GetMicroPeriods(int macroPeriod)
WorkCenterSchedulingDecision(WorkCenterReference workCenter, int planningHorizon)