Skip to content

Package: ProduktionsAuftragServiceImpl$2

ProduktionsAuftragServiceImpl$2

nameinstructionbranchcomplexitylinemethod
handle(FarbDruckTypMischbar)
M: 0 C: 19
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 2
100%
M: 0 C: 1
100%
handle(SimplexDuplexMischbar)
M: 0 C: 19
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 2
100%
M: 0 C: 1
100%
{...}
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%

Coverage

1: package produktionsauftrag;
2:
3: import auftraege.Dokumentenklasse;
4: import auftraege.ProduktionsAuftrag;
5: import auftraege.UnpassendeKlasseException;
6: import auftraege.auftragsBildungsParameter.BeilagenArten;
7: import auftraege.auftragsBildungsParameter.BlattAnzahlSpanne;
8: import auftraege.auftragsBildungsParameter.FarbDruckTypMischbar;
9: import auftraege.auftragsBildungsParameter.Kunden;
10: import auftraege.auftragsBildungsParameter.KuvertFormate;
11: import auftraege.auftragsBildungsParameter.MaxBeilagenarten;
12: import auftraege.auftragsBildungsParameter.MaxKundenauftraege;
13: import auftraege.auftragsBildungsParameter.PapierFormate;
14: import auftraege.auftragsBildungsParameter.Rollenkapazitaet;
15: import auftraege.auftragsBildungsParameter.SimplexDuplexMischbar;
16: import auftraege.auftragsBildungsParameter.abstraction.AusschliessenderParameter;
17: import auftraege.auftragsBildungsParameter.abstraction.AusschliessenderParameterVisitor;
18: import auftraege.auftragsBildungsParameter.abstraction.LimitierenderParameter;
19: import auftraege.auftragsBildungsParameter.abstraction.LimitierenderParameterVisitor;
20: import auftraege.auftragsBildungsParameter.abstraction.ProduktionsauftragsParameter;
21: import auftraege.auftragsBildungsParameter.abstraction.StrategieParameter;
22: import auftraege.auftragsBildungsParameter.abstraction.StrategieParameterVisitor;
23: import auftraege.auftragsBildungsParameter.dokumentenKlassenVariablen.BlattAnzahl;
24: import auftraege.auftragsBildungsParameter.dokumentenKlassenVariablen.ProzessModell;
25: import auftraege.versand.Kunde;
26: import maschine.faehigkeit.DruckTyp;
27: import maschine.faehigkeit.FarbDruckTyp;
28: import material.auspraegungen.Papierformat;
29: import material.kuvert.KuvertFormat;
30: import util.ClassObjectMap;
31: import util.Pair;
32: import util.exceptions.AlreadyExistsException;
33: import zeit.eintraege.Zeitraum;
34:
35: import java.time.LocalDateTime;
36: import java.util.ArrayList;
37: import java.util.Collection;
38: import java.util.Comparator;
39: import java.util.List;
40: import java.util.Map;
41: import java.util.Set;
42: import java.util.stream.Collectors;
43: import java.util.stream.Stream;
44:
45: /**
46: * Dieser Service stellt die Grundlegende Funktionalität zur Verfügung, um Produktionsaufträge anhand unterschiedlicher Kriterien bilden zu können.
47: */
48: public class ProduktionsAuftragServiceImpl implements ProduktionsAuftragsService {
49:
50:         private ClassObjectMap<ProduktionsauftragsParameter> parameterMap;
51:
52:         @Override
53:         public Pair<Collection<Dokumentenklasse>, List<ProduktionsAuftrag>> erstelleProduktionsauftraege(
54:                         final Set<ProduktionsauftragsParameter> parameter, final Collection<Dokumentenklasse> dokumentenKlassen) {
55:                 this.organizeParameters(parameter);
56:
57:                 final Map<Boolean, List<Dokumentenklasse>> partitionierteDokumentenklassen = this.filterKlassenByParameter(dokumentenKlassen);
58:                 final List<DokumentenklasseBuilder> abzuarbeitendeDokumentenklassenbuilder =
59:                                 partitionierteDokumentenklassen.get(true).stream()
60:                                                 .map(DokumentenklasseBuilder::new)
61:                                                 .collect(Collectors.toList());
62:                 final List<DokumentenklasseBuilder> nichtAbzuarbeitendeDokumentenklassenbuilder =
63:                                 partitionierteDokumentenklassen.get(false).stream()
64:                                                 .map(DokumentenklasseBuilder::new)
65:                                                 .collect(Collectors.toList());
66:
67:                 // Liefern des Ergebnisses.
68:                 final List<ProduktionsauftragsBuilder> erstelleProduktionsauftraegeIntern =
69:                                 this.erstelleProduktionsauftraegeIntern(abzuarbeitendeDokumentenklassenbuilder);
70:
71:                 final List<Dokumentenklasse> nichtVerarbeiteteDokumentenklassen = Stream
72:                                 .concat(
73:                                                 abzuarbeitendeDokumentenklassenbuilder.stream().filter(bauer -> bauer.getRestlicheBlaetter() > 0),
74:                                                 nichtAbzuarbeitendeDokumentenklassenbuilder.stream()
75:                                 )
76:                                 .map(DokumentenklasseBuilder::baueRest).collect(Collectors.toList());
77:
78:                 final List<ProduktionsAuftrag> erstellteProduktionsauftraege = erstelleProduktionsauftraegeIntern.stream()
79:                                 .map(ProduktionsauftragsBuilder::baue)
80:                                 .collect(Collectors.toList());
81:                 return Pair.create(nichtVerarbeiteteDokumentenklassen, erstellteProduktionsauftraege);
82:         }
83:
84:         /**
85:          * Filtert und Gruppiert die Dokumentenklassen mit den Parametern des ProduktionsAuftragService.
86:          *
87:          * @param dokumentenKlassen nach ihren Parametern zu filternde Dokumentenklassen.
88:          * @return Einträge der Map mit dem key <i>true</i> sind abzuarbeitende Dokumentenklassen; Einträge unter dem Key <i>false</i> sind nicht abzuarbeitende
89:          * Dokumentenklassen.
90:          */
91:         private Map<Boolean, List<Dokumentenklasse>> filterKlassenByParameter(final Collection<Dokumentenklasse> dokumentenKlassen) {
92:                 return dokumentenKlassen.stream()
93:                                 .collect(Collectors.partitioningBy(dokumentenklasse -> Stream.concat(
94:                                                 this.parameterMap.getBySuperclass(AusschliessenderParameter.class).stream()
95:                                                                 .map(ausschliessenderParameter -> ausschliessenderParameter
96:                                                                                 .accept(new BooleanAusschliessenderParameterVisitor(dokumentenklasse))),
97:                                                 this.parameterMap.getBySuperclass(LimitierenderParameter.class).stream()
98:                                                                 // Hier sollen alle möglichkeiten eliminiert werden, wenn ein limitierender Parameter zum ausschluss einer Dokumentenklasse führen soll.
99:                                                                 .map(limitierenderParameter -> limitierenderParameter.accept(new LimitierenderParameterVisitor<Boolean>() {
100:                                                                         @Override
101:                                                                         public Boolean handle(final MaxKundenauftraege maxKundenauftraege) {
102:                                                                                 return maxKundenauftraege.getValue() > 0; // lol
103:                                                                         }
104:
105:                                                                         @Override
106:                                                                         public Boolean handle(final MaxBeilagenarten maxBeilagenarten) {
107:                                                                                 return dokumentenklasse.getVariablen().get(BeilagenArten.class)
108:                                                                                                 .map(BeilagenArten::getBeilagenarten)
109:                                                                                                 .map(Set::size)
110:                                                                                                 .map(size -> size <= maxBeilagenarten.getBegrenzung())
111:                                                                                                 .orElse(true);
112:                                                                         }
113:
114:                                                                         @Override
115:                                                                         public Boolean handle(final Rollenkapazitaet rollenkapazitaet) {
116:                                                                                 return true;
117:                                                                         }
118:                                                                 }))
119:
120:                                 )
121:                                                 /* Hier befindet sich nun ein Stream mit so vielen Elementen, wie es Parameter beim Ausruf gibt.
122:                                                 Es werden die Klassen abgearbeitet, für welche ALLE Parameter zutreffen.*/
123:                                                 .reduce(Boolean.TRUE, (current, rest) -> current && rest)));
124:         }
125:
126:         /**
127:          * Setzt die Parameter in den Kontext des Services und bereitet wichtige Parameter für schnellen Zugriff vor. Überschreibt/ löscht 'alte' Parameter.
128:          *
129:          * @param parameter zu organisierende Parameter.
130:          */
131:         private void organizeParameters(final Set<ProduktionsauftragsParameter> parameter) {
132:                 this.parameterMap = new ClassObjectMap<>();
133:                 parameter.forEach(this.parameterMap::put);
134:         }
135:
136:         /**
137:          * Erstellt eine Liste der nächsten abzufertigenden Produktionsaufträge. Abgearbeitet werden dazu Kundenaufträge, die priorisiert nach SLA und gruppiert nach
138:          * ProzessTyp in Produktionsaufträge überführtwerden.
139: * Ein Produktionsauftrag wird dabei nur erstellt, wenn dabei eine ganze Rolle gefüllt wird oder er mindestens ein
140:          * dringenden Auftrag (kleiner Zeit Methodenlauf + 2 Tage) enthällt.
141:          */
142:         private List<ProduktionsauftragsBuilder> erstelleProduktionsauftraegeIntern(final Collection<DokumentenklasseBuilder> nichtKomplettAbgearbeitetenKundenauftraege) {
143:                 final List<DokumentenklasseBuilder> collect = this.sortiereNachStrategieParametern(nichtKomplettAbgearbeitetenKundenauftraege);
144:                 return this.erstelleProduktionsauftraegeZuEinemProzesstyp(collect);
145:         }
146:
147:         private List<DokumentenklasseBuilder> sortiereNachStrategieParametern(final Collection<DokumentenklasseBuilder> nichtKomplettAbgearbeitetenKundenauftraege) {
148:                 return nichtKomplettAbgearbeitetenKundenauftraege.stream()
149:                                 .sorted((o1, o2) -> this.parameterMap.getBySuperclass(StrategieParameter.class).stream()
150:                                                 .sorted(Comparator.comparing(StrategieParameter::holePrioritaet))
151:                                                 //TODO Art: Feature request; ich denke es wär sinnvoll für das Codeverständnis,
152: // diesen Visitor als private Class zu definieren und einen Kommentar zu spendieren.
153:                                                 .map(param -> param.accept(new StrategieParameterVisitor<Integer>() {
154:                                                         @Override
155:                                                         public Integer handle(final FarbDruckTypMischbar farbDruckTypMischbar) {
156:                                                                 return o1.getVariablen().get(FarbDruckTyp.class).orElse(FarbDruckTyp.Farbdruck)
157:                                                                                 .compareTo(o2.getVariablen().get(FarbDruckTyp.class).orElse(FarbDruckTyp.Farbdruck));
158:                                                         }
159:
160:                                                         @Override
161:                                                         public Integer handle(final SimplexDuplexMischbar simplexDuplexMischbar) {
162:                                                                 return o1.getVariablen().get(DruckTyp.class).orElse(DruckTyp.duplex)
163:                                                                                 .compareTo(o2.getVariablen().get(DruckTyp.class).orElse(DruckTyp.duplex));
164:                                                         }
165:
166:                                                 })).reduce((erstes, zweites) -> zweites)
167:                                                 .orElse(0)).collect(Collectors.toList());
168:         }
169:
170:         /**
171:          * Erstellt Produktionsaufträge und liefert diese zurück. Die Liste beinhaltet vermischt die priorisierten und nicht-priorisierten Dokumentenklassen.
172:          *
173:          * @param kundenauftraege Dokumentenklassen, welche zu Produktionsaufträgen verarbeitet werden sollen.
174:          * @return Liste von Produktionsaufträgen
175:          */
176:         private List<ProduktionsauftragsBuilder> erstelleProduktionsauftraegeZuEinemProzesstyp(final List<DokumentenklasseBuilder> kundenauftraege) {
177:                 final List<ProduktionsauftragsBuilder> produktionsAuftraege = new ArrayList<>();
178:
179:                 try {
180:                         this.verarbeitePriorisierteKundenauftraege(kundenauftraege, produktionsAuftraege);
181:                         // hier wird die gleiche Liste für die priorisierten und nicht-priorisierten Kundenaufträge genutzt.
182:                         // Sollte man diese voneinander trennen wollen, so ist hier die Möglichkeit das gut zu realisieren.
183:                         this.verarbeiteNichtPriorisierteKundenauftraege(kundenauftraege, produktionsAuftraege);
184:                 } catch (final FaktorOutOfBoundsException | UnpassendeKlasseException | AlreadyExistsException e) {
185:                         // Die exceptions brauch doch echt keiner...
186:                         throw new RuntimeException(e);
187:                 }
188:
189:                 return produktionsAuftraege;
190:         }
191:
192:         /**
193:          * Hier werden Kundenaufträge verarbeite und Produktionsaufträgen zugewiesen Dies geschied anhand der Wichtigkeit (Dringlichkeit durch SLA definiert) und die
194:          * Auslastung vorhandener Rollen in % wichtige Aufträge haben Vorrang vor unwichtigen.
195:          *
196:          * @param kundenauftraege zu verarbeitende Kundenaufträge.
197:          * @param produktionsAuftraege bereits evtl. erstellte Produktionsaufträge.
198:          */
199:         private void verarbeiteNichtPriorisierteKundenauftraege(final List<DokumentenklasseBuilder> kundenauftraege,
200:          final List<ProduktionsauftragsBuilder> produktionsAuftraege)
201:                         throws FaktorOutOfBoundsException, UnpassendeKlasseException, AlreadyExistsException {
202:                 final List<DokumentenklasseBuilder> nichtPriorisierteKundenauftraege =
203:                                 kundenauftraege.stream().filter(it -> !this.kundenauftragIstWichtig(it)).collect(Collectors.toList());
204:
205:                 this.fuelleProduktionsauftrag(produktionsAuftraege, nichtPriorisierteKundenauftraege);
206:         }
207:
208:         /**
209:          * Verarbeitet priorisierte Kundenaufträge und liefert eine Liste mit Produktionsaufträgen zurück.
210:          *
211:          * @param kundenauftraege zu verarbeitende Kundenaufträge.
212:          * @param produktionsAuftraege bereits evtl. existierende Produktionsaufträge.
213:          */
214:
215:         private void verarbeitePriorisierteKundenauftraege(final List<DokumentenklasseBuilder> kundenauftraege, final List<ProduktionsauftragsBuilder> produktionsAuftraege)
216:                         throws FaktorOutOfBoundsException, UnpassendeKlasseException, AlreadyExistsException {
217:                 final List<DokumentenklasseBuilder> priorisierteKundenauftraege =
218:                                 kundenauftraege.stream()
219:                                                 .filter(this::kundenauftragIstWichtig)
220:                                                 .collect(Collectors.toList());
221:
222:                 if (!priorisierteKundenauftraege.isEmpty()) {
223:                         this.fuelleProduktionsauftragPriorisiert(produktionsAuftraege, priorisierteKundenauftraege);
224:                 }
225:         }
226:
227:         /**
228:          * Füllt Produktionsaufträge mit priorisierten Kundenaufträgen Dies wird mittels der gegebenen SLA Zeiten entschieden.
229:          *
230:          * @param produktionsAuftraege bereits evtl. existierende Produktionsaufträge.
231:          * @param priorisierteKundenauftraege zu verarbeitende Kundenaufträge.
232:          */
233:         private void fuelleProduktionsauftragPriorisiert(
234:                         final List<ProduktionsauftragsBuilder> produktionsAuftraege,
235:                         final List<DokumentenklasseBuilder> priorisierteKundenauftraege)
236:                         throws AlreadyExistsException, FaktorOutOfBoundsException, UnpassendeKlasseException {
237:                 ProduktionsauftragsBuilder matchingProduktionsauftragsBuilder;
238:                 for (final DokumentenklasseBuilder dokumentenklasse : priorisierteKundenauftraege) {
239:                         while (dokumentenklasse.getRestlicheBlaetter() > 0) {
240:                                 matchingProduktionsauftragsBuilder = this.ermittlePassendenProduktionsauftragsBuilder(produktionsAuftraege, dokumentenklasse);
241:
242:                                 if (this.passtKomplettAufRolle(matchingProduktionsauftragsBuilder, dokumentenklasse)) {
243:                                         matchingProduktionsauftragsBuilder.addDokumentenklasse(dokumentenklasse, this.errechneFaktorNochOffeneBlattzahl(dokumentenklasse));
244:                                 } else {
245:                                         final double verarbeitbarerFaktor =
246:                                                         this.errechneVerarbeitbarenFaktor(matchingProduktionsauftragsBuilder, dokumentenklasse);
247:                                         matchingProduktionsauftragsBuilder.addDokumentenklasse(dokumentenklasse, verarbeitbarerFaktor);
248:                                 }
249:                         }
250:                 }
251:         }
252:
253:         /**
254:          * Prüft, ob es in der vorhandenen Liste der ProduktionsauftragsBuilder einen einen zur Dokumentenklasse passenenden Builder gibt. Gibt es keinen, wird ein neuer
255:          * erstellt und in die Liste hinzugefügt.
256:          *
257:          * @param produktionsAuftraege zu prüfende ProduktionsauftragsBuilder.
258:          * @param dokumentenklasse auf Kompatibilität zu prüfende Dokumentenklasse.
259:          * @return einen zur Dokumentenklasse passenden ProduktionsauftragsBuilder.
260:          */
261:         private ProduktionsauftragsBuilder ermittlePassendenProduktionsauftragsBuilder(
262:                         final List<ProduktionsauftragsBuilder> produktionsAuftraege,
263:                         final DokumentenklasseBuilder dokumentenklasse) {
264:                 // TODO Art: unidentified; ich weiß nicht ob, aber vermutlich kann man das auch irgendwie magisch effizienter mit weniger rechnen machen?
265:                 return produktionsAuftraege.stream()
266:                                 .filter(produktionsauftrag -> produktionsauftrag.pruefeKompatibilitaet(dokumentenklasse))
267:                                 .filter(produktionsauftrag -> this.errechneVerarbeitbarenFaktor(produktionsauftrag, dokumentenklasse) > 0)
268:                                 .findFirst().orElseGet(() -> {
269:                                         final ProduktionsauftragsBuilder newProduktionsauftragsBuilder = new ProduktionsauftragsBuilder(this.parameterMap);
270:
271:                                         produktionsAuftraege.add(newProduktionsauftragsBuilder);
272:                                         return newProduktionsauftragsBuilder;
273:                                 });
274:         }
275:
276:         /**
277:          * Hier werden Produktionsaufträge mit Kundenauftrage bzw. daraus gewonnenen Dokumentenklassen befüllt.
278: * Beachtet werden neben den SLA Zeiten auch die verfügbaren
279:          * Kapazitäten auf Papierrollen. Um einem produktionsauftrag zugeordnet werden zu könnene,
280: * werden die Kundenaufträge nach SLA und dann nach Prozesstyp gruppiert.
281: * Am Ende entsteht eine Grupe Liste mit allen Produktionsaufträgen (Wichtig und ohne SLA gemischt)
282:          *
283:          * @param produktionsAuftraege bereits evtl. existierende Produktionsaufträge.
284:          * @param nichtPriorisierteKundenauftraege zu verarbeitende Kundenaufträge.
285:          */
286:         private void fuelleProduktionsauftrag(final List<ProduktionsauftragsBuilder> produktionsAuftraege,
287:          final List<DokumentenklasseBuilder> nichtPriorisierteKundenauftraege)
288:                         throws FaktorOutOfBoundsException, UnpassendeKlasseException, AlreadyExistsException {
289:                 for (final DokumentenklasseBuilder dokumentenklasse : nichtPriorisierteKundenauftraege) {
290:                         while (dokumentenklasse.getRestlicheBlaetter() > 0) {
291:                                 final ProduktionsauftragsBuilder currentProduktionsAuftrag = this.ermittlePassendenProduktionsauftragsBuilder(produktionsAuftraege, dokumentenklasse);
292:
293:                                 if (this.passtKomplettAufRolle(currentProduktionsAuftrag, dokumentenklasse)) {
294:                                         currentProduktionsAuftrag.addDokumentenklasse(
295:                                                         dokumentenklasse,
296:                                                         this.errechneFaktorNochOffeneBlattzahl(dokumentenklasse));
297:                                 } else {
298:                                         final double verarbeitbarerFaktor =
299:                                                         this.errechneVerarbeitbarenFaktor(currentProduktionsAuftrag, dokumentenklasse);
300:                                         currentProduktionsAuftrag.addDokumentenklasse(dokumentenklasse, verarbeitbarerFaktor);
301:                                         // TODO Art: unidentified; Jan/ Jeremy was geschieht mit der restlichen, nicht eingeplanten dokumentenklasse? Die
302:                                         // müsste ja gesplittet in einen neuen Produktionsauftrag kommen.
303:                                 }
304:                         }
305:                 }
306:         }
307:
308:         /**
309:          * @param dokumentenklasse Dokumentenklasse zu welcher der Faktor der noch offenen Blätter bestimmt werden soll.
310:          * @return liefert die noch freien Seiten in A4 auf einer Rolle in % zurück
311:          */
312:         private double errechneFaktorNochOffeneBlattzahl(final DokumentenklasseBuilder dokumentenklasse) {
313:                 return dokumentenklasse.getBereitsEingeplanteBlaetter() == 0 ? 1.0
314:                                 : dokumentenklasse.getRestlicheBlaetter() / (double) dokumentenklasse.getAnzahlBlaetter();
315:         }
316:
317:         /**
318:          * @param produktionsAuftrag Produktionsauftrag, zu welchem geprüft werden soll, wie voll die Dokumentenklasse auf dem Autrag Platz findet.
319:          * @param dokumentenklasse Dokumentenklasse zu welcher geprüft werden soll, wie vollständig diese Platz auf einem Produktionsauftrag findet.
320:          * @return liefert die restlichen freien Seiten der Rolle zurück, nachdem der produktionsauftrag auf dieser untergebracht wurde
321:          */
322:         private double errechneVerarbeitbarenFaktor(final ProduktionsauftragsBuilder produktionsAuftrag,
323:          final DokumentenklasseBuilder dokumentenklasse) {
324:                 return this.parameterMap.get(Rollenkapazitaet.class).map(Rollenkapazitaet::getKapazitaet)
325:                                 .map(
326:                                                 kapazitaet -> (kapazitaet - produktionsAuftrag.getBlattZahl())
327:                                                                 / (double) dokumentenklasse.getRestlicheBlaetter())
328:                                 .orElse(1.);
329:         }
330:
331:         /**
332:          * @param nichtPriorisierteKundenauftraege kundenaufträge, mit welchen geprüft wird, ob die Rolle gefüllt werden kann.
333: * Enthält dieser Parameter eine leere Liste, so wird false geliefert.
334:          * @return Gibt an ob die Rolle 100% Auslastung erreicht hat
335:          */
336:         private boolean bekommeRolleVoll(final List<DokumentenklasseBuilder> nichtPriorisierteKundenauftraege) {
337:                 return !nichtPriorisierteKundenauftraege.isEmpty()
338:                                 && this.parameterMap.get(Rollenkapazitaet.class).map(Rollenkapazitaet::getKapazitaet)
339:                                 .map(
340:                                                 kapazitaet -> nichtPriorisierteKundenauftraege.stream()
341:                                                                 .mapToInt(DokumentenklasseBuilder::getRestlicheBlaetter).sum() >= kapazitaet)
342:                                 .orElse(true);
343:         }
344:
345:         /**
346:          * @param produktionsAuftrag Produktionsauftrag, zu welchem geprüft wird, ob die Dokumentenklasse vollständig drauf passt.
347:          * @param dokumentenklasse Dokumentenklasse, zu welcher geprüft werden soll, ob diese vollständig auf den Produktionsauftrag passt.
348:          * @return Passt der Auftrag ganz auf die Rolle? Liefert zurück ob der Umfang in A4 Blättern auf die gewählte rolle passt oder nicht
349:          */
350:         private boolean passtKomplettAufRolle(final ProduktionsauftragsBuilder produktionsAuftrag, final DokumentenklasseBuilder dokumentenklasse) {
351:                 return this.parameterMap.get(Rollenkapazitaet.class).map(Rollenkapazitaet::getKapazitaet).map(
352:                                 kapazitaet -> dokumentenklasse.getRestlicheBlaetter() + produktionsAuftrag.getBlattZahl() <= kapazitaet)
353:                                 .orElse(true);
354:         }
355:
356:         /**
357:          * @param dokumentenklasse Dokumentenklasse, welche auf Priorität geprüft werden soll.
358:          * @return Ob ein Kundenauftrag wichtig ist; Anhand der SLA Zeiten ermittelt
359:          */
360:         private boolean kundenauftragIstWichtig(final DokumentenklasseBuilder dokumentenklasse) {
361:                 return dokumentenklasse.getSla().getFrist(dokumentenklasse.getEingangszeitpunkt()).isBefore(LocalDateTime.now().plusDays(2));
362:         }
363:
364: /**
365: * Innere Klasse, welche einen Namen bekommen hat damit Checkstyle nicht meckert.
366: * // TODO Art: Feature request; Jan oder Jeremy bitte beschreiben, was diese Klasse genau tut und evtl den Namen anpassen.
367: */
368: private static class BooleanAusschliessenderParameterVisitor implements AusschliessenderParameterVisitor<Boolean> {
369: private final Dokumentenklasse dokumentenklasse;
370:
371: BooleanAusschliessenderParameterVisitor(final Dokumentenklasse dokumentenklasse) {
372: this.dokumentenklasse = dokumentenklasse;
373: }
374:
375: @Override
376: public Boolean handle(final Kunden kunden) {
377: return this.dokumentenklasse.getVariablen().get(Kunde.class).map(kunden::contains).orElse(false);
378: }
379:
380: @Override
381: public Boolean handle(final KuvertFormate kuvertFormate) {
382: return this.dokumentenklasse.getVariablen().get(KuvertFormat.class).map(kuvertFormate::contains).orElse(false);
383: }
384:
385: @Override
386: public Boolean handle(final ProzessModell prozessModell) {
387: return this.dokumentenklasse.getVariablen().get(ProzessModell.class).map(prozessModell::equals).orElse(false);
388: }
389:
390: @Override
391: public Boolean handle(final BeilagenArten beilagenArten) {
392: return this.dokumentenklasse.getVariablen().get(BeilagenArten.class)
393: //TODO Art: Work in Progress; hier muss politisch entschieden werden, ob ALLE oder nur ein teil der Beilagen enthalten sein muss
394: .map(e -> beilagenArten.containsAll(e.getBeilagenarten()))
395: .orElse(false);
396: }
397:
398: @Override
399: public Boolean handle(final Zeitraum zeitraum) {
400: return zeitraum.contains(this.dokumentenklasse.getFrist());
401: }
402:
403: @Override
404: public Boolean handle(final BlattAnzahlSpanne blattAnzahlSpanne) {
405: return this.dokumentenklasse.getVariablen().get(BlattAnzahl.class).map(blattAnzahlSpanne::contains).orElse(false);
406: }
407:
408: @Override
409: public Boolean handle(final DruckTyp druckTyp) {
410: return this.dokumentenklasse.getVariablen().get(DruckTyp.class).map(druckTyp::equals).orElse(false);
411: }
412:
413: @Override
414: public Boolean handle(final PapierFormate papierFormate) {
415: return this.dokumentenklasse.getVariablen().get(Papierformat.class).map(papierFormate::contains).orElse(false);
416: }
417:
418: @Override
419: public Boolean handle(final FarbDruckTyp farbDruckTyp) {
420: return this.dokumentenklasse.getVariablen().get(FarbDruckTyp.class).map(farbDruckTyp::equals).orElse(false);
421: }
422: }
423: }