Skip to contentMethod: simuliereAuslastungProMitarbeiter(ErmittelteBelegungen)
      1: package simulation.SimulationsHelper;
2: 
3: import maschine.Maschine;
4: import mensch.Mitarbeiter;
5: import rollenbelegung.ErmittelteBelegungen;
6: import rollenbelegung.MaschinenBelegung;
7: import rollenbelegung.MitarbeiterBelegung;
8: import simulation.exceptions.SimulationsException;
9: import tec.uom.se.ComparableQuantity;
10: import tec.uom.se.quantity.Quantities;
11: import zeit.TypMitKalender;
12: import zeit.eintraege.BelegungsEintrag;
13: 
14: import javax.measure.Unit;
15: import javax.measure.quantity.Time;
16: import java.time.LocalDateTime;
17: import java.time.temporal.ChronoUnit;
18: import java.util.AbstractMap;
19: import java.util.Collection;
20: import java.util.Map;
21: import java.util.stream.Collectors;
22: 
23: /**
24:  * Helperklasse, um die Auslastung von Mitarbeitern und Maschinen auszurechnen.
25:  */
26: public final class AuslastungsHelper {
27: 
28:     private final ChronoUnit javaZeitEinheit;
29:     private final Unit<Time> zeitEinheit;
30: 
31:     private AuslastungsHelper(final ChronoUnit berechnungsZeitEinheit) {
32:         this.javaZeitEinheit = berechnungsZeitEinheit;
33:         this.zeitEinheit = SimulationsKonstanten.getZeitEinheit(berechnungsZeitEinheit);
34:     }
35: 
36:     /**
37:      *
38:      * @param berechnungsZeitEinheit Zeiteinheit, welche als Basis der Berechnung genutzt werden soll
39:      * @return den erstellten Helper
40:      */
41:     public static AuslastungsHelper create(final ChronoUnit berechnungsZeitEinheit) {
42:         return new AuslastungsHelper(berechnungsZeitEinheit);
43:     }
44: 
45: 
46:     /**
47:      * @return den erstellten Helper
48:      */
49:     public static AuslastungsHelper create() {
50:         return new AuslastungsHelper(SimulationsKonstanten.DEFAULT_JAVA_ZEIT_EINHEIT);
51:     }
52: 
53:     /**
54:      *
55:      * @param ermittelteBelegungen Belegungen der Maschinen und Mitarbeiter
56:      * @return Auslastung pro Maschine als Fraction.
57:      */
58:     public Map<Maschine, Auslastung> simuliereAuslastungProMaschine(final ErmittelteBelegungen ermittelteBelegungen) {
59:         final LocalDateTime firstWorkDay = this.ermittleErstenTagImPlanungsZeitraum(ermittelteBelegungen);
60:         final LocalDateTime lastWorkDay = this.ermittleLetztenTagImPlanungsZeitraum(ermittelteBelegungen);
61: 
62:         return ermittelteBelegungen.getMaschinenbelegungen()
63:                 .entrySet()
64:                 .stream()
65:                 .map(belegungenProMaschine ->
66:                         this.berechneAuslastungProMaschine(belegungenProMaschine, firstWorkDay, lastWorkDay))
67:                 .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
68:     }
69: 
70:     /**
71:      *
72:      * @param ermittelteBelegungen Belegungen der Maschinen und Mitarbeiter
73:      * @return Auslastung pro Mitarbeiter als Fraction.
74:      */
75:     public Map<Mitarbeiter, Auslastung> simuliereAuslastungProMitarbeiter(final ErmittelteBelegungen ermittelteBelegungen) {
76:         final LocalDateTime firstWorkDay = this.ermittleErstenTagImPlanungsZeitraum(ermittelteBelegungen);
77:         final LocalDateTime lastWorkDay = this.ermittleLetztenTagImPlanungsZeitraum(ermittelteBelegungen);
78: 
79:         return ermittelteBelegungen.getMitarbeiterbelegungen()
80:                 .entrySet()
81:                 .stream()
82:                 .map(belegungenProMitarbeiter -> this.berechneAuslastungProMitarbeiter(belegungenProMitarbeiter, firstWorkDay, lastWorkDay))
83:                 .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
84:     }
85: 
86:     private Map.Entry<Mitarbeiter, Auslastung> berechneAuslastungProMitarbeiter(
87:             final Map.Entry<Mitarbeiter, MitarbeiterBelegung> belegungenProMitarbeiter,
88:             final LocalDateTime firstWorkDay, final LocalDateTime lastWorkDay) {
89: 
90:         final ComparableQuantity<Time> geleistetetArbeitszeitDesMitarbeiters = this.berechneDauerDerBelegungen(belegungenProMitarbeiter.getValue().getBelegung());
91:         final ComparableQuantity<Time> verfuegbareArbeitszeitDesMitarbeiters = this.berechneArbeitszeit(belegungenProMitarbeiter.getKey(), firstWorkDay, lastWorkDay);
92: 
93: 
94:         return new AbstractMap.SimpleEntry<>(belegungenProMitarbeiter.getKey(),
95:                 Auslastung.create(geleistetetArbeitszeitDesMitarbeiters, verfuegbareArbeitszeitDesMitarbeiters));
96:     }
97: 
98: 
99: 
100:     private Map.Entry<Maschine, Auslastung> berechneAuslastungProMaschine(final Map.Entry<Maschine, MaschinenBelegung> belegungenProMaschine,
101:                                                                 final LocalDateTime firstWorkDay, final LocalDateTime lastWorkDay) {
102: 
103:         final ComparableQuantity<Time> geleisteteZeitDerMaschineInStunden = this.berechneDauerDerBelegungen(belegungenProMaschine.getValue().getBelegung());
104:         final ComparableQuantity<Time> maximalVerfuegbareStunden = this.berechneArbeitszeit(belegungenProMaschine.getKey(), firstWorkDay, lastWorkDay);
105: 
106:         return new AbstractMap.SimpleEntry<>(belegungenProMaschine.getKey(),
107:                 Auslastung.create(geleisteteZeitDerMaschineInStunden, maximalVerfuegbareStunden));
108:     }
109: 
110:     private ComparableQuantity<Time> berechneDauerDerBelegungen(final Collection<? extends BelegungsEintrag> belegungsEintraege) {
111:         return belegungsEintraege.stream()
112:                 .map(BelegungsEintrag::getDauer)
113:                 .reduce(SimulationsKonstanten.NEUTRALE_ZEIT, ComparableQuantity::add);
114:     }
115: 
116:     private ComparableQuantity<Time> berechneArbeitszeit(final TypMitKalender typMitKalender, final LocalDateTime firstWorkDay, final LocalDateTime lastWorkDay) {
117:         long sum = 0;
118:         LocalDateTime workDay = firstWorkDay;
119:         while (!workDay.isAfter(lastWorkDay)) {
120:             sum += typMitKalender.getArbeitszeit(workDay.toLocalDate(), this.getJavaZeitEinheit());
121:             workDay = workDay.plusDays(1);
122:         }
123:         return Quantities.getQuantity(sum, this.getZeitEinheit());
124:     }
125: 
126: 
127:     private LocalDateTime ermittleErstenTagImPlanungsZeitraum(final ErmittelteBelegungen ermittelteBelegungen) {
128:         return ermittelteBelegungen.getMitarbeiterbelegungen()
129:                 .values()
130:                 .stream()
131:                 .flatMap(mitarbeiterBelegung -> mitarbeiterBelegung.getBelegung()
132:                         .stream())
133:                 .map(BelegungsEintrag::getVon)
134:                 .min(LocalDateTime::compareTo)
135:                 .orElseThrow(() -> new SimulationsException(SimulationsKonstanten.SIMULATION_NICHT_MOEGLICH));
136:     }
137: 
138:     private LocalDateTime ermittleLetztenTagImPlanungsZeitraum(final ErmittelteBelegungen ermittelteBelegungen) {
139:         return ermittelteBelegungen.getMitarbeiterbelegungen()
140:                 .values()
141:                 .stream()
142:                 .flatMap(mitarbeiterBelegung -> mitarbeiterBelegung.getBelegung()
143:                         .stream())
144:                 .map(BelegungsEintrag::getBis)
145:                 .max(LocalDateTime::compareTo)
146:                 .orElseThrow(() -> new SimulationsException(SimulationsKonstanten.SIMULATION_NICHT_MOEGLICH));
147:     }
148: 
149: 
150:     private ChronoUnit getJavaZeitEinheit() {
151:         return this.javaZeitEinheit;
152:     }
153: 
154:     private Unit<Time> getZeitEinheit() {
155:         return this.zeitEinheit;
156:     }
157: }