Skip to content

Package: Schicht

Schicht

nameinstructionbranchcomplexitylinemethod
Schicht(Zeitraum, Map)
M: 0 C: 9
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 4
100%
M: 0 C: 1
100%
addProduktionsauftrag(ProduktionsAuftrag, Maschine, Fraction)
M: 0 C: 39
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 7
100%
M: 0 C: 1
100%
berechneBetriebsdauerDerMaschine(Maschine, Fraction)
M: 0 C: 29
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 5
100%
M: 0 C: 1
100%
copy()
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%
createOhneMaschinen(Zeitraum)
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%
equals(Object)
M: 4 C: 23
85%
M: 2 C: 4
67%
M: 2 C: 2
50%
M: 2 C: 6
75%
M: 0 C: 1
100%
getDokumentenklassen(Maschine)
M: 0 C: 23
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 5
100%
M: 0 C: 1
100%
getMaschinenProduktionsauftraegeMap()
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%
getMaschinentypen()
M: 0 C: 15
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 7
100%
M: 0 C: 1
100%
getProduktionsauftraege()
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%
getSchichtDauer()
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%
getZeitraum()
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%
hashCode()
M: 14 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 3 C: 0
0%
M: 1 C: 0
0%
lambda$berechneBetriebsdauerDerMaschine$1(Maschine)
M: 4 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%
lambda$getMaschinentypen$0(Map, MaschinenTyp)
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%
toString()
M: 17 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%

Coverage

