Skip to content

Package: Maschine

Maschine

nameinstructionbranchcomplexitylinemethod
Maschine(int, MaschinenTyp)
M: 0 C: 14
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 5
100%
M: 0 C: 1
100%
berechneBenoetigteZeit(Dokumentenklasse)
M: 2 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
berechneBenoetigteZeit(ProduktionsAuftrag)
M: 0 C: 5
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
berechneBenoetigteZeitInklusiveBeilagen(ProduktionsAuftrag, LocalDateTime)
M: 0 C: 12
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
berechneVerfuegbarkeitenProQualifiziertenMitarbeiter(List, LocalDateTime, ComparableQuantity, LocalDateTime)
M: 0 C: 15
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 3
100%
M: 0 C: 1
100%
calculateUmruestungen(ProduktionsAuftrag, LocalDateTime)
M: 0 C: 32
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 8
100%
M: 0 C: 1
100%
equals(Object)
M: 0 C: 32
100%
M: 1 C: 9
90%
M: 1 C: 5
83%
M: 0 C: 6
100%
M: 0 C: 1
100%
erfuellt(ClassObjectMap)
M: 0 C: 20
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 4
100%
M: 0 C: 1
100%
erstelleBelegungsEintrag(LocalDateTime, ComparableQuantity, ProduktionsAuftrag)
M: 0 C: 11
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 3
100%
M: 0 C: 1
100%
findePassendenMitarbeiterZeitraumBeginn(ComparableQuantity, Zeitraum, Map.Entry)
M: 0 C: 13
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 5
100%
M: 0 C: 1
100%
getAmFruehestenVerfuegbarenQualifiziertenMitarbeiter(List, LocalDateTime, ComparableQuantity, LocalDateTime)
M: 0 C: 68
100%
M: 0 C: 4
100%
M: 0 C: 3
100%
M: 0 C: 13
100%
M: 0 C: 1
100%
getAnzahlMoeglicherBeilagen()
M: 0 C: 10
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
getAnzahlVerarbeitbarerBlaetterOderKuverts(Quantity)
M: 0 C: 5
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
getBelegungen()
M: 0 C: 4
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
getDruckEigenschaften()
M: 1 C: 12
92%
M: 1 C: 1
50%
M: 1 C: 1
50%
M: 0 C: 1
100%
M: 0 C: 1
100%
getFaehigkeit()
M: 0 C: 4
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
getKalender()
M: 0 C: 3
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
getLetztenBelegungseintragVorZeitpunkt(LocalDateTime)
M: 0 C: 10
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 2
100%
M: 0 C: 1
100%
getMaschinentyp()
M: 0 C: 3
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
getNummer()
M: 0 C: 3
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
getQualifzierteMitarbeiter(Collection)
M: 0 C: 9
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 3
100%
M: 0 C: 1
100%
hashCode()
M: 0 C: 3
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
lambda$berechneVerfuegbarkeitenProQualifiziertenMitarbeiter$5(Map, LocalDateTime, ComparableQuantity, LocalDateTime, Mitarbeiter)
M: 0 C: 11
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
lambda$calculateUmruestungen$10()
M: 0 C: 16
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 2
100%
M: 0 C: 1
100%
lambda$erfuellt$0()
M: 5 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
lambda$erfuellt$1(ClassObjectMap, MaschinenFaehigkeit)
M: 0 C: 9
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
lambda$erfuellt$2(Boolean, Boolean)
M: 0 C: 11
100%
M: 1 C: 3
75%
M: 1 C: 2
67%
M: 0 C: 1
100%
M: 0 C: 1
100%
lambda$findePassendenMitarbeiterZeitraumBeginn$6(Zeitraum, Zeitraum)
M: 0 C: 4
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
lambda$findePassendenMitarbeiterZeitraumBeginn$7(Optional)
M: 0 C: 5
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
lambda$getAmFruehestenVerfuegbarenQualifiziertenMitarbeiter$3(List, Map.Entry, LocalDateTime)
M: 0 C: 8
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
lambda$getAmFruehestenVerfuegbarenQualifiziertenMitarbeiter$4(List)
M: 0 C: 12
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 2
100%
M: 0 C: 1
100%
lambda$getLetztenBelegungseintragVorZeitpunkt$9(KalenderEintrag)
M: 0 C: 8
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
lambda$getQualifzierteMitarbeiter$8(Mitarbeiter)
M: 0 C: 4
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
removeBelegungsEintrag(MaschinenBelegungEintrag)
M: 0 C: 5
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 2
100%
M: 0 C: 1
100%
toString()
M: 0 C: 18
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%

