Skip to content

Package: Kalender

Kalender

nameinstructionbranchcomplexitylinemethod
Kalender()
M: 0 C: 13
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 4
100%
M: 0 C: 1
100%
addEintrag(KalenderEintrag)
M: 0 C: 55
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 9
100%
M: 0 C: 1
100%
dauerDesEintragsKleinerAlsDauer(Zeitraum, Quantity)
M: 0 C: 17
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 1
100%
erstelleMonatlichenSerienTermin(KalenderEintrag)
M: 0 C: 13
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 4
100%
M: 0 C: 1
100%
erstelleSerienTerminMitWiederholungsIntervall(KalenderEintrag, ComparableQuantity)
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%
findeFreieZeitslots(Quantity, Set, Set)
M: 0 C: 33
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 8
100%
M: 0 C: 1
100%
getAbwesenheitenAlsZeitraeume(Collection)
M: 0 C: 10
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 4
100%
M: 0 C: 1
100%
getAlleEintraege(Zeitraum, KalenderEintragTyp[])
M: 0 C: 60
100%
M: 0 C: 10
100%
M: 0 C: 6
100%
M: 0 C: 10
100%
M: 0 C: 1
100%
getEintraege()
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%
getEintraegeZuTag(LocalDate)
M: 0 C: 23
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 6
100%
M: 0 C: 1
100%
getEintraegeZuTagOhneSerienTermine(LocalDate)
M: 0 C: 37
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 8
100%
M: 0 C: 1
100%
getFruehesteVerfuegbarkeit(LocalDateTime, Quantity, LocalDateTime)
M: 0 C: 45
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 10
100%
M: 0 C: 1
100%
getLetztenEintragVorZeitpunkt(LocalDateTime)
M: 0 C: 17
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 5
100%
M: 0 C: 1
100%
getRelevanteAnwesenheitenAlsZeitraum(Collection, Quantity)
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%
getVerfuegbarkeiten(LocalDateTime, Quantity, LocalDateTime)
M: 0 C: 65
100%
M: 0 C: 8
100%
M: 0 C: 5
100%
M: 0 C: 14
100%
M: 0 C: 1
100%
isVerfuegbar(LocalDateTime)
M: 0 C: 24
100%
M: 0 C: 4
100%
M: 0 C: 3
100%
M: 0 C: 4
100%
M: 0 C: 1
100%
isVerfuegbar(LocalDateTime, LocalDateTime)
M: 0 C: 12
100%
M: 0 C: 4
100%
M: 0 C: 3
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
lambda$findeFreieZeitslots$2(Quantity, Zeitraum)
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$getEintraegeZuTag$0(Collection, LocalDate, SerienTermin)
M: 0 C: 7
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
lambda$getLetztenEintragVorZeitpunkt$4(Set)
M: 0 C: 7
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
lambda$getLetztenEintragVorZeitpunkt$5(LocalDateTime, KalenderEintrag)
M: 0 C: 9
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
lambda$getRelevanteAnwesenheitenAlsZeitraum$3(Quantity, KalenderEintrag)
M: 0 C: 6
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
lambda$isVerfuegbar$1(LocalDateTime, KalenderEintrag)
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%
reduziereZeitraeumeWelcheUeberSLAGehen(Set, LocalDateTime)
M: 0 C: 33
100%
M: 0 C: 4
100%
M: 0 C: 3
100%
M: 0 C: 7
100%
M: 0 C: 1
100%
reduziereZeitraeumeWelcheVorAbZeitpunktSind(Set, LocalDateTime)
M: 0 C: 33
100%
M: 0 C: 4
100%
M: 0 C: 3
100%
M: 0 C: 7
100%
M: 0 C: 1
100%
removeEintrag(KalenderEintrag)
M: 0 C: 36
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 6
100%
M: 0 C: 1
100%

Coverage