1: package planung;
2:
3: import auftraege.Dokumentenklasse;
4: import auftraege.ProduktionsAuftrag;
5: import maschine.Maschine;
6: import maschine.MaschinenTyp;
7: import tec.uom.se.ComparableQuantity;
8: import tec.uom.se.quantity.Quantities;
9: import tec.uom.se.unit.Units;
10: import util.CollectionHelper;
11: import util.Constants;
12: import util.Fraction;
13: import zeit.eintraege.Zeitraum;
14:
15: import javax.measure.quantity.Time;
16: import java.util.ArrayList;
17: import java.util.Collection;
18: import java.util.Collections;
19: import java.util.HashMap;
20: import java.util.HashSet;
21: import java.util.Map;
22: import java.util.Optional;
23: import java.util.Set;
24: import java.util.stream.Collectors;
25:
26: /**
27: * Eine Schicht besteht aus einem Zeitraum (siehe {@link Schicht#zeitraum}), sowie einer Map von {@link Maschine Maschinen} auf eine Liste von {@link ProduktionsAuftrag
28: * Produktionsaufträgen} (siehe {@link Schicht#maschinenProduktionsauftraegeMap}).
29: */
30: public final class Schicht {
31:
32:         /**
33:          * Zeitraum, von wann bis wann die Schicht geht.
34:          */
35:         private final Zeitraum zeitraum;
36:
37:         private final Map<Maschine, Collection<ProduktionsAuftrag>> maschinenProduktionsauftraegeMap;
38:
39:
40:         private Schicht(final Zeitraum zeitraum, final Map<Maschine, Collection<ProduktionsAuftrag>> maschinenProduktionsauftraegeMap) {
41:                 this.zeitraum = zeitraum;
42:                 this.maschinenProduktionsauftraegeMap = maschinenProduktionsauftraegeMap;
43:         }
44:
45:         /**
46:          * Hier wird die Schicht erstellt, die einen konkreten Zeitraum und Maschinen erhält.
47:          *
48:          * @param zeitraum
49:          *                 der {@link Schicht#zeitraum Zeitraum} für die Schicht
50:          *
51:          * @return eine Schicht für den genannten Zeitraum, jedoch ohne Maschinen. Diese können mittels {@link Schicht#addProduktionsauftrag(ProduktionsAuftrag, Maschine,
52:          * Fraction)} hinzugefügt werden.
53:          */
54:         public static Schicht createOhneMaschinen(final Zeitraum zeitraum) {
55:                 return new Schicht(zeitraum, new HashMap<>());
56:         }
57:
58:         /**
59:          * @return liefert die Maschinentypen, welche in der Schicht benötigt werden, sowie zu jedem Maschinentypen eine Zahl, wie häufig dieser in der Schicht benötigt
60:          * wird.
61:          */
62:         public Map<MaschinenTyp, Integer> getMaschinentypen() {
63:                 final Map<MaschinenTyp, Integer> ret = new HashMap<>();
64:                 this.maschinenProduktionsauftraegeMap
65:                                 .keySet()
66:                                 .stream()
67:                                 .map(Maschine::getMaschinentyp)
68:                                 .forEach(maschinenTyp -> ret.put(maschinenTyp, Optional.ofNullable(ret.get(maschinenTyp)).orElse(0) + 1));
69:                 return ret;
70:         }
71:
72:         @Override
73:         public boolean equals(final Object o) {
74:•                if (this == o) {
75:                         return true;
76:                 }
77:•                if (!(o instanceof Schicht)) {
78:                         return false;
79:                 }
80:
81:                 final Schicht schicht = (Schicht) o;
82:
83:•                if (!this.zeitraum.equals(schicht.zeitraum)) {
84:                         return false;
85:                 }
86:                 return this.maschinenProduktionsauftraegeMap.equals(schicht.maschinenProduktionsauftraegeMap);
87:         }
88:
89:         @Override
90:         public int hashCode() {
91:                 int result = this.zeitraum.hashCode();
92:                 result = Constants.EINUNDDREISSIG * result + this.maschinenProduktionsauftraegeMap.hashCode();
93:                 return result;
94:         }
95:
96:         /**
97:          * @return liefert den Zeitraum der Schicht.
98:          */
99:         public Zeitraum getZeitraum() {
100:                 return this.zeitraum;
101:         }
102:
103:         /**
104:          * fügt, falls in der Schicht noch genügend Zeit für den ProduktionsAuftrag ist, diesen hinzu. ACHTUNG! hierbei findet keine Prüfung statt, ob der
105:          * Produktionsauftrag tatsächlich auch auf dieser Maschine bearbeitet werden kann!
106:          *
107:          * @param produktionsAuftrag
108:          *                 hinzuzufügender Produktionsauftrag.
109:          * @param maschine
110:          *                 maschine, auf die der Auftrag geplant wird.
111:          * @param produktionssatz
112:          *                 Produktionssatz, welcher zur Sicherheit gesetzt werden kann. Wenn er bei <b>100%</b> liegt, laufen sämtliche Maschinen auf voller Last. Um eine
113:          *                 Planungssicherheit einbauen zu können, kann der Satz beispielsweise auf <b>80%</b> festgelegt werden, um mit nur 80%igen Maschinengeschwindigkeiten zu
114:          *                 rechnen.
115:          *
116:          * @return <i>true</i>, falls der Auftrag hinzugefügt wurde, <i>false</i>, falls kein Platz mehr war.
117:          */
118:         public boolean addProduktionsauftrag(final ProduktionsAuftrag produktionsAuftrag, final Maschine maschine, final Fraction produktionssatz) {
119:                 this.maschinenProduktionsauftraegeMap.putIfAbsent(maschine, new ArrayList<>());
120:                 final ComparableQuantity<Time> betriebsdauer = this.berechneBetriebsdauerDerMaschine(maschine, produktionssatz);
121:                 final ComparableQuantity<Time> produktionsauftragsdauer = maschine.berechneBenoetigteZeit(produktionsAuftrag).multiply(produktionssatz.inversion());
122:•                if (betriebsdauer.add(produktionsauftragsdauer).compareTo(this.getSchichtDauer()) > 0) {
123:                         return false;
124:                 } else {
125:                         this.maschinenProduktionsauftraegeMap.get(maschine).add(produktionsAuftrag);
126:                         return true;
127:                 }
128:         }
129:
130:         /**
131:          * @param maschine
132:          *                 Maschine, deren Dokumentenklassen zurückgegeben werden sollen.
133:          *
134:          * @return liefert eine Liste sämtlicher Dokumentenklassen, die in den Produktionsaufträgen vorhanden sind, die der übergebenen Maschine zugeordnet wurden.
135:          */
136:         public Collection<Dokumentenklasse> getDokumentenklassen(final Maschine maschine) {
137:                 final Collection<ProduktionsAuftrag> produktionsauftraege = this.getMaschinenProduktionsauftraegeMap().get(maschine);
138:•                return produktionsauftraege == null
139:                                 ? new ArrayList<>()
140:                                 : produktionsauftraege
141:                                 .stream()
142:                                 .map(ProduktionsAuftrag::getDokumentenklassen)
143:                                 .reduce(new ArrayList<>(), CollectionHelper::concat);
144:         }
145:
146:         /**
147:          * @param maschine
148:          *                 Maschine deren Betriebsdauer in dieser Schicht berechnet werden soll.
149:          * @param produktionssatz
150:          *                 Produktionssatz, welcher zur Sicherheit gesetzt werden kann. Wenn er bei <b>100%</b> liegt, laufen sämtliche Maschinen auf voller Last. Um eine
151:          *                 Planungssicherheit einbauen zu können, kann der Satz beispielsweise auf <b>80%</b> festgelegt werden, um mit nur 80%igen Maschinengeschwindigkeiten zu
152:          *                 rechnen.
153:          *
154:          * @return liefert die gesamte Betriebsdauer der übergebenen Maschine mit allen ihren bereits zugeordneten Produktionsaufträgen dieser Schicht (siehe {@link
155:          * Schicht#maschinenProduktionsauftraegeMap})
156:          */
157:         public ComparableQuantity<Time> berechneBetriebsdauerDerMaschine(final Maschine maschine, final Fraction produktionssatz) {
158:                 this.maschinenProduktionsauftraegeMap.computeIfAbsent(maschine, k -> new HashSet<>());
159:                 return this.maschinenProduktionsauftraegeMap.get(maschine) //hole die Produktionsaufträge für die Maschine
160:                                 .stream().map(maschine::berechneBenoetigteZeit) //berechne die jeweils benötigte Zeit auf der Maschine
161:                                 .reduce(Quantities.getQuantity(0, Units.MINUTE), ComparableQuantity::add) //addiere sämtliche benötigten Zeiten zusammen
162:                                 .multiply(produktionssatz.inversion()); // multipliziere sie mit dem Kehrwert des Produktionssatzes, um die Sicherheit mit einzuberechnen.
163:         }
164:
165:         /**
166:          * @return liefert die Dauer der Schicht.
167:          */
168:         public ComparableQuantity<Time> getSchichtDauer() {
169:                 return this.zeitraum.getDauer();
170:         }
171:
172:         /**
173:          * @return sämtliche Produktionsaufträge, welche an den Maschinen dieser Schicht hängen. Die Aggregation erfolgt über ein Set, sodass Dopplungen nicht vorkommen.
174:          */
175:         public Set<ProduktionsAuftrag> getProduktionsauftraege() {
176:                 return this.maschinenProduktionsauftraegeMap.values().stream().flatMap(Collection::stream).collect(Collectors.toSet());
177:         }
178:
179:         /**
180:          * @return liefert die Liste der Maschinen der Schicht und die jeweiligen Produktionsaufträge, die ihnen zugeordnet sind.
181:          * @see Schicht#maschinenProduktionsauftraegeMap
182:          */
183:         public Map<Maschine, Collection<ProduktionsAuftrag>> getMaschinenProduktionsauftraegeMap() {
184:                 return Collections.unmodifiableMap(this.maschinenProduktionsauftraegeMap);
185:         }
186:
187:         @Override
188:         public String toString() {
189:                 return "Schicht{" + "zeitraum=" + this.zeitraum + ", auftraege=" + this.maschinenProduktionsauftraegeMap + '}';
190:         }
191:
192:
193:         /**
194:          * @return DeepCopy der Schicht.
195:          */
196:         public Schicht copy() {
197:                 return new Schicht(this.zeitraum, new HashMap<>(this.maschinenProduktionsauftraegeMap));
198:         }
199: }