Skip to contentMethod: getProduktionsAuftraegeMitFehlendenBelegungen()
      1: package simulation;
2: 
3: import auftraege.ProduktionsAuftrag;
4: import maschine.Maschine;
5: import material.Material;
6: import material.MaterialMitMessung;
7: import mensch.Mitarbeiter;
8: import rollenbelegung.ErmittelteBelegungen;
9: import util.Immutable;
10: import zeit.eintraege.MaschinenBelegungEintrag;
11: import zeit.eintraege.MenschBelegungEintrag;
12: 
13: import javax.measure.Quantity;
14: import java.util.Collection;
15: import java.util.Collections;
16: import java.util.List;
17: import java.util.Map;
18: import java.util.Objects;
19: import java.util.Optional;
20: import java.util.stream.Collectors;
21: 
22: /**
23:  * Das Ergebnis einer Prüfung auf die Korrektheit der Eingaben beim Simulationsalgorithmus.
24:  */
25: @Immutable
26: public final class PruefErgebnis {
27: 
28:     private final ErmittelteBelegungen gepruefteBelegungen;
29:         
30:         private final Collection<Mitarbeiter> ueberbuchteMitarbeiter;
31:         private final Collection<Maschine> ueberbuchteMaschinen;
32:         private final Collection<MenschBelegungEintrag> mitarbeiterbelegungenOhneMaschinenbelegung;
33:         private final Collection<MaschinenBelegungEintrag> maschinenbelegungenOhneMitarbeiterbelegung;
34:         private final Map<Mitarbeiter, Collection<MenschBelegungEintrag>> fehlendeFaehigkeitenFuerBelegungenProMitarbeiter;
35:         
36:         /**
37:          * Bei diesen Produktionsaufträgen wurde der zugehörige Prozesstyp mit den vorhandenen Belegungen nicht erfüllt.
38:          * D.h. eine passende Zuordnung von Maschinentypen und Rollen zu Maschinen und Personen konnte nicht gefunden werden.
39:          */
40:         private final Collection<ProduktionsAuftrag> produktionsAuftraegeMitFehlendenBelegungen;
41: 
42:     private final Collection<MaterialMitMessung<?>> verbrauchtesMaterial;
43:     private final Collection<MaterialMitMessung<?>> verfuegbaresMaterial;
44: 
45:     /**
46:      * Konstrukor mit allen Parametern.
47:      * @param ueberbuchteMitarbeiter ueberbuchteMitarbeiter
48:      * @param ueberbuchteMaschinen ueberbuchteMaschinen
49:      * @param mitarbeiterbelegungenOhneMaschinenbelegung mitarbeiterbelegungenOhneMaschinenbelegung
50:      * @param maschinenbelegungenOhneMitarbeiterbelegung maschinenbelegungenOhneMitarbeiterbelegung
51:      * @param fehlendeFaehigkeitenFuerBelegungenProMitarbeiter fehlendeFaehigkeitenFuerBelegungenProMitarbeiter
52:      * @param produktionsAuftraegeMitFehlendenBelegungen produktionsAuftraegeMitFehlendenBelegungen
53:      * @param verbrauchtesMaterial das durch die Produktion verbrauchte Material
54:      * @param verfuegbaresMaterial das für die Produktion verfügbare Material
55:      * @param gepruefteBelegungen die geprüfte Belegungen der Produktionsplanung
56:      */
57:     PruefErgebnis(final Collection<Mitarbeiter> ueberbuchteMitarbeiter,
58:                   final Collection<Maschine> ueberbuchteMaschinen,
59:                   final Collection<MenschBelegungEintrag> mitarbeiterbelegungenOhneMaschinenbelegung,
60:                   final Collection<MaschinenBelegungEintrag> maschinenbelegungenOhneMitarbeiterbelegung,
61:                   final Map<Mitarbeiter, Collection<MenschBelegungEintrag>> fehlendeFaehigkeitenFuerBelegungenProMitarbeiter,
62:                   final Collection<ProduktionsAuftrag> produktionsAuftraegeMitFehlendenBelegungen,
63:                   final Collection<MaterialMitMessung<?>> verbrauchtesMaterial,
64:                   final Collection<MaterialMitMessung<?>> verfuegbaresMaterial,
65:                   final ErmittelteBelegungen gepruefteBelegungen) {
66:         this.ueberbuchteMitarbeiter = ueberbuchteMitarbeiter;
67:         this.ueberbuchteMaschinen = ueberbuchteMaschinen;
68:         this.mitarbeiterbelegungenOhneMaschinenbelegung = mitarbeiterbelegungenOhneMaschinenbelegung;
69:         this.maschinenbelegungenOhneMitarbeiterbelegung = maschinenbelegungenOhneMitarbeiterbelegung;
70:         this.fehlendeFaehigkeitenFuerBelegungenProMitarbeiter = fehlendeFaehigkeitenFuerBelegungenProMitarbeiter;
71:         this.produktionsAuftraegeMitFehlendenBelegungen = produktionsAuftraegeMitFehlendenBelegungen;
72:         this.verbrauchtesMaterial = verbrauchtesMaterial;
73:         this.verfuegbaresMaterial = verfuegbaresMaterial;
74:         this.gepruefteBelegungen = gepruefteBelegungen;
75:     }
76: 
77: 
78: 
79:     /**
80:          *
81:          * @return Builder, um das PruefErgebnis komfortabler erstellen zu können.
82:          */
83:         static PruefErgebnisBuilder builder() {
84:                 return PruefErgebnisBuilder.create();
85:         }
86: 
87:     /**
88:      *
89:      * @return die geprüften Belegungen
90:      */
91:     public ErmittelteBelegungen getGepruefteBelegungen() {
92:         return this.gepruefteBelegungen;
93:     }
94: 
95:         /**
96:          *
97:          * @return produktionsAuftraegeMitFehlendenBelegungen read-only
98:          */
99:         public Collection<ProduktionsAuftrag> getProduktionsAuftraegeMitFehlendenBelegungen() {
100:                 return Collections.unmodifiableCollection(this.produktionsAuftraegeMitFehlendenBelegungen);
101:         }
102:         
103:         /**
104:          *
105:          * @return UeberbuchteMitarbeiter read-only
106:          */
107:         public Collection<Mitarbeiter> getUeberbuchteMitarbeiter() {
108:                 return Collections.unmodifiableCollection(this.ueberbuchteMitarbeiter);
109:         }
110:         
111:         /**
112:          *
113:          * @return UeberbuchteMaschinen read-only
114:          */
115:         public Collection<Maschine> getUeberbuchteMaschinen() {
116:                 return Collections.unmodifiableCollection(this.ueberbuchteMaschinen);
117:         }
118:         
119:         /**
120:          * derived.
121:          * @return true wenn die Eingaben der Simulation korrekt waren.
122:          */
123:         public boolean pruefungWarFehlerfrei() {
124:                 return  this.ueberBuchungLiegtNichtVor()
125:                                 && this.produktionsAuftraegeMitFehlendenBelegungen.isEmpty()
126:                                 && this.belegungenPassenZueinander()
127:                                 && this.fehlendeFaehigkeitenFuerBelegungenProMitarbeiter.isEmpty()
128:                 && this.istAusreichendMaterialVorhanden();
129:         }
130: 
131:         private boolean belegungenPassenZueinander() {
132:                 return this.mitarbeiterbelegungenOhneMaschinenbelegung.isEmpty()
133:                         && this.maschinenbelegungenOhneMitarbeiterbelegung.isEmpty();
134:         }
135: 
136:         private boolean ueberBuchungLiegtNichtVor() {
137:                 return this.ueberbuchteMaschinen.isEmpty()
138:                         && this.ueberbuchteMitarbeiter.isEmpty();
139:         }
140: 
141: 
142: 
143:         /**
144:          *
145:          * @return MitarbeiterbelegungenenOhneMaschinenbelegung read-only
146:          */
147:         public Collection<MenschBelegungEintrag> getMitarbeiterbelegungenOhneMaschinenbelegung() {
148:                 return Collections.unmodifiableCollection(this.mitarbeiterbelegungenOhneMaschinenbelegung);
149:         }
150:         /**
151:          *
152:          * @return MaschinenbelegungenenOhneMitarbeiterbelegung read-only
153:          */
154:         public Collection<MaschinenBelegungEintrag> getMaschinenbelegungenOhneMitarbeiterbelegung() {
155:                 return Collections.unmodifiableCollection(this.maschinenbelegungenOhneMitarbeiterbelegung);
156:         }
157:         
158:         /**
159:          * 
160:          * @return Belegungseinträge bei welchen der Mitarbeiter nicht die entsprechende Fähigkeit besitzt um diese Belegung durchzuführen.
161:          */
162:         public Map<Mitarbeiter, Collection<MenschBelegungEintrag>> getFehlendeFaehigkeitenFuerBelegungenProMitarbeiter() {
163:                 return Collections.unmodifiableMap(this.fehlendeFaehigkeitenFuerBelegungenProMitarbeiter);
164:         }
165: 
166:     /**
167:      *
168:      * @return verbrauchtesMaterial read-only
169:      */
170:     public Collection<MaterialMitMessung<?>> getVerbrauchtesMaterial() {
171:         return Collections.unmodifiableCollection(this.verbrauchtesMaterial);
172:     }
173: 
174:     /**
175:      *
176:      * @return verbrauchtesMaterial read-only
177:      */
178:     public Collection<MaterialMitMessung<?>> getVerfuegbaresMaterial() {
179:         return Collections.unmodifiableCollection(this.verfuegbaresMaterial);
180:     }
181: 
182:     /**
183:      * derived.
184:      * @return das für die Produktionsplanung fehlende Material.
185:      */
186:     public List<MaterialMitMessung<?>> getFehlendesMaterial() {
187:         return this.verbrauchtesMaterial.stream()
188:                 .map(einVerbrauchtesMaterial -> {
189:                     final Optional<MaterialMitMessung<?>> passendesMaterial = this.verfuegbaresMaterial.stream()
190:                             .filter(it -> it.getMaterial().equals(einVerbrauchtesMaterial.getMaterial()))
191:                             .findFirst();
192:                     if (!passendesMaterial.isPresent()) {
193:                         return einVerbrauchtesMaterial;
194:                     } else {
195:                         return this.bestimmeDifferenzDerMaterialien(einVerbrauchtesMaterial, passendesMaterial.get());
196:                     }
197:                 })
198:                 .filter(Objects::nonNull)
199:                 .collect(Collectors.toList());
200:     }
201: 
202:     private MaterialMitMessung<?> bestimmeDifferenzDerMaterialien(
203:             final MaterialMitMessung einVerbrauchtesMaterial,
204:             final MaterialMitMessung vorhandenesPassendesMaterial) {
205:         final Quantity<?> differenz = einVerbrauchtesMaterial.getMessung().subtract(vorhandenesPassendesMaterial.getMessung());
206:         if (differenz.getValue().doubleValue() > 0) {
207:             return MaterialMitMessung.create(vorhandenesPassendesMaterial.getMaterial(), differenz);
208:         }
209:         // Dies bedeutet es ist genug vom Material vorhanden. D.h. es wird nicht in die Liste der fehlenden Materialien aufgenommen
210:         // Nulls werden gefiltert.
211:         return null;
212:     }
213: 
214:     /**
215:      * derived.
216:      * @return true, wenn genug Material für die Produktion vorhanden ist.
217:      * Dies ist gleichbedeutend damit, dass es keine fehlenden Materialien gibt.
218:      */
219:     public boolean istAusreichendMaterialVorhanden() {
220:         return this.getFehlendesMaterial().isEmpty();
221:     }
222: 
223:     /**
224:      * derived.
225:      * Der Materialverbrauch pro Material wird auf den Materialverbrauch pro Typ umgerechnet und zurückgegeben.
226:      * @return den Materialverbrauch pro Materialtyp.
227:      */
228:     public Map<Class<? extends Material>, Quantity> getMaterialVerbrauchProMaterialKategorie() {
229:         final Map<Class<? extends Material>, Optional<Quantity>> messungenProMaterialTyp = this.getVerbrauchtesMaterial().stream()
230:                 .collect(Collectors.groupingBy(m -> m.getMaterial().getClass(),
231:                         Collectors.mapping(MaterialMitMessung::getMessung, Collectors.reducing(Quantity::add))));
232: 
233:         return messungenProMaterialTyp.entrySet().stream()
234:                 .collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().get()));
235:     }
236: 
237:     @Override
238:     public boolean equals(final Object o) {
239:         if (this == o) {
240:             return true;
241:         }
242:         if (!(o instanceof PruefErgebnis)) {
243:             return false;
244:         }
245:         final PruefErgebnis that = (PruefErgebnis) o;
246:         return com.google.common.base.Objects.equal(this.gepruefteBelegungen, that.gepruefteBelegungen)
247:                 && com.google.common.base.Objects.equal(this.ueberbuchteMitarbeiter, that.ueberbuchteMitarbeiter)
248:                 && com.google.common.base.Objects.equal(this.ueberbuchteMaschinen, that.ueberbuchteMaschinen)
249:                 && com.google.common.base.Objects.equal(this.mitarbeiterbelegungenOhneMaschinenbelegung, that.mitarbeiterbelegungenOhneMaschinenbelegung)
250:                 && com.google.common.base.Objects.equal(this.maschinenbelegungenOhneMitarbeiterbelegung, that.maschinenbelegungenOhneMitarbeiterbelegung)
251:                 && com.google.common.base.Objects.equal(this.fehlendeFaehigkeitenFuerBelegungenProMitarbeiter, that.fehlendeFaehigkeitenFuerBelegungenProMitarbeiter)
252:                 && com.google.common.base.Objects.equal(this.produktionsAuftraegeMitFehlendenBelegungen, that.produktionsAuftraegeMitFehlendenBelegungen)
253:                 && com.google.common.base.Objects.equal(this.verbrauchtesMaterial, that.verbrauchtesMaterial)
254:                 && com.google.common.base.Objects.equal(this.verfuegbaresMaterial, that.verfuegbaresMaterial);
255:     }
256: 
257:     @Override
258:     public int hashCode() {
259:         return com.google.common.base.Objects.hashCode(this.gepruefteBelegungen,
260:                 this.ueberbuchteMitarbeiter,
261:                 this.ueberbuchteMaschinen,
262:                 this.mitarbeiterbelegungenOhneMaschinenbelegung,
263:                 this.maschinenbelegungenOhneMitarbeiterbelegung,
264:                 this.fehlendeFaehigkeitenFuerBelegungenProMitarbeiter,
265:                 this.produktionsAuftraegeMitFehlendenBelegungen,
266:                 this.verbrauchtesMaterial,
267:                 this.verfuegbaresMaterial);
268:     }
269: }