1: package zeit;
2:
3: import tec.uom.se.ComparableQuantity;
4: import util.exceptions.KeineVerfuegbarkeitException;
5: import zeit.eintraege.KalenderEintrag;
6: import zeit.eintraege.KalenderEintragTyp;
7: import zeit.eintraege.Zeitraum;
8: import zeit.serientermin.SerienTermin;
9:
10: import javax.measure.Quantity;
11: import javax.measure.quantity.Time;
12: import java.time.LocalDate;
13: import java.time.LocalDateTime;
14: import java.time.format.DateTimeFormatter;
15: import java.time.temporal.ChronoUnit;
16: import java.util.ArrayList;
17: import java.util.Collection;
18: import java.util.Collections;
19: import java.util.Comparator;
20: import java.util.HashMap;
21: import java.util.HashSet;
22: import java.util.Map;
23: import java.util.Objects;
24: import java.util.Optional;
25: import java.util.Set;
26: import java.util.stream.Collectors;
27: import java.util.stream.Stream;
28:
29: /**
30: * Kalender Schnittstelle, welche die Gemeinsamkeiten aller Kalenderimplementierungen kapselt.
31: * Alle Kalender haben Kalendereinträge(zugeordnet zu Tagen, an denen sie stattfinden) und Serientermine.
32: */
33: public abstract class Kalender {
34:
35:         private final Map<LocalDate, Set<KalenderEintrag>> eintraege;
36:         private final Set<SerienTermin> serienTermine;
37:
38:         /**
39:          * Erstellte einen Kalender ohne Kalendereinträgen und Serienterminen.
40:          */
41:         protected Kalender() {
42:                 this.eintraege = new HashMap<>();
43:                 this.serienTermine = new HashSet<>();
44:         }
45:
46:         /**
47:          * Fügt dem Kalender einen Eintrag hinzu.
48:          *
49:          * @param eintrag
50:          *                 hinzuzufügender Eintrag.
51:          */
52:         public void addEintrag(final KalenderEintrag eintrag) {
53:                 this.pruefeKalenderEintrag(eintrag);
54:
55:                 final LocalDate tagVon = eintrag.getVon().toLocalDate();
56:                 final LocalDate tagBis = eintrag.getBis().toLocalDate();
57:
58:                 this.eintraege.putIfAbsent(tagVon, new HashSet<>());
59:                 this.eintraege.get(tagVon).add(eintrag);
60:
61:•                for (LocalDate laufendesDatum = tagVon; laufendesDatum.isBefore(tagBis); laufendesDatum = laufendesDatum.plusDays(1)) {
62:                         this.eintraege.putIfAbsent(tagBis, new HashSet<>());
63:                         this.eintraege.get(tagBis).add(eintrag);
64:                 }
65:         }
66:
67:
68:         /**
69:          * Entfernt einen KalenderEintrag aus dem Kalender.
70:          *
71:          * @param eintrag
72:          *                 zu entfernender KalenderEintrag.
73:          */
74:         public void removeEintrag(final KalenderEintrag eintrag) {
75:                 final LocalDate tagVon = eintrag.getVon().toLocalDate();
76:                 final LocalDate tagBis = eintrag.getBis().toLocalDate();
77:
78:                 this.eintraege.get(tagVon).remove(eintrag);
79:
80:•                for (LocalDate laufendesDatum = tagVon; laufendesDatum.isBefore(tagBis); laufendesDatum = laufendesDatum.plusDays(1)) {
81:                         this.eintraege.get(tagBis).remove(eintrag);
82:                 }
83:         }
84:
85:         /**
86:          * @param typ
87:          *                 Kalendereintrag, dessen Richtigkeit geprüft werden soll.
88:          */
89:         protected abstract void pruefeKalenderEintrag(KalenderEintrag typ);
90:
91:         /**
92:          * @param eintrag
93:          *                 Kalendereintrag, welcher Serienmäßig wiederholt werden soll.
94:          * @param wiederholungsIntervall
95:          *                 Zeitspanne nach welcher sich der Kalendereintrag wiederholen soll.
96:          */
97:         public void erstelleSerienTerminMitWiederholungsIntervall(final KalenderEintrag eintrag, final ComparableQuantity<Time> wiederholungsIntervall) {
98:                 this.pruefeKalenderEintrag(eintrag);
99:                 this.serienTermine.add(SerienTermin.createSerienterminMitIntervall(eintrag, wiederholungsIntervall));
100:         }
101:
102:
103:         /**
104:          * Erstellt einen Termin, der sich jeden Monat am gleichen Tag bis ins Unendliche wiederholt.
105:          *
106:          * @param eintrag
107:          *                 Kalendereintrag, welcher Serienmäßig wiederholt werden soll.
108:          * @return liefert den Serientermin, der dem Kalender hinzugefügt wird
109:          */
110:         public SerienTermin erstelleMonatlichenSerienTermin(final KalenderEintrag eintrag) {
111:                 this.pruefeKalenderEintrag(eintrag);
112:                 final SerienTermin monatlicherSerientermin = SerienTermin.createMonatlichenSerientermin(eintrag);
113:                 this.serienTermine.add(monatlicherSerientermin);
114:                 return monatlicherSerientermin;
115:         }
116:
117:         /**
118:          * @param tag
119:          *                 zu welchem alle Einträge im Kalender bestimmt werden sollen.
120:          *
121:          * @return Liefert ein nicht bearbeitbares Set der Einträge des Tages zurück.
122:          */
123:         public Collection<KalenderEintrag> getEintraegeZuTag(final LocalDate tag) {
124:                 final Collection<KalenderEintrag> eintraegeZuTag = this.getEintraegeZuTagOhneSerienTermine(tag);
125:•                if (this.serienTermine.isEmpty()) {
126:                         return eintraegeZuTag;
127:                 }
128:
129:                 final Collection<KalenderEintrag> result = new HashSet<>(eintraegeZuTag);
130:                 this.serienTermine.forEach(serienTermin -> result.addAll(serienTermin.getKalenderEintraegeDesSerienTerminAmTag(tag)));
131:                 return result;
132:         }
133:
134:         /**
135:          * Template-Method.
136:          *
137:          * @param tag
138:          *                 zu welchem alle Einträge im Kalender bestimmt werden sollen.
139:          *
140:          * @return Liefert ein nicht bearbeitbares Set der Einträge des Tages zurück.
141:          *                 Hier werden keine Serientermine mehr beachtet.
142:          */
143:         protected Collection<KalenderEintrag> getEintraegeZuTagOhneSerienTermine(final LocalDate tag) {
144:                 final Set<KalenderEintrag> result = this.getEintraege().get(tag);
145:                 final Optional<KalenderEintrag> defaultEintragZuTag = this.createDefaultEintragZuTag(tag);
146:•                if (Objects.isNull(result)) {
147:                         final Set<KalenderEintrag> eintraegeZuTag = new HashSet<>();
148:                         defaultEintragZuTag.ifPresent(eintraegeZuTag::add);
149:                         return Collections.unmodifiableCollection(eintraegeZuTag);
150:                 }
151:                 defaultEintragZuTag.ifPresent(result::add);
152:                 return Collections.unmodifiableCollection(result);
153:         }
154:
155:         /**
156:          * @param tag
157:          *                 Tag, für welchen ein Default-Eintrag im Kalender erzeugt werden soll.
158:          *
159:          * @return einen optionalen Standardeintrag für den speziellen Kalendertypen.
160:          *                 Eine Maschine ist z.B. immer von 0-24 Uhr verfügbar und deswegen wird hier im Maschinenkalender ein entsprechender Eintrag zurückgegeben.
161:          *                 Ein Mitarbeiter ist z.B. immer von 8-16 Uhr anwesend und deswegen wird hier im Mitarbeiterkalender ein entsprechender Eintrag zurückgegeben.
162:          */
163:         protected abstract Optional<KalenderEintrag> createDefaultEintragZuTag(LocalDate tag);
164:
165:         /**
166:          * @param zeitpunkt
167:          *                 Zeitpunkt bei welchem die Verfügbarkeit ermittelt werden soll.
168:          *
169:          * @return true wenn nach dem Kalender eine Verfügbarkeit besteht.
170:          *                 Konkurierende Einträege werden beachtet, dabei wird eine Belegung/Wartung/Abwesenheit oder Krankheit stärker gewichtet,
171:          *                 als Verfügbarkeit und Anwesenheit.
172:          *                 z.B. Anwesend 8-14 Uhr, Belegt 10-14 Uhr, dann ist die Maschine nur von 8-10 Uhr verfügbar!
173:          */
174:         public boolean isVerfuegbar(final LocalDateTime zeitpunkt) {
175:                 final Set<KalenderEintrag> eintraegeDieDenZeitpunktbeinhalten = this.getEintraegeZuTag(zeitpunkt.toLocalDate()).stream()
176:                                 .filter(eintrag -> eintrag.contains(zeitpunkt)).collect(Collectors.toSet());
177:•                return !eintraegeDieDenZeitpunktbeinhalten.isEmpty()
178:•                                && eintraegeDieDenZeitpunktbeinhalten.stream().allMatch(KalenderEintrag::isVerfuegbar);
179:         }
180:
181:         /**
182:          * @param von
183:          *                 Beginn des zu prüfenden Zeitraums
184:          * @param bis
185:          *                 Ende des zu prüfenden Zeitraums
186:          *
187:          * @return true wenn nach dem Kalender eine Verfügbarkeit besteht.
188:          *                 Konkurierende Einträege werden beachtet, dabei wird eine Belegung stärker gewichtet.
189:          *                 z.B. Anwesend 8-14 Uhr, Belegt 10-14 Uhr, dann ist die Maschine nur von 8-10 Uhr verfügbar!
190:          */
191:         public boolean isVerfuegbar(final LocalDateTime von, final LocalDateTime bis) {
192:•                return this.isVerfuegbar(von) && this.isVerfuegbar(bis);
193:         }
194:
195:         /**
196:          * @param tag
197:          *                 zu welchem die verfügbare Zeit ermittelt werden soll.
198:          * @param einheit
199:          *                 einheit der Zahl die zurückgegeben wird.
200:          *
201:          * @return Die Arbeitszeit in der spezifizierten Einheit.
202:          *                 Eine Maschine arbeitet nicht wenn sie gewartet wird
203:          *                 und ein Mensch arbeitet nicht wenn er krank ist.
204:          */
205:         public abstract long getArbeitszeit(LocalDate tag, ChronoUnit einheit);
206:
207:         /**
208:          * @param abZeitpunkt
209:          *                 Zeipunkt ab dem die nächste Verfügbarkeit gefunden werden soll.
210:          * @param benoetigteZeit
211:          *                 Groesse des Zeitslots der benötigt wird
212:          * @param slaFrist
213:          *                 Zeitpunkt, bis zu dem ein Zeitslot gefunden sein muss
214:          *
215:          * @return alle Zeitslots bis zur SLA-Frist in denen der Kalender frei ist und die mindestens die Länge der benötigten Zeit haben.
216:          */
217:         public Collection<Zeitraum> getVerfuegbarkeiten(final LocalDateTime abZeitpunkt, final Quantity<Time> benoetigteZeit, final LocalDateTime slaFrist) {
218:                 final Collection<Zeitraum> zeitslots = new HashSet<>();
219:                 LocalDateTime laufenderZeitpunkt = abZeitpunkt;
220:•                while (laufenderZeitpunkt.isBefore(slaFrist) || laufenderZeitpunkt.equals(slaFrist)) {
221:
222:                         final Collection<KalenderEintrag> alleEintraegeZumTag = this.getEintraegeZuTagOhneSerienTermine(laufenderZeitpunkt.toLocalDate());
223:
224:                         Set<Zeitraum> relevanteAnwesenheiten = this.getRelevanteAnwesenheitenAlsZeitraum(alleEintraegeZumTag, benoetigteZeit);
225:                         final Set<Zeitraum> abwesenheiten = this.getAbwesenheitenAlsZeitraeume(alleEintraegeZumTag);
226:
227:•                        if (slaFrist.toLocalDate().equals(laufenderZeitpunkt.toLocalDate())) {
228:                                 // SLA-Frist ist am Tag des laufenden Zeitpunkts.
229:                                 relevanteAnwesenheiten = this.reduziereZeitraeumeWelcheUeberSLAGehen(relevanteAnwesenheiten, slaFrist);
230:                         }
231:
232:•                        if (abZeitpunkt.toLocalDate().equals(laufenderZeitpunkt.toLocalDate())) {
233:                                 // Ab Zeitpunkt ist am Tag des laufenden Zeitpunkts.
234:                                 relevanteAnwesenheiten = this.reduziereZeitraeumeWelcheVorAbZeitpunktSind(relevanteAnwesenheiten, abZeitpunkt);
235:                         }
236:
237:
238:                         zeitslots.addAll(this.findeFreieZeitslots(benoetigteZeit, relevanteAnwesenheiten, abwesenheiten));
239:
240:                         laufenderZeitpunkt = laufenderZeitpunkt.plusDays(1);
241:                 }
242:                 return zeitslots;
243:         }
244:
245:         /**
246:          * @param abZeitpunkt
247:          *                 Zeitpunkt ab dem die nächste Verfügbarkeit gefunden werden soll.
248:          * @param benoetigteZeit
249:          *                 Groesse des Zeitslots der benötigt wird
250:          * @param slaFrist
251:          *                 Zeitpunkt, bis zu dem ein Zeitslot gefunden sein muss
252:          *
253:          * @return fruehster Zeitpunkt zu dem ein Zeitslot der spezifizierten Groesse verfügbar ist
254:          * @throws KeineVerfuegbarkeitException
255:          *                 wenn keine Zeitraum bis zum SLA in der vorgegebenen Länge gefunden werden kann.
256:          */
257:         public LocalDateTime getFruehesteVerfuegbarkeit(final LocalDateTime abZeitpunkt,
258:          final Quantity<Time> benoetigteZeit,
259:          final LocalDateTime slaFrist) throws KeineVerfuegbarkeitException {
260:                 final Optional<LocalDateTime> beginnDesErstenZeitslots = this.getVerfuegbarkeiten(abZeitpunkt, benoetigteZeit, slaFrist).stream()
261:                                 .map(Zeitraum::getVon)
262:                                 .sorted()
263:                                 .findFirst();
264:•                if (beginnDesErstenZeitslots.isPresent()) {
265:                         return beginnDesErstenZeitslots.get();
266:                 }
267:
268:                 final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm:ss");
269:                 throw new KeineVerfuegbarkeitException(String.format("Bis zur SLA-Frist %s wurde ab dem Zeitpunkt %s kein freier Zeitslot von %s gefunden.",
270:                                 formatter.format(slaFrist),
271:                                 formatter.format(abZeitpunkt),
272:                                 benoetigteZeit));
273:         }
274:
275:         private Collection<Zeitraum> findeFreieZeitslots(final Quantity<Time> benoetigteZeit,
276:          final Set<Zeitraum> relevanteAnwesenheiten,
277:          final Set<Zeitraum> abwesenheiten) {
278:                 final Collection<Zeitraum> zeitslots = new HashSet<>();
279:
280:•                for (final Zeitraum anwesenheitsZeitraum : relevanteAnwesenheiten) {
281:                         final Set<Zeitraum> wirklicheAnwesenheiten = anwesenheitsZeitraum.entferneZeitraeume(abwesenheiten);
282:
283:                         zeitslots.addAll(wirklicheAnwesenheiten.stream()
284:                                         .filter(zeitraum -> this.dauerDesEintragsKleinerAlsDauer(zeitraum, benoetigteZeit))
285:                                         .collect(Collectors.toSet()));
286:                 }
287:
288:                 return zeitslots;
289:
290:         }
291:
292:         private Set<Zeitraum> reduziereZeitraeumeWelcheVorAbZeitpunktSind(final Set<Zeitraum> relevanteAnwesenheiten, final LocalDateTime abZeipunkt) {
293:                 final Set<Zeitraum> reduzierteZeitraeume = new HashSet<>();
294:
295:•                for (final Zeitraum anwesenheit : relevanteAnwesenheiten) {
296:•                        if (anwesenheit.contains(abZeipunkt)) {
297:                                 // Arbeitszeitraum Anfang wird auf den abZeipunkt verkürzt.
298:                                 reduzierteZeitraeume.add(Zeitraum.create(abZeipunkt, anwesenheit.getBis()));
299:                         } else {
300:                                 reduzierteZeitraeume.add(anwesenheit);
301:                         }
302:                 }
303:
304:                 return reduzierteZeitraeume;
305:         }
306:
307:         private Set<Zeitraum> reduziereZeitraeumeWelcheUeberSLAGehen(final Set<Zeitraum> relevanteAnwesenheiten, final LocalDateTime slaFrist) {
308:                 final Set<Zeitraum> reduzierteZeitraeume = new HashSet<>();
309:
310:•                for (final Zeitraum anwesenheit : relevanteAnwesenheiten) {
311:•                        if (anwesenheit.contains(slaFrist)) {
312:                                 // Arbeitszeitraum Ende wird auf die SLA-Frist verkürzt.
313:                                 reduzierteZeitraeume.add(Zeitraum.create(anwesenheit.getVon(), slaFrist));
314:                         } else {
315:                                 reduzierteZeitraeume.add(anwesenheit);
316:                         }
317:                 }
318:
319:                 return reduzierteZeitraeume;
320:         }
321:
322:         private Set<Zeitraum> getAbwesenheitenAlsZeitraeume(final Collection<KalenderEintrag> eintraegeZuTag) {
323:                 return eintraegeZuTag.stream()
324:                                 .filter(KalenderEintrag::isNichtVerfuegbar)
325:                                 .map(KalenderEintrag::getZeitraum)
326:                                 .collect(Collectors.toSet());
327:         }
328:
329:         private Set<Zeitraum> getRelevanteAnwesenheitenAlsZeitraum(final Collection<KalenderEintrag> eintraegeZuTag,
330:          final Quantity<Time> benoetigteZeit) {
331:
332:                 return eintraegeZuTag.stream()
333:                                 // Nur Anwesenheiten
334:                                 .filter(KalenderEintrag::isVerfuegbar)
335:                                 // Nur Einträge, wessen Dauer länger oder gleich der geforderten Dauer sind berücksichtigen
336:                                 .filter(kalenderEintrag -> this.dauerDesEintragsKleinerAlsDauer(kalenderEintrag.getZeitraum(), benoetigteZeit))
337:                                 .map(KalenderEintrag::getZeitraum)
338:                                 .collect(Collectors.toSet());
339:
340:         }
341:
342:
343:         private boolean dauerDesEintragsKleinerAlsDauer(final Zeitraum zeitraum, final Quantity<Time> benoetigteZeit) {
344:                 final int dauerDesEintragsInEinheitDerDauer = zeitraum.getDauer().to(benoetigteZeit.getUnit()).getValue().intValue();
345:•                return dauerDesEintragsInEinheitDerDauer >= benoetigteZeit.getValue().intValue();
346:         }
347:
348:         /**
349:          * @return alle Kaleindereinträge des Kalenders. Hier werden keine Serientermine berücksichtigt.
350:          */
351:         protected Map<LocalDate, Set<KalenderEintrag>> getEintraege() {
352:                 return this.eintraege;
353:         }
354:
355:         /**
356:          * @param zeitraum
357:          *                 zu welchem die Einträge ermittelt werden soll.
358:          * @param filter
359:          *                 Liste der Typen, von denen Einträge zurückgegeben werden.
360:          *
361:          * @return Alle Einträge, bei denen der Typ dem Filter entspricht.
362:          */
363:         public Collection<KalenderEintrag> getAlleEintraege(final Zeitraum zeitraum, final KalenderEintragTyp[] filter) {
364:                 final Collection<KalenderEintrag> result = new ArrayList<>();
365:•                for (final Set<KalenderEintrag> kalenderEintraege : this.eintraege.values()) {
366:•                        for (final KalenderEintrag kalenderEintrag : kalenderEintraege) {
367:•                                if (kalenderEintrag.getZeitraum().ueberschneidet(zeitraum)) {
368:•                                        for (final KalenderEintragTyp typ : filter) {
369:•                                                if (kalenderEintrag.getTyp().compareTo(typ) == 0) {
370:                                                         result.add(kalenderEintrag);
371:                                                 }
372:                                         }
373:                                 }
374:                         }
375:
376:                 }
377:                 return result;
378:         }
379:
380:         /**
381:          * @param zeitpunkt
382:          *                 Zeitpunkt, vor welchem der späteste Eintrag geliefert wird.
383:          *
384:          * @return Spätester Eintrag vor dem Zeitpunkt.
385:          */
386:         public Optional<KalenderEintrag> getLetztenEintragVorZeitpunkt(final LocalDateTime zeitpunkt) {
387:                 return Stream.of(this.eintraege.get(zeitpunkt.toLocalDate()))
388:•                                .filter(e -> !Objects.isNull(e))
389:                                 .flatMap(Set::stream)
390:•                                .filter(eintrag -> !eintrag.getBis().isAfter(zeitpunkt))
391:                                 .max(Comparator.comparing(KalenderEintrag::getBis));
392:
393:                 //Falls doch umgestellt werden soll, sodass die Beilagenfächer Quasi über Nacht nicht entleert werden.
394:                 //                return this.eintraege.entrySet().stream()
395:                 //                                .map(Map.Entry::getValue)
396:                 //                                .flatMap(Set::stream)
397:                 //                                .filter(eintrag -> eintrag.getBis().isBefore(zeitpunkt))
398:                 //                                .max(Comparator.comparing(KalenderEintrag::getBis));
399:         }
400: }