Coverage

1: package maschine;
2:
3: import auftraege.Dokumentenklasse;
4: import auftraege.ProduktionsAuftrag;
5: import auftraege.auftragsBildungsParameter.BeilagenArten;
6: import auftraege.auftragsBildungsParameter.abstraction.DokumentenklassenVariable;
7: import auftraege.auftragsBildungsParameter.dokumentenKlassenVariablen.ProzessModell;
8: import maschine.faehigkeit.DruckTyp;
9: import maschine.faehigkeit.Drucken;
10: import maschine.faehigkeit.FaehigkeitVisitor;
11: import maschine.faehigkeit.FarbDruckTyp;
12: import maschine.faehigkeit.Kuvertieren;
13: import maschine.faehigkeit.MaschinenFaehigkeit;
14: import maschine.faehigkeit.SimplesDrucken;
15: import maschine.faehigkeit.SimplesKuvertieren;
16: import material.kuvert.KuvertFormat;
17: import mensch.Mitarbeiter;
18: import tec.uom.se.ComparableQuantity;
19: import tec.uom.se.quantity.Quantities;
20: import tec.uom.se.unit.Units;
21: import util.ClassObjectMap;
22: import util.Pair;
23: import util.exceptions.KeineVerfuegbarkeitException;
24: import zeit.Kalender;
25: import zeit.MaschinenKalender;
26: import zeit.TypMitKalender;
27: import zeit.eintraege.KalenderEintrag;
28: import zeit.eintraege.KalenderEintragGenerell;
29: import zeit.eintraege.KalenderEintragVisitor;
30: import zeit.eintraege.MaschinenBelegungEintrag;
31: import zeit.eintraege.MenschBelegungEintrag;
32: import zeit.eintraege.Zeitraum;
33:
34: import javax.measure.Quantity;
35: import javax.measure.quantity.Time;
36: import java.time.LocalDateTime;
37: import java.util.ArrayList;
38: import java.util.Collection;
39: import java.util.Comparator;
40: import java.util.HashSet;
41: import java.util.LinkedHashMap;
42: import java.util.List;
43: import java.util.Map;
44: import java.util.NoSuchElementException;
45: import java.util.Objects;
46: import java.util.Optional;
47: import java.util.Set;
48: import java.util.stream.Collectors;
49:
50: /**
51: * Klasse zur Repräsentation von Maschinen in der Produktion.
52: */
53: public class Maschine implements TypMitKalender {
54:
55:         private final MaschinenKalender kalender = new MaschinenKalender();
56:         private final MaschinenTyp maschinentyp;
57:         private final int nummer;
58:
59:         /**
60:          * Konstruktor für die Klasse Maschine.
61:          *
62:          * @param nummer
63:          *                 Nummer zur eindeutigen Identifikation.
64:          * @param maschinentyp
65:          *                 {@link MaschinenTyp}.
66:          */
67:         public Maschine(final int nummer, final MaschinenTyp maschinentyp) {
68:                 this.nummer = nummer;
69:                 this.maschinentyp = maschinentyp;
70:         }
71:
72:         /**
73:          * @return den {@link MaschinenTyp}.
74:          */
75:         public MaschinenTyp getMaschinentyp() {
76:                 return this.maschinentyp;
77:         }
78:
79:         /**
80:          * Getter.
81:          *
82:          * @return Die Nummer der Maschine
83:          */
84:
85:         public int getNummer() {
86:                 return this.nummer;
87:         }
88:
89:         /**
90:          * @param zeitraum
91:          *                 Zeitraum, welcher überprüft werden muss.
92:          *
93:          * @return anzahl der A4-Blätter, welche im spezifizierten Zeitraum verarbeitet werden kann.
94:          */
95:         public int getAnzahlVerarbeitbarerBlaetterOderKuverts(final Quantity<Time> zeitraum) {
96:                 return this.maschinentyp.getAnzahlVerarbeitbarerBlaetterOderKuverts(zeitraum);
97:         }
98:
99:         /**
100:          * @param variablen
101:          *                 {@link DokumentenklassenVariable Dokumentenklassenvariablen}
102:          *
103:          * @return true, wenn der Maschinentyp der Maschine alle geforderten Variablen erfüllt.
104:          */
105:         public boolean erfuellt(final ClassObjectMap<DokumentenklassenVariable> variablen) {
106:                 final ProzessModell prozessModell = variablen.get(ProzessModell.class)
107:                                 .orElseThrow(() -> new NoSuchElementException("Das Prozessmodell muss enthalten sein!"));
108:
109:                 return prozessModell.getFaehigkeiten().stream().map(e -> e.accept(new FaehigkeitVisitor<Boolean>() {
110:                         private final MaschinenFaehigkeit maschinenFaehigkeit = Maschine.this.maschinentyp.getMaschinenFaehigkeit();
111:
112:                         @Override
113:                         public Boolean handle(final Drucken drucken) {
114:                                 // an der Dokumentenklasse sollte kein "komplexes Drucken" enthalten sein!
115:                                 return false;
116:                         }
117:
118:                         @Override
119:                         public Boolean handle(final Kuvertieren kuvertieren) {
120:                                 // an der Dokumentenklasse sollte kein "komplexes Kuvertieren" enthalten sein!
121:                                 return false;
122:                         }
123:
124:                         @Override
125:                         public Boolean handle(final SimplesDrucken simplesDrucken) {
126:                                 // Es muss mindestens eine MaschinenFaehigkeit der Maschine geben, welche die Anforderungen resultierend aus den
127:                                 // Dokumentenklassenvariablen erfüllen kann
128:                                 return this.maschinenFaehigkeit.erfuelltDruckTyp(variablen.get(DruckTyp.class)
129:                                                 .orElseThrow(() -> new NoSuchElementException("Dokumentenklassenvariablen müssen einen Drucktypen enthalten!")))
130:                                                 && this.maschinenFaehigkeit.erfuelltFarbDruckTyp(variablen.get(FarbDruckTyp.class)
131:                                                 .orElseThrow(() -> new NoSuchElementException("Dokumentenklassenvariablen müssen einen FarbDrucktypen enthalten!")));
132:                         }
133:
134:                         @Override
135:                         public Boolean handle(final SimplesKuvertieren simplesKuvertieren) {
136:                                 // Es muss mindestens eine MaschinenFaehigkeit der Maschine geben, welche die Anforderungen resultierend aus den
137:                                 // Dokumentenklassenvariablen erfüllen kann
138:                                 return this.maschinenFaehigkeit.erfuelltKuvertFormat(variablen.get(KuvertFormat.class).orElseThrow(() ->
139:                                                 new NoSuchElementException("Dokumentenklassenvariablen müssen ein KuvertFormat enthalten!")));
140:                         }
141:                         // Alle Faehigkeiten des Prozessmodells müssen nach diesem Schritt true sein, damit die Anforderungen als
142:                         // erfüllt gelten.
143:•                })).reduce(Boolean.TRUE, (e1, e2) -> e1 && e2);
144:         }
145:
146:         @Override
147:         public boolean equals(final Object o) {
148:•                if (this == o) {
149:                         return true;
150:                 }
151:•                if (o == null || this.getClass() != o.getClass()) {
152:                         return false;
153:                 }
154:                 final Maschine maschine = (Maschine) o;
155:•                return this.nummer == maschine.nummer && Objects.equals(this.maschinentyp, maschine.maschinentyp);
156:         }
157:
158:         @Override
159:         public int hashCode() {
160:                 return this.nummer;
161:         }
162:
163:         @Override
164:         public Kalender getKalender() {
165:                 return this.kalender;
166:         }
167:
168:         @Override
169:         public String toString() {
170:                 return "Maschine{" + "maschinentyp=" + this.maschinentyp.getName() + ", nummer=" + this.nummer + '}';
171:         }
172:
173:         /**
174:          * @param start
175:          *                 Startzeitpunkt des Belegungseintrags
176:          * @param dauer
177:          *                 Dauer des Belegungseintrags
178:          * @param zuVerarbeitenderAuftrag
179:          *                 Der zu verarbeitende Produktionsauftrag während der Belegung
180:          *
181:          * @return Den erstellten Belegungseintrag.
182:          */
183:         public MaschinenBelegungEintrag erstelleBelegungsEintrag(final LocalDateTime start,
184:          final ComparableQuantity<Time> dauer,
185:          final ProduktionsAuftrag zuVerarbeitenderAuftrag) {
186:                 final MaschinenBelegungEintrag eintrag = MaschinenBelegungEintrag.create(start, dauer, zuVerarbeitenderAuftrag);
187:                 this.getKalender().addEintrag(eintrag);
188:                 return eintrag;
189:         }
190:
191:         /**
192:          * @param eintrag
193:          *                 Eintrag, welcher aus dem Kalender der Maschine entfernt werden soll.
194:          */
195:         public void removeBelegungsEintrag(final MaschinenBelegungEintrag eintrag) {
196:                 this.getKalender().removeEintrag(eintrag);
197:         }
198:
199:         /**
200:          * @return alle Belegungen der Maschine. Diese werden aus dem Kalender ermittelt.
201:          */
202:         public Set<MaschinenBelegungEintrag> getBelegungen() {
203:                 return this.kalender.getBelegungen();
204:         }
205:
206:         /**
207:          * Liefert die Druckfähigkeiten der Maschine. An diesem Objekt kann erkannt werden, ob die Maschine SchwarzWeiß, FarbDruck, Simplex, Duplex, etc. beherrscht.
208:          *
209:          * @return Optional, welches ein {@link Drucken} beinhaltet (sofern vorhanden).
210:          */
211:         public Optional<Drucken> getDruckEigenschaften() {
212:•                return this.maschinentyp.getMaschinenFaehigkeit() instanceof Drucken ? Optional.of((Drucken) this.maschinentyp.getMaschinenFaehigkeit()) : Optional.empty();
213:         }
214:
215:         /**
216:          * Findet aus der übergebenen Liste von {@link Mitarbeiter}n denjenigen welcher am frühesten gemeinsam mit der {@link Maschine} für die übergebene benötigte Zeit
217:          * verfügbar ist.
218:          *
219:          * @param mitarbeiter
220:          *                 {@link List} von {@link Mitarbeiter}n, die durchsucht wird
221:          * @param abZeitpunkt
222:          *                 Zeitpunkt ab dem gesucht wird
223:          * @param benoetigteZeit
224:          *                 Zeitraum der benötigt wird
225:          * @param slaFrist
226:          *                 Zeitpunkt bis zu dem ein Zeitraum gemeinsamer Verfügbarkeit gefunden werden muss.
227:          *
228:          * @return am fruehsten gemeinsam mit der {@link Maschine} verfügbarer {@link Mitarbeiter} + Zeitpunkt der frühsten gemeinsamen Verfügbarkeit.
229:          * @throws KeineVerfuegbarkeitException
230:          *                 wird geworfen, wenn kein angemessener Zeitpunkt gefunden werden kann.
231:          */
232:         public Pair<Mitarbeiter, LocalDateTime> getAmFruehestenVerfuegbarenQualifiziertenMitarbeiter(
233:                         final List<Mitarbeiter> mitarbeiter,
234:                         final LocalDateTime abZeitpunkt,
235:                         final ComparableQuantity<Time> benoetigteZeit,
236:                         final LocalDateTime slaFrist) throws KeineVerfuegbarkeitException {
237:
238:                 final List<Zeitraum> verfuegbarkeitenDerMaschineSortiertNachBeginn = this.getVerfuegbarkeiten(abZeitpunkt, benoetigteZeit, slaFrist)
239:                                 .stream()
240:                                 .sorted(Comparator.comparing(Zeitraum::getVon))
241:                                 .collect(Collectors.toList());
242:
243:                 final Map<Mitarbeiter, Collection<Zeitraum>> verfuegbarkeitenProMitarbeiter = this.berechneVerfuegbarkeitenProQualifiziertenMitarbeiter(mitarbeiter,
244:                                 abZeitpunkt,
245:                                 benoetigteZeit,
246:                                 slaFrist);
247:
248:                 final List<Pair<Mitarbeiter, LocalDateTime>> ret = new ArrayList<>();
249:•                for (final Zeitraum verfuegbarkeitDerMaschine : verfuegbarkeitenDerMaschineSortiertNachBeginn) {
250:•                        for (final Map.Entry<Mitarbeiter, Collection<Zeitraum>> zeitraumProMitarbeiter : verfuegbarkeitenProMitarbeiter.entrySet()) {
251:                                 final Optional<LocalDateTime> potentiellerBeginnEinesZeitraums = this.findePassendenMitarbeiterZeitraumBeginn(benoetigteZeit,
252:                                                 verfuegbarkeitDerMaschine,
253:                                                 zeitraumProMitarbeiter);
254:                                 potentiellerBeginnEinesZeitraums.ifPresent(localDateTime -> ret.add(Pair.create(zeitraumProMitarbeiter.getKey(), localDateTime)));
255:                         }
256:                 }
257:                 
258:                 return ret.stream().min(Comparator.comparing(Pair::getSecond)).orElseThrow(() -> new KeineVerfuegbarkeitException(
259:                                 String.format("Es wurde kein Mitarbeiter gefunden, welcher in einem der foldenden Maschinenzeitslots %s verfügbar war.",
260:                                                 verfuegbarkeitenDerMaschineSortiertNachBeginn)));
261:         }
262:
263:         private Map<Mitarbeiter, Collection<Zeitraum>> berechneVerfuegbarkeitenProQualifiziertenMitarbeiter(final List<Mitarbeiter> mitarbeiter,
264:          final LocalDateTime abZeitpunkt,
265:          final ComparableQuantity<Time> benoetigteZeit,
266:          final LocalDateTime slaFrist) {
267:
268:                 final Map<Mitarbeiter, Collection<Zeitraum>> verfuegbarkeitenProMitarbeiter = new LinkedHashMap<>();
269:
270:                 this.getQualifzierteMitarbeiter(mitarbeiter).forEach(einMitarbeiter ->
271:                                 verfuegbarkeitenProMitarbeiter.put(einMitarbeiter, einMitarbeiter.getVerfuegbarkeiten(abZeitpunkt, benoetigteZeit, slaFrist)));
272:
273:                 return verfuegbarkeitenProMitarbeiter;
274:         }
275:
276:         /**
277:          * @param benoetigteZeit
278:          *                 Zeitraum der benötigt wird
279:          * @param verfuegbarkeitDerMaschine
280:          *                 Zeitraum, in welcher die Maschine verfügbar ist.
281:          * @param zeitraeumeProMitarbeiter
282:          *                 Zeiträume in denen der Mitarbeiter verfügbar ist.
283:          *
284:          * @return den Beginn eines Zeitraums, in dem sowohl die Maschine als auch der Mitarbeiter verfügbar ist. Darüberhinaus muss dieser Zeitraum mindest die
285:          *                 benoetigteZeit als Länge haben.
286:          */
287:         private Optional<LocalDateTime> findePassendenMitarbeiterZeitraumBeginn(final ComparableQuantity<Time> benoetigteZeit,
288:          final Zeitraum verfuegbarkeitDerMaschine,
289:          final Map.Entry<Mitarbeiter, Collection<Zeitraum>> zeitraeumeProMitarbeiter) {
290:
291:                 return zeitraeumeProMitarbeiter.getValue().stream()
292:                                 .map(zeitraum -> zeitraum.berechneUeberschneidung(verfuegbarkeitDerMaschine))
293:                                 .filter(Optional::isPresent)
294:                                 .map(zeitraum -> zeitraum.get().getVon())
295:                                 .findFirst();
296:
297:         }
298:
299:         /**
300:          * @param mitarbeiter
301:          *                 Liste von Mitarbeitern
302:          *
303:          * @return die Mitarbeiter aus der Liste der Mitarbeiter, welche qualifziert sind die Maschine this zu bedienen.
304:          */
305:         private List<Mitarbeiter> getQualifzierteMitarbeiter(final Collection<Mitarbeiter> mitarbeiter) {
306:                 return mitarbeiter.stream()
307:                                 .filter(einMitarbeiter -> einMitarbeiter.kannMaschineBedienen(this))
308:                                 .collect(Collectors.toList());
309:         }
310:
311:         /**
312:          * @return die Fähigkeiten des Maschinentypen.
313:          */
314:         public MaschinenFaehigkeit getFaehigkeit() {
315:                 return this.maschinentyp.getMaschinenFaehigkeit();
316:         }
317:
318:         /**
319:          * Berechnet die nötige Zeit, die die {@link Dokumentenklasse} zur abarbeitung an einer Maschine benötigt.
320:          *
321:          * @param dokumentenklasse
322:          *                 {@link Dokumentenklasse}, welche an dieser Maschine bearbeitet werden soll.
323:          *
324:          * @return Dauer, die diese Maschine für diese Dokumentenklasse insgesamt braucht.
325:          */
326:         public ComparableQuantity<Time> berechneBenoetigteZeit(final Dokumentenklasse dokumentenklasse) {
327:                 return null;
328:         }
329:
330:         /**
331:          * Berechnet die nötige Zeit, die der Produktionsauftrag zur abarbeitung an einer Maschine benötigt.
332:          *
333:          * @param auftrag
334:          *                 {@link ProduktionsAuftrag}, welcher an dieser Maschine bearbeitet werden soll.
335:          *
336:          * @return Dauer, die diese Maschine für diesen Auftrag insgesamt braucht.
337:          */
338:         public ComparableQuantity<Time> berechneBenoetigteZeit(final ProduktionsAuftrag auftrag) {
339:                 return this.maschinentyp.berechneBenoetigteZeitOhneBeilagenruestZeit(auftrag);
340:         }
341:
342:         /**
343:          * Berechnet die nötige Zeit, die der Produktionsauftrag zur abarbeitung an einer Maschine benötigt.
344:          *
345:          * @param auftrag
346:          *                 {@link ProduktionsAuftrag}, welcher an dieser Maschine bearbeitet werden soll.
347:          * @param arbeitsbeginn
348:          *                 Zeitpunkt zu welchem die an der Maschine verfügbare Beilagenkonfiguration geprüft werden soll.
349:          *
350:          * @return Dauer, die diese Maschine für diesen Auftrag insgesamt braucht.
351:          */
352:         public ComparableQuantity<Time> berechneBenoetigteZeitInklusiveBeilagen(final ProduktionsAuftrag auftrag, final LocalDateTime arbeitsbeginn) {
353:                 return this.maschinentyp.getMaschinenFaehigkeit().accept(new FaehigkeitVisitor<ComparableQuantity<Time>>() {
354:                         @Override
355:                         public ComparableQuantity<Time> handle(final Drucken drucken) {
356:                                 return Maschine.this.berechneBenoetigteZeit(auftrag);
357:                         }
358:
359:                         @Override
360:                         public ComparableQuantity<Time> handle(final Kuvertieren kuvertieren) {
361:
362:                                 final BegrenzteBeilagenArten begrenzteBeilagenArten = Maschine.this.getLetztenBelegungseintragVorZeitpunkt(arbeitsbeginn)
363:                                                 .map(MaschinenBelegungEintrag::getBeilagenKonfiguration)
364:                                                 .orElseGet(() -> new BegrenzteBeilagenArten(new HashSet<>(), kuvertieren.getAnzahlMoeglicherBeilagen()));
365:
366:                                 final int noetigeUmruestungen = begrenzteBeilagenArten.calculateUmruestvorgaengeZuNeuerBeilagenArt(auftrag.getBeilagenArten());
367:                                 final ComparableQuantity<Time> toBeAdded = Maschine.this.getMaschinentyp().getBeilagenRuestzeit().multiply(noetigeUmruestungen);
368:
369:                                 return Maschine.this.berechneBenoetigteZeit(auftrag).add(toBeAdded);
370:                         }
371:
372:                         @Override
373:                         public ComparableQuantity<Time> handle(final SimplesDrucken simplesDrucken) {
374:                                 // sollte - wie immer - nicht an der Maschine stehen..
375:                                 return null;
376:                         }
377:
378:                         @Override
379:                         public ComparableQuantity<Time> handle(final SimplesKuvertieren simplesKuvertieren) {
380:                                 // sollte - wie immer - nicht an der Maschine stehen..
381:                                 return null;
382:                         }
383:                 });
384:         }
385:
386:         /**
387:          * @return maximale Anzahl der verschiedenen Beilagen, welche eine Maschine haben kann.
388:          */
389:         public Optional<Integer> getAnzahlMoeglicherBeilagen() {
390:                 return this.getMaschinentyp().getMaschinenFaehigkeit().accept(new FaehigkeitVisitor<Optional<Integer>>() {
391:                         @Override
392:                         public Optional<Integer> handle(final Drucken drucken) {
393:                                 return Optional.empty();
394:                         }
395:
396:                         @Override
397:                         public Optional<Integer> handle(final Kuvertieren kuvertieren) {
398:                                 return Optional.of(kuvertieren.getAnzahlMoeglicherBeilagen());
399:                         }
400:
401:                         @Override
402:                         public Optional<Integer> handle(final SimplesDrucken simplesDrucken) {
403:                                 return Optional.empty();
404:                         }
405:
406:                         @Override
407:                         public Optional<Integer> handle(final SimplesKuvertieren simplesKuvertieren) {
408:                                 return Optional.empty();
409:                         }
410:                 });
411:         }
412:
413:         /**
414:          * @param zeitpunkt
415:          *                 Zeitpunkt, vor welchem der späteste Eintrag geliefert wird.
416:          *
417:          * @return Spätester Eintrag vor dem Zeitpunkt.
418:          */
419:         public Optional<MaschinenBelegungEintrag> getLetztenBelegungseintragVorZeitpunkt(final LocalDateTime zeitpunkt) {
420:                 final Optional<KalenderEintrag> letztenEintragVorZeitpunkt = this.kalender.getLetztenEintragVorZeitpunkt(zeitpunkt);
421:                 return letztenEintragVorZeitpunkt.flatMap(eintrag -> eintrag.accept(new KalenderEintragVisitor<Optional<MaschinenBelegungEintrag>>() {
422:                         @Override
423:                         public Optional<MaschinenBelegungEintrag> handle(final MaschinenBelegungEintrag maschinenBelegungEintrag) {
424:                                 return Optional.of(maschinenBelegungEintrag);
425:                         }
426:
427:                         @Override
428:                         public Optional<MaschinenBelegungEintrag> handle(final MenschBelegungEintrag menschBelegungEintrag) {
429:                                 return Optional.empty();
430:                         }
431:
432:                         @Override
433:                         public Optional<MaschinenBelegungEintrag> handle(final KalenderEintragGenerell kalenderEintragGenerell) {
434:                                 return Optional.empty();
435:                         }
436:                 }));
437:         }
438:
439:         /**
440:          * Berechnet die Umrüstungsdauer, welche die Maschine zu einem bestimmten Zeitpunkt für einen neuen Produktionsauftrag benötigt.
441:          *
442:          * @param auftrag
443:          *                 Relevanter Auftrag, zu welchem die Maschine geprüft werden soll.
444:          * @param value
445:          *                 Zeit, zu welcher geprüft werden soll, wann der neue Auftrag bearbeitet werden soll.
446:          *
447:          * @return Dauer der Beilagenrüstzeit.
448:          */
449:         public ComparableQuantity<Time> calculateUmruestungen(final ProduktionsAuftrag auftrag, final LocalDateTime value) {
450:                 final BegrenzteBeilagenArten begrenzteBeilagenArten = this.getLetztenBelegungseintragVorZeitpunkt(value)
451:                                 .map(MaschinenBelegungEintrag::getBeilagenKonfiguration)
452:                                 .orElseGet(() -> new BegrenzteBeilagenArten(new HashSet<>(),
453:                                                 this.getFaehigkeit().accept(new FaehigkeitVisitor<Integer>() {
454:                                                         @Override
455:                                                         public Integer handle(final Drucken drucken) {
456:                                                                 return 0;
457:                                                         }
458:
459:                                                         @Override
460:                                                         public Integer handle(final Kuvertieren kuvertieren) {
461:                                                                 return kuvertieren.getAnzahlMoeglicherBeilagen();
462:                                                         }
463:
464:                                                         @Override
465:                                                         public Integer handle(final SimplesDrucken simplesDrucken) {
466:                                                                 return null;
467:                                                         }
468:
469:                                                         @Override
470:                                                         public Integer handle(final SimplesKuvertieren simplesKuvertieren) {
471:                                                                 return null;
472:                                                         }
473:                                                 })));
474:                 //ist die Begrenzung 0, so handelt es sich um ein Drucken-Objekt, bei welchem die Zahl der Umrüstungen nicht betrachtet werden müssen.
475:•                if (begrenzteBeilagenArten.getBegrenzung() == 0) {
476:                         return Quantities.getQuantity(0, Units.SECOND);
477:                 }
478:                 final BeilagenArten beilagenArten = auftrag.getBeilagenArten();
479:
480:                 final int umruestungen = begrenzteBeilagenArten.calculateUmruestvorgaengeZuNeuerBeilagenArt(beilagenArten);
481:                 return this.getMaschinentyp().getBeilagenRuestzeit().multiply(umruestungen);
482:         }
483:
484: }