Пример #1
0
        public Arbeitswoche CreateArbeitswoche(int jahr, int woche)
        {
            var aw = new Arbeitswoche(jahr, woche);

            var montag = DateTimeExtensions.FirstDateOfWeekIso8601(jahr, woche);

            aw.Arbeitstage.Add(new Arbeitstag(montag));
            aw.Arbeitstage.Add(new Arbeitstag(montag.AddDays(1)));
            aw.Arbeitstage.Add(new Arbeitstag(montag.AddDays(2)));
            aw.Arbeitstage.Add(new Arbeitstag(montag.AddDays(3)));
            aw.Arbeitstage.Add(new Arbeitstag(montag.AddDays(4)));
            aw.Arbeitstage.Add(new Arbeitstag(montag.AddDays(5)));
            aw.Arbeitstage.Add(new Arbeitstag(montag.AddDays(6)));

            return(aw);
        }
Пример #2
0
        public static AuswertungViewmodel ValidateArbeitswoche(this Arbeitswoche woche)
        {
            //frei nicht weniger als tagessatz
            //Nicht weniger als 4h
            //1 Frühdienst
            //1 8Uhr Dienst
            //2 Spätdienst
            //16Uhr Dienst

            //Kernzeit 1MA 8:30-15:30
            //Kernzeit 2MA 9:00-13:00

            var result = new AuswertungViewmodel();

            foreach (var arbeitstag in woche.Arbeitstage)
            {
                //Samstag und Sontag ignorieren bei Planung
                if (arbeitstag.Datum.DayOfWeek == DayOfWeek.Saturday || arbeitstag.Datum.DayOfWeek == DayOfWeek.Sunday)
                {
                    continue;
                }

                var aa = new ArbeitstagAuswertung {
                    Wochentag = arbeitstag.Wochentag
                };

                if (!arbeitstag.IsFeiertag)
                {
                    #region Frühdienst

                    var obGenauEinFrühdienst = arbeitstag.Planzeiten.Where(x => x.Dienst == DienstTyp.Frühdienst && x.Zeitraum.Start == x.Arbeitstag.Frühdienst).ToList();
                    if (obGenauEinFrühdienst.Count != 1)
                    {
                        var keinMehr = obGenauEinFrühdienst.Count == 0 ? "Kein" : "Mehr als ein";
                        var msg      = $"{keinMehr} {DienstTyp.Frühdienst.GetDisplayname()} geplant für {arbeitstag.Frühdienst.ToString("HH:mm")}Uhr.";
                        var v        = new ValidationMessage()
                        {
                            Message = msg
                        };
                        aa.Messages.Add(v);
                    }
                    #endregion

                    #region Spätdienst

                    var obGenauZweiSpätdienste = arbeitstag.Planzeiten.Where(x => x.Dienst == DienstTyp.SpätdienstEnde && x.Zeitraum.End == x.Arbeitstag.SpätdienstEnde).ToList();
                    if (obGenauZweiSpätdienste.Count != 2)
                    {
                        var keinMehr = obGenauEinFrühdienst.Count == 0 ? "Kein" : obGenauEinFrühdienst.Count == 1 ? "Nur ein" : "Mehr als ein";
                        var msg      = $"{keinMehr} {DienstTyp.SpätdienstEnde.GetDisplayname()} geplant bis {arbeitstag.SpätdienstEnde.ToString("HH:mm")}Uhr.";
                        var v        = new ValidationMessage()
                        {
                            Message = msg
                        };
                        aa.Messages.Add(v);
                    }
                    #endregion

                    #region 8Uhr Dienst

                    var obGenauEin8Uhrdienst = arbeitstag.Planzeiten.Where(x => x.Dienst == DienstTyp.AchtUhrDienst && x.Zeitraum.HasInside(x.Arbeitstag.AchtUhrDienst)).ToList();
                    if (obGenauEin8Uhrdienst.Count == 0)
                    {
                        var msg = $"Kein {DienstTyp.AchtUhrDienst.GetDisplayname()} geplant für {arbeitstag.AchtUhrDienst.ToString("HH:mm")}Uhr.";
                        var v   = new ValidationMessage()
                        {
                            Message = msg
                        };
                        aa.Messages.Add(v);
                    }
                    #endregion

                    #region 16Uhr Dienst

                    var obGenauEin16Uhrdienst = arbeitstag.Planzeiten.Where(x => x.Dienst == DienstTyp.SechszehnUhrDienst && x.Zeitraum.End == x.Arbeitstag.SechzehnUhrDienst).ToList();
                    if (!arbeitstag.HasGrossteam && obGenauEin16Uhrdienst.Count == 0)
                    {
                        var msg = $"Kein {DienstTyp.SechszehnUhrDienst.GetDisplayname()} geplant bis {arbeitstag.SechzehnUhrDienst.ToString("HH:mm")}Uhr.";
                        var v   = new ValidationMessage()
                        {
                            Message = msg
                        };
                        aa.Messages.Add(v);
                    }
                    #endregion

                    #region Kernzeit
                    var gruppen =
                        arbeitstag.Planzeiten.Where(x => x.Gruppe != GruppenTyp.None)
                        .GroupBy(x => x.Gruppe)
                        .ToList();

                    foreach (var gruppe in gruppen)
                    {
                        if (!arbeitstag.CheckKernzeitAbgedeckt(gruppe.Key))
                        {
                            var zeitraum = $"{arbeitstag.KernzeitBasisRange.Start.ToString("HH:mm")}-{arbeitstag.KernzeitBasisRange.End.ToString("HH:mm")}";
                            var msg      = $"Gruppe: {gruppe.Key.GetDisplayname()} Kernzeit  ({zeitraum}) nicht abgedeckt";
                            var v        = new ValidationMessage()
                            {
                                Message = msg
                            };
                            aa.Messages.Add(v);
                        }
                        else if (!arbeitstag.CheckKernzeitDoppelBesetzungAbgedeckt(gruppe.Key))
                        {
                            var doppelzeitraum = $"{arbeitstag.KernzeitDoppelBesetzungRange.Start.ToString("HH:mm")}-{arbeitstag.KernzeitDoppelBesetzungRange.End.ToString("HH:mm")}";
                            var msgDoppel      = $"Gruppe: {gruppe.Key.GetDisplayname()} Doppelbesetzung ({doppelzeitraum}) nicht abgedeckt.";
                            var vDoppel        = new ValidationMessage()
                            {
                                Message = msgDoppel
                            };
                            aa.Messages.Add(vDoppel);
                        }
                    }
                    #endregion

                    #region Check Mindestarbeitszeit
                    var mindestArbeitszeiten =
                        arbeitstag.Planzeiten.Where(
                            x => x.Dienst != DienstTyp.Frei && !x.Zeitraum.Duration.IsMindestzeitAbgedeckt()).ToList();

                    foreach (var planItem in mindestArbeitszeiten)
                    {
                        var planstunden = (planItem.GetArbeitsminutenAmKindOhnePause() / 60).ToString("#.##");
                        var msg         = $"{planItem.ErledigtDurch?.Name}: Mindestarbeitzeit nicht abgedeckt {planItem.GetArbeitsminutenAmKindOhnePause()}Minuten ({planstunden}h).";
                        var v           = new ValidationMessage()
                        {
                            Message = msg
                        };
                        aa.Messages.Add(v);
                    }
                    #endregion
                }

                #region Check Frei Tagessollsatz
                var wenigerZeitAlsFreiTagessatz =
                    arbeitstag.Planzeiten.Where(
                        x => x.Dienst == DienstTyp.Frei && x.GetArbeitsminutenAmKindOhnePause() < x.ErledigtDurch.TagesSollMinuten).ToList();

                foreach (var planItem in wenigerZeitAlsFreiTagessatz)
                {
                    var planstunden = (planItem.GetArbeitsminutenAmKindOhnePause() / 60).ToString("#.##");
                    var msg         = $"{planItem.ErledigtDurch.Name}: Dienst Frei geplant mit {planItem.GetArbeitsminutenAmKindOhnePause()}Minuten ({planstunden}h). Tagessatz: {planItem.ErledigtDurch.TagesSollMinuten}Minuten";
                    var v           = new ValidationMessage()
                    {
                        Message = msg
                    };
                    aa.Messages.Add(v);
                }
                #endregion


                if (aa.Messages.Count > 0)
                {
                    result.Auswertungen.Add(aa);
                }
                else
                {
                    aa.Messages.Add(new ValidationMessage()
                    {
                        Message = "Alles Prima :)"
                    });
                    result.Auswertungen.Add(aa);
                }
            }

            return(result);
        }
Пример #3
0
        private static void NichtVerplanteZeitenPlanen(Arbeitswoche woche)
        {
            var mitarbeiterPlanzeiten =
                woche.Arbeitstage
                .SelectMany(x => x.Planzeiten)
                .GroupBy(x => x.ErledigtDurch)
                .ToDictionary(x => x.Key, x => x.ToList());

            foreach (var mapl in mitarbeiterPlanzeiten)
            {
                var kfz       = (int)(mapl.Key.KindFreieZeit * 60);
                var grossteam = mapl.Value.Where(x => x.HatGrossteam).Select(x => x.Arbeitstag.Grossteam).Sum(s => (int)s.Duration.TotalMinutes);
                var wochenstundenAngeordnet = (int)(mapl.Key.WochenStunden * 60);
                var geplant = mapl.Value.Sum(x => (int)x.GetArbeitsminutenAmKindOhnePause());
                var saldo   = geplant + kfz + grossteam - wochenstundenAngeordnet;

                if (saldo < 15 && saldo > -15)
                {
                    continue;
                }

                if (saldo >= 15)
                {
                    var aufzuteilenMin = (int)(saldo);

                    if (aufzuteilenMin < 15)
                    {
                        continue;
                    }


                    aufzuteilenMin = ((int)aufzuteilenMin / 15) * 15;
                    var tage = mapl.Value.Count(x => (x.Dienst & DienstTyp.Frei) != DienstTyp.Frei);

                    if (tage == 0)
                    {
                        continue;
                    }

                    var tagAufteilung = ((int)((int)(aufzuteilenMin / tage)) / 15) * 15;

                    //1. Kleine Zeiten auf alle Teile
                    foreach (var planItem in mapl.Value)
                    {
                        if ((planItem.Dienst & DienstTyp.Frei) == DienstTyp.Frei)
                        {
                            continue;
                        }

                        var aufteilen = 15;
                        while (aufteilen <= tagAufteilung)
                        {
                            if (PlanzeitReduzierenOhneKernzeitVerletzung(planItem, 15))
                            {
                                aufzuteilenMin -= 15;
                            }
                            else
                            {
                                break;
                            }

                            aufteilen += 15;
                        }
                    }
                    //2. Rest irgendwie
                    foreach (var planItem in mapl.Value)
                    {
                        if ((planItem.Dienst & DienstTyp.Frei) == DienstTyp.Frei)
                        {
                            continue;
                        }

                        var aufteilen = aufzuteilenMin;
                        while (aufteilen > 0)
                        {
                            if (PlanzeitReduzierenOhneKernzeitVerletzung(planItem, 15))
                            {
                                aufzuteilenMin -= 15;
                                break;
                            }

                            aufteilen -= 15;
                        }
                    }
                }
            }
        }
Пример #4
0
        private static void CheckKernzeitAbgedecktMitMitarbeiternVomTag(Arbeitswoche woche)
        {
            var gruppen = woche.Mitarbeiter.Select(x => x.DefaultGruppe).Distinct().ToList();

            //prüfen ob alle Gruppen in der Kernzeit besetzt sind
            foreach (var arbeitstag in woche.Arbeitstage)
            {
                //Samstag und Sontag ignorieren bei Planung
                if (arbeitstag.Datum.DayOfWeek == DayOfWeek.Saturday ||
                    arbeitstag.Datum.DayOfWeek == DayOfWeek.Sunday ||
                    arbeitstag.IsFeiertag)
                {
                    continue;
                }

                foreach (var gruppe in gruppen)
                {
                    if (gruppe == GruppenTyp.None)
                    {
                        continue;
                    }

                    DateTime startzeit;
                    short    ticks;

                    if (!CheckKernzeitAbgedeckt(arbeitstag, gruppe, out startzeit, out ticks))
                    {
                        //beim Tag schauen in andern Gruppen
                        var wirHabenvlltZeit = arbeitstag.Planzeiten.Where(x => (x.ErledigtDurch.DefaultGruppe & gruppe) != gruppe && !x.ErledigtDurch.IsHelfer && !x.Dienst.HasFlag(DienstTyp.Frei))
                                               .GroupBy(g => g.Gruppe)
                                               .OrderByDescending(o => o.Count())
                                               .ToList();

                        foreach (var vllt in wirHabenvlltZeit)
                        {
                            if (vllt.Count() < 2)
                            {
                                continue;
                            }

                            var mitarbeiterDieInDerEigentlichenGruppeGebrauchtWerden = new List <Mitarbeiter>();
                            var nachDienstbegin = vllt.OrderBy(x => x.Zeitraum.Start);

                            var erster = nachDienstbegin.FirstOrDefault();

                            if (erster == null)
                            {
                                continue;
                            }

                            mitarbeiterDieInDerEigentlichenGruppeGebrauchtWerden.Add(erster.ErledigtDurch);
                            var bisAbgedeckt = erster.Zeitraum.End;

                            //gucken ohne Zeiten zu ändern
                            while (bisAbgedeckt < arbeitstag.KernzeitGruppeEnde)
                            {
                                var nächster = vllt.FirstOrDefault(x => !mitarbeiterDieInDerEigentlichenGruppeGebrauchtWerden.Contains(x.ErledigtDurch) &&
                                                                   x.Zeitraum.End >= arbeitstag.KernzeitGruppeEnde);

                                if (nächster == null)
                                {
                                    var alle = vllt.Where(x => !mitarbeiterDieInDerEigentlichenGruppeGebrauchtWerden.Contains(x.ErledigtDurch))
                                               .Select(x => x.ErledigtDurch);
                                    mitarbeiterDieInDerEigentlichenGruppeGebrauchtWerden.AddRange(alle);
                                    break;
                                }

                                mitarbeiterDieInDerEigentlichenGruppeGebrauchtWerden.Add(nächster.ErledigtDurch);
                                bisAbgedeckt = nächster.Zeitraum.End;
                            }

                            var kanditaten = vllt.Where(x => !mitarbeiterDieInDerEigentlichenGruppeGebrauchtWerden.Contains(x.ErledigtDurch)).ToList();

                            if (kanditaten.Count == 0)
                            {
                                continue;
                            }

                            var mindauer   = (int)(startzeit.AddMinutes(ticks) - startzeit).TotalMinutes;
                            var erstbesten = kanditaten.Where(x => x.Zeitraum.Duration.TotalMinutes >= mindauer && !x.Dienst.IstRandDienst()).OrderBy(x => x.Zeitraum.Start).FirstOrDefault()
                                             ?? kanditaten.Where(x => x.Zeitraum.Duration.TotalMinutes >= mindauer).OrderBy(x => x.Zeitraum.Start).FirstOrDefault();

                            if (erstbesten == null)
                            {
                                continue;
                            }

                            //Wenn nur randdienstler gefunden, dann darf der nicht "verschoben" werden in der Zeit
                            if (erstbesten.Dienst.IstRandDienst())
                            {
                                if (erstbesten.Zeitraum.Start > startzeit || erstbesten.Zeitraum.End < arbeitstag.KernzeitGruppeEnde)
                                {
                                    continue;
                                }
                            }

                            //einen Gefunden
                            var dauer = (int)(erstbesten.Zeitraum.Duration).TotalMinutes;
                            erstbesten.Gruppe = gruppe;

                            //wenn die Zeiten nicht passen, dann anpassen
                            if (erstbesten.Zeitraum.Start > startzeit)
                            {
                                erstbesten.Zeitraum.Start = startzeit;
                                erstbesten.Zeitraum.End   = startzeit.AddMinutes(dauer);
                            }

                            if (erstbesten.Zeitraum.End < arbeitstag.KernzeitGruppeEnde)
                            {
                                erstbesten.Zeitraum.End   = arbeitstag.KernzeitGruppeEnde;
                                erstbesten.Zeitraum.Start = arbeitstag.KernzeitGruppeEnde.AddMinutes(-1 * dauer);
                            }

                            break;
                        }
                    }
                }
            }
        }
Пример #5
0
        private static Mitarbeiter NextMitarbeiter(IList <Mitarbeiter> alleDieDaSind, IList <Mitarbeiter> schonEingeteilt, Arbeitstag arbeitstag, Arbeitswoche woche = null, DienstTyp ma4Diensttyp = DienstTyp.None, GruppenTyp etage = GruppenTyp.Gelb | GruppenTyp.Gruen | GruppenTyp.Nest | GruppenTyp.Rot)
        {
            var arbeitstagPlanzeiten = arbeitstag.Planzeiten.ToList();

            var topf = alleDieDaSind.Except(schonEingeteilt).Where(x => x.DefaultGruppe.IstFarbGruppe()).ToList();

            if (topf.Count == 0)
            {
                return(null);
            }

            //alle die nicht allein sind in der gruppe
            var sonderTopf  = topf.ToList();
            var mitarbeiter = new List <Mitarbeiter>();

            //Wenn RandDienst dann gilt erstmal die Wunschdienst REgel zwingend
            if (ma4Diensttyp.IstRandDienst())
            {
                mitarbeiter = sonderTopf = topf.Where(x => (x.Wunschdienste & ma4Diensttyp) == ma4Diensttyp).ToList();
            }

            //erstma gucken für die ganz RandRand Dienste
            //alle verfügbaren wo mehr als einer noch in der Gruppe ist
            //und in der Gruppe darf noch keiner einen RandRandDienst haben
            if (sonderTopf.Count == 0 && ma4Diensttyp.IstRandRandDienst())
            {
                sonderTopf = topf.GroupBy(x => x.DefaultGruppe).Where(x => x.Count() > 1)
                             .SelectMany(x => x.Where(ma => !arbeitstagPlanzeiten.Any(y => y.Gruppe == ma.DefaultGruppe && y.Dienst.IstRandRandDienst()))).ToList();
            }

            //dann gucken für die ganz Rand Dienste
            if (sonderTopf.Count == 0 && ma4Diensttyp.IstRandDienst())
            {
                sonderTopf = topf.GroupBy(x => x.DefaultGruppe).Where(x => x.Count() > 1)
                             .SelectMany(x => x.Where(ma => !arbeitstagPlanzeiten.Any(y => y.Gruppe == ma.DefaultGruppe && y.Dienst.IstRandDienst()))).ToList();
            }

            //Probieren einen zu Finden aus einer Gruppen die noch keinen Randdienst hat
            if (sonderTopf.Count == 0 && ma4Diensttyp.IstRandDienst())
            {
                sonderTopf = topf.GroupBy(x => x.DefaultGruppe)
                             .SelectMany(x => x.Where(ma => !arbeitstagPlanzeiten.Any(y => y.Gruppe == ma.DefaultGruppe && y.Dienst.IstRandDienst()))).ToList();
            }

            //die mit Wunschdienst aus Etage
            if (mitarbeiter.Count == 0)
            {
                mitarbeiter = sonderTopf.Where(x => (x.Wunschdienste & ma4Diensttyp) == ma4Diensttyp && (etage & x.DefaultGruppe) == x.DefaultGruppe).ToList();
            }

            //die von Etage
            if (mitarbeiter.Count == 0)
            {
                mitarbeiter = sonderTopf.Where(x => (etage & x.DefaultGruppe) == x.DefaultGruppe).ToList();
            }

            //Wunschdienst
            if (mitarbeiter.Count == 0)
            {
                mitarbeiter = sonderTopf.Where(x => (x.Wunschdienste & ma4Diensttyp) == ma4Diensttyp).ToList();
            }

            //Wenn mit der RandDienstlogik niemand gefunden wurde, dann vllt vorher nochmal schauen ob ein Wunschdienstler Lust hat
            if (mitarbeiter.Count == 0 && ma4Diensttyp.IstRandDienst())
            {
                sonderTopf = topf.Where(x => (x.Wunschdienste & ma4Diensttyp) == ma4Diensttyp).ToList();
            }

            if (mitarbeiter.Count == 0)
            {
                mitarbeiter = sonderTopf;
            }

            if (mitarbeiter.Count == 0)//bei allen gucken wenn keiner will
            {
                mitarbeiter = topf;
            }

            //RandDienste Gleichverteilen über die Woche
            if (woche != null && ma4Diensttyp.IstRandDienst())
            {
                var geplanteRanddienste        = woche.Arbeitstage.SelectMany(x => x.Planzeiten.Where(p => p.Dienst == ma4Diensttyp)).ToList();
                var mitarbeiterMitRanddiensten = geplanteRanddienste.Select(x => x.ErledigtDurch).Distinct().ToList();

                //irgendein Mitarbeiter da, der noch gar nix hat
                if (mitarbeiter.Except(mitarbeiterMitRanddiensten).Any())
                {
                    mitarbeiter = mitarbeiter.Except(mitarbeiterMitRanddiensten).ToList();
                }
                else
                {
                    var mitarbeiterMitAnzahlRanddienstInderWoche = geplanteRanddienste.GroupBy(g => g.ErledigtDurch).ToDictionary(x => x.Key, c => c.Count());
                    var minCount = mitarbeiterMitAnzahlRanddienstInderWoche.Min(x => x.Value);
                    var mitarbeiterMitWenigstenCounts = mitarbeiterMitAnzahlRanddienstInderWoche.Where(x => x.Value == minCount).Select(x => x.Key).ToList();
                    var mitarbeiterMitMehrcounts      = mitarbeiterMitAnzahlRanddienstInderWoche.Where(x => x.Value != minCount).Select(x => x.Key).ToList();

                    if (mitarbeiter.Intersect(mitarbeiterMitWenigstenCounts).Any())
                    {
                        mitarbeiter = mitarbeiter.Intersect(mitarbeiterMitWenigstenCounts).ToList();
                    }
                    else if (mitarbeiter.Except(mitarbeiterMitRanddiensten.Except(mitarbeiterMitMehrcounts)).Any())
                    {
                        mitarbeiter = mitarbeiter.Except(mitarbeiterMitRanddiensten.Except(mitarbeiterMitMehrcounts)).ToList();
                    }

                    //sofern noch einer übrig bleibt soll derjenige der am Vortag das gemacht, nicht nochmal dran sein
                    var vortag = woche.Arbeitstage.Single(x => x.Datum == arbeitstag.Datum.AddDays(-1));
                    var letzte = vortag?.Planzeiten?.Where(x => x.Dienst == ma4Diensttyp).Select(x => x.ErledigtDurch).ToList() ?? new List <Mitarbeiter>();

                    if (mitarbeiter.Except(letzte).Any())
                    {
                        mitarbeiter = mitarbeiter.Except(letzte).ToList();
                    }
                }

                //am gleichen Tag vllt nicht unbedingt auch noch aus der gleichen gruppe
                var ma4Gruppencheck  = arbeitstag.Planzeiten.Where(x => x.Dienst == ma4Diensttyp).Select(x => x.ErledigtDurch).ToList();
                var maGleicherGruppe = mitarbeiter.Where(x => ma4Gruppencheck.Any(m => m.DefaultGruppe == x.DefaultGruppe)).ToList();
                if (mitarbeiter.Except(maGleicherGruppe).Any())
                {
                    mitarbeiter = mitarbeiter.Except(maGleicherGruppe).ToList();
                }
            }

            int ichBinDran = Zufall.Next(0, mitarbeiter.Count);

#if DEBUG
            Console.WriteLine($"{ma4Diensttyp}: {ichBinDran} von {mitarbeiter.Count}");
#endif
            return(mitarbeiter[ichBinDran]);
        }
Пример #6
0
        public static void ErstelleWochenplan(Arbeitswoche woche, IList <Mitarbeiter> maList)
        {
            foreach (var item in woche.Arbeitstage)
            {
                item.Planzeiten.Clear();
            }

            foreach (var arbeitstag in woche.Arbeitstage)
            {
                //Samstag und Sontag ignorieren bei Planung
                if (arbeitstag.Datum.DayOfWeek == DayOfWeek.Saturday || arbeitstag.Datum.DayOfWeek == DayOfWeek.Sunday)
                {
                    continue;
                }

                if (arbeitstag.IsFeiertag)
                {
                    //Wenn Feiertag, dann seinen Tagessatz minutengenau
                    foreach (var mitarbeiter in maList)
                    {
                        arbeitstag.Planzeiten.Add(CreatePlanItem(arbeitstag, mitarbeiter, GruppenTyp.None, DienstTyp.Frei));
                    }
                    continue;
                }

                //Wenn wer nicht da ist, dann seinen Tagessatz minutengenau
                var mitarbeiterNichtDa = maList.Where(x => x.NichtDaZeiten.Any(dt => dt == arbeitstag.Datum)).ToList();
                foreach (var mitarbeiter in mitarbeiterNichtDa)
                {
                    arbeitstag.Planzeiten.Add(CreatePlanItem(arbeitstag, mitarbeiter, GruppenTyp.None, DienstTyp.Frei));
                }

                //Nur richtige Mitarbeiter die auch da sind
                var alledieDaSind = maList.Where(x => !x.NichtDaZeiten.Any(dt => dt == arbeitstag.Datum) && !x.IsHelfer).ToList();

                var schonEingeteilt = new List <Mitarbeiter>();

                #region Frühdienst

                var maFrüh = NextMitarbeiter(alledieDaSind, schonEingeteilt, arbeitstag, woche, DienstTyp.Frühdienst);
                if (maFrüh != null)
                {
                    schonEingeteilt.Add(maFrüh);
                    var istFrüh = CreatePlanItem(arbeitstag, maFrüh, maFrüh.DefaultGruppe, DienstTyp.Frühdienst);
                    arbeitstag.Planzeiten.Add(istFrüh);
                }

                #endregion

                #region Spätdienst 2Mitarbeiter

                var maSpät1 = NextMitarbeiter(alledieDaSind, schonEingeteilt, arbeitstag, woche, DienstTyp.SpätdienstEnde);

                if (maSpät1 != null)
                {
                    schonEingeteilt.Add(maSpät1);
                    var istSpät1 = CreatePlanItem(arbeitstag, maSpät1, maSpät1.DefaultGruppe, DienstTyp.SpätdienstEnde);
                    arbeitstag.Planzeiten.Add(istSpät1);
                }

                var maSpät2 = NextMitarbeiter(alledieDaSind, schonEingeteilt, arbeitstag, woche, DienstTyp.SpätdienstEnde, GibAndereEtage(maSpät1));

                if (maSpät2 != null)
                {
                    schonEingeteilt.Add(maSpät2);
                    var istSpät2 = CreatePlanItem(arbeitstag, maSpät2, maSpät2.DefaultGruppe, DienstTyp.SpätdienstEnde);
                    arbeitstag.Planzeiten.Add(istSpät2);
                }

                #endregion

                #region 8 uhr Dienst

                var ma8UhrErster = NextMitarbeiter(alledieDaSind, schonEingeteilt, arbeitstag, woche, DienstTyp.AchtUhrDienst, GibAndereEtage(maFrüh));
                if (ma8UhrErster != null)
                {
                    schonEingeteilt.Add(ma8UhrErster);
                    var ist8UhrErster = CreatePlanItem(arbeitstag, ma8UhrErster, ma8UhrErster.DefaultGruppe, DienstTyp.AchtUhrDienst);
                    arbeitstag.Planzeiten.Add(ist8UhrErster);
                }

                #endregion

                #region 16 Uhr Dienst

                if (!arbeitstag.HasGrossteam)
                {
                    var ma16Uhr = NextMitarbeiter(alledieDaSind, schonEingeteilt, arbeitstag, woche, DienstTyp.SechszehnUhrDienst);

                    if (ma16Uhr != null)
                    {
                        schonEingeteilt.Add(ma16Uhr);
                        var ist16Uhr = CreatePlanItem(arbeitstag, ma16Uhr, ma16Uhr.DefaultGruppe, DienstTyp.SechszehnUhrDienst);
                        arbeitstag.Planzeiten.Add(ist16Uhr);
                    }
                }

                #endregion

                #region Gruppendienste

                var restMas = alledieDaSind.Where(x => !schonEingeteilt.Contains(x)).ToList();

                var nestMas = restMas.Where(x => x.DefaultGruppe.HasFlag(GruppenTyp.Nest)).ToList();
                FillGruppenDiensteMitKernzeitPrio(nestMas, arbeitstag, GruppenTyp.Nest, schonEingeteilt);

                var blauMas = restMas.Where(x => x.DefaultGruppe.HasFlag(GruppenTyp.Gelb)).ToList();
                FillGruppenDiensteMitKernzeitPrio(blauMas, arbeitstag, GruppenTyp.Gelb, schonEingeteilt);

                var gruenMas = restMas.Where(x => x.DefaultGruppe.HasFlag(GruppenTyp.Gruen)).ToList();
                FillGruppenDiensteMitKernzeitPrio(gruenMas, arbeitstag, GruppenTyp.Gruen, schonEingeteilt);

                var rotMas = restMas.Where(x => x.DefaultGruppe.HasFlag(GruppenTyp.Rot)).ToList();
                FillGruppenDiensteMitKernzeitPrio(rotMas, arbeitstag, GruppenTyp.Rot, schonEingeteilt);

                var rest = alledieDaSind.Where(x => !schonEingeteilt.Contains(x)).ToList();
                foreach (var mitarbeiter in rest)
                {
                    arbeitstag.Planzeiten.Add(CreatePlanItem(arbeitstag, mitarbeiter, GruppenTyp.None, DienstTyp.KernzeitStartDienst));
                }

                #endregion

                #region FSJ Dienste

                var helferleins = maList.Where(x => !x.NichtDaZeiten.Any(dt => dt == arbeitstag.Datum) && x.IsHelfer).ToList();

                //Frühdienst
                if (!arbeitstag.HasGrossteam)
                {
                    var h1 = NextMitarbeiter(helferleins, schonEingeteilt, arbeitstag, woche, DienstTyp.FsjFrühdienst);

                    if (h1 != null)
                    {
                        schonEingeteilt.Add(h1);
                        var h1Früh = CreatePlanItem(arbeitstag, h1, h1.DefaultGruppe, DienstTyp.FsjFrühdienst);
                        arbeitstag.Planzeiten.Add(h1Früh);
                    }

                    var h2 = NextMitarbeiter(helferleins, schonEingeteilt, arbeitstag, woche, DienstTyp.FsjSpätdienst);

                    if (h2 != null)
                    {
                        schonEingeteilt.Add(h2);
                        var h2Früh = CreatePlanItem(arbeitstag, h2, h2.DefaultGruppe, DienstTyp.FsjSpätdienst);
                        arbeitstag.Planzeiten.Add(h2Früh);
                    }


                    foreach (var helferlein in helferleins.Except(schonEingeteilt).ToList())
                    {
                        schonEingeteilt.Add(helferlein);
                        var h = CreatePlanItem(arbeitstag, helferlein, helferlein.DefaultGruppe, DienstTyp.FsjKernzeitdienst);
                        arbeitstag.Planzeiten.Add(h);
                    }
                }
                else
                {
                    foreach (var helferlein in helferleins.Except(schonEingeteilt).ToList())
                    {
                        schonEingeteilt.Add(helferlein);
                        var hSpät = CreatePlanItem(arbeitstag, helferlein, helferlein.DefaultGruppe, DienstTyp.FsjSpätdienst);
                        arbeitstag.Planzeiten.Add(hSpät);
                    }
                }

                #endregion
            }

            CheckKernzeitAbgedecktMitMitarbeiternVomTag(woche);

            NichtVerplanteZeitenPlanen(woche);
        }
Пример #7
0
        public MemoryStream SchreibeIstZeiten(Arbeitswoche woche, IList <Mitarbeiter> mitarbeiters, bool showThemen = false)
        {
            ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
            using (var xls = new ExcelPackage())
            {
                var ws = xls.Workbook.Worksheets.Add($"Woche {woche.KalenderWoche}");
                ws.Workbook.CalcMode = ExcelCalcMode.Automatic;
                ws.Cells["A:XFD"].Style.Font.Name = "Consolas";


                var row = 1;
                ws.Cells[row, 1, 1, 9].Merge            = true;
                ws.Cells[row, 1].Value                  = $"Arbeitswoche:  {woche.KalenderWoche}  vom {woche.Arbeitstage.First().Datum.ToString("dd.MM.yyyy")} bis {woche.Arbeitstage.Last().Datum.ToString("dd.MM.yyyy")}";
                ws.Cells[row, 1, 1, 13].Style.Font.Bold = true;

                row++;
                row++;
                for (int i = 0; i < woche.Arbeitstage.Count; i++)
                {
                    var datum = woche.Arbeitstage[i].Datum;
                    if (datum.DayOfWeek == DayOfWeek.Saturday || datum.DayOfWeek == DayOfWeek.Sunday)
                    {
                        continue;
                    }

                    int col = i + 2;
                    ws.Cells[row, col].Value = datum.GetWochentagName();
                }

                var colAngeordneteStunden = 7;
                ws.Cells[row, colAngeordneteStunden].Value = "ang. Std.";
                ws.Cells[row, colAngeordneteStunden].Style.HorizontalAlignment = ExcelHorizontalAlignment.Center;

                var colKfz = 8;
                ws.Cells[row, colKfz].Value = "KFZ";
                ws.Cells[row, colKfz].Style.HorizontalAlignment = ExcelHorizontalAlignment.Center;

                var sortedMa = mitarbeiters.OrderBy(x => x.DefaultGruppe).ThenBy(x => x.IsHelfer).ThenBy(x => x.Name).ToList();
                for (int i = 0; i < mitarbeiters.Count; i++)
                {
                    row++;
                    var obThemenRow = false;
                    var ma          = sortedMa[i];
                    ws.Cells[row, 1].Value = ma.Name;

                    var color = ma.DefaultGruppe.GetFarbeFromResources();
                    ws.Cells[row, 1].Style.Fill.PatternType = ExcelFillStyle.Solid;
                    ws.Cells[row, 1].Style.Fill.BackgroundColor.SetColor(System.Drawing.Color.FromArgb(color.Color.A, color.Color.R, color.Color.G, color.Color.B));

                    if (showThemen && woche.Arbeitstage.Any(a => a.Planzeiten.Any(x => x.ErledigtDurch.Name == ma.Name && x.Thema != Themen.None)))
                    {
                        ws.Cells[row + 1, 1].Style.Fill.PatternType = ExcelFillStyle.Solid;
                        ws.Cells[row + 1, 1].Style.Fill.BackgroundColor.SetColor(System.Drawing.Color.FromArgb(color.Color.A, color.Color.R, color.Color.G, color.Color.B));
                    }

                    for (int j = 0; j < woche.Arbeitstage.Count; j++)
                    {
                        var tag = woche.Arbeitstage[j];

                        //var tmp =mitarbeiters.SingleOrDefault(x => x.Name == "Robert");
                        //if (tag.Datum == new DateTime(2020, 7, 3) && tag.Planzeiten.Any(x=>x.ErledigtDurch==null))
                        //{
                        //    var pp = tag.Planzeiten.Where(x => x.ErledigtDurch == null);
                        //    pp.First().ErledigtDurch = tmp;
                        //}

                        foreach (var zeiten in tag.Planzeiten.Where(x => x.ErledigtDurch.Name == ma.Name))
                        {
                            if (zeiten.Dienst == DienstTyp.Frei)
                            {
                                continue;
                            }

                            ws.Cells[row, j + 2].Value = zeiten.GetInfoPlanzeitInfo(true);

                            var c = zeiten.Gruppe != zeiten.ErledigtDurch.DefaultGruppe ? zeiten.Gruppe.GetFarbeFromResources() : zeiten.Dienst.GetFarbeFromResources();
                            ws.Cells[row, j + 2].Style.Fill.PatternType = ExcelFillStyle.Solid;
                            ws.Cells[row, j + 2].Style.Fill.BackgroundColor.SetColor(System.Drawing.Color.FromArgb(c.Color.A, c.Color.R, c.Color.G, c.Color.B));

                            //if ((zeiten.Dienst & DienstTyp.Frühdienst)== DienstTyp.Frühdienst
                            //    || (zeiten.Dienst & DienstTyp.SpätdienstEnde) == DienstTyp.SpätdienstEnde)
                            //    ws.Cells[row, j + 2].Style.Font.Bold = true;

                            if (showThemen && zeiten.Thema != Themen.None)
                            {
                                ws.Cells[row + 1, j + 2].Value = zeiten.Thema.GetDisplayname();
                                obThemenRow = true;
                            }
                        }
                    }

                    ws.Cells[row, colAngeordneteStunden].Value = ma.WochenStunden;
                    ws.Cells[row, colAngeordneteStunden].Style.HorizontalAlignment = ExcelHorizontalAlignment.Center;

                    ws.Cells[row, colKfz].Value = ma.KindFreieZeit;
                    ws.Cells[row, colKfz].Style.HorizontalAlignment = ExcelHorizontalAlignment.Center;

                    var oben = ws.Cells[row, 1, row, 8];
                    oben.Style.Border.Top.Style   = ExcelBorderStyle.Thin;
                    oben.Style.Border.Left.Style  = ExcelBorderStyle.Thin;
                    oben.Style.Border.Right.Style = ExcelBorderStyle.Thin;

                    if (obThemenRow)
                    {
                        row++;
                    }

                    var unten = ws.Cells[row, 1, row, 8];
                    unten.Style.Border.Left.Style   = ExcelBorderStyle.Thin;
                    unten.Style.Border.Right.Style  = ExcelBorderStyle.Thin;
                    unten.Style.Border.Bottom.Style = ExcelBorderStyle.Thin;
                }

                if (woche.Arbeitstage.Any(x => x.HasGrossteam))
                {
                    row++;
                    row++;
                    var gts = woche.Arbeitstage.Where(x => x.HasGrossteam).ToList();

                    foreach (var at in gts)
                    {
                        var index = woche.Arbeitstage.IndexOf(at);
                        ws.Cells[row, index + 2].Value           = $"Großteam {Environment.NewLine}{at.Grossteam.Start.ToString("HH:mm")}-{at.Grossteam.End.ToString("HH:mm")}";
                        ws.Cells[row, index + 2].Style.Font.Bold = true;
                        ws.Cells[row, index + 2].Style.WrapText  = true;

                        var border = ws.Cells[row, index + 2];
                        border.Style.Border.Top.Style    = ExcelBorderStyle.Thin;
                        border.Style.Border.Left.Style   = ExcelBorderStyle.Thin;
                        border.Style.Border.Right.Style  = ExcelBorderStyle.Thin;
                        border.Style.Border.Bottom.Style = ExcelBorderStyle.Thin;
                    }
                }



                ws.Cells.AutoFitColumns();
                ws.View.ShowGridLines = false;

                var ms = new MemoryStream();
                xls.SaveAs(ms);

                return(ms);
            }
        }
Пример #8
0
        public static ArbeitswocheViewmodel MapArbeitswocheToViewmodel(this Arbeitswoche aw)
        {
            var msgService = new WpfMessageBoxService();
            var vm         = new ArbeitswocheViewmodel(aw.Jahr, aw.KalenderWoche);

            vm.Mitarbeiter = new List <MitarbeiterViewmodel>(aw.Mitarbeiter.Select(x => x.MapMitarbeiterToViewmodel()));

            vm.Montag = new ArbeitstagWrapper(msgService)
            {
                Arbeitstag = aw.Arbeitstage.Single(x => x.Datum.DayOfWeek == DayOfWeek.Monday)
            };
            vm.Dienstag = new ArbeitstagWrapper(msgService)
            {
                Arbeitstag = aw.Arbeitstage.Single(x => x.Datum.DayOfWeek == DayOfWeek.Tuesday)
            };
            vm.Mittwoch = new ArbeitstagWrapper(msgService)
            {
                Arbeitstag = aw.Arbeitstage.Single(x => x.Datum.DayOfWeek == DayOfWeek.Wednesday)
            };
            vm.Donnerstag = new ArbeitstagWrapper(msgService)
            {
                Arbeitstag = aw.Arbeitstage.Single(x => x.Datum.DayOfWeek == DayOfWeek.Thursday)
            };
            vm.Freitag = new ArbeitstagWrapper(msgService)
            {
                Arbeitstag = aw.Arbeitstage.Single(x => x.Datum.DayOfWeek == DayOfWeek.Friday)
            };

            vm.IsMontagFeiertag     = vm.Montag.Arbeitstag.IsFeiertag;
            vm.IsDienstagFeiertag   = vm.Dienstag.Arbeitstag.IsFeiertag;
            vm.IsMittwochFeiertag   = vm.Mittwoch.Arbeitstag.IsFeiertag;
            vm.IsDonnerstagFeiertag = vm.Donnerstag.Arbeitstag.IsFeiertag;
            vm.IsFreitagFeiertag    = vm.Freitag.Arbeitstag.IsFeiertag;

            vm.HasMontagGrossteam     = vm.Montag.Arbeitstag.HasGrossteam;
            vm.HasDienstagGrossteam   = vm.Dienstag.Arbeitstag.HasGrossteam;
            vm.HasMittwochGrossteam   = vm.Mittwoch.Arbeitstag.HasGrossteam;
            vm.HasDonnerstagGrossteam = vm.Donnerstag.Arbeitstag.HasGrossteam;
            vm.HasFreitagGrossteam    = vm.Freitag.Arbeitstag.HasGrossteam;


            var pwmvms = new List <PlanungswocheMitarbeiterViewmodel>();

            foreach (var ma in vm.Mitarbeiter)
            {
                var pwmvm = new PlanungswocheMitarbeiterViewmodel()
                {
                    Mitarbeiter = ma
                };

                foreach (var arbeitstag in aw.Arbeitstage)
                {
                    var dow  = arbeitstag.Datum.DayOfWeek;
                    var ptvm = new PlanungstagViewmodel(ma, msgService, new Action(() => pwmvm.Refresh()))
                    {
                        Datum        = arbeitstag.Datum,
                        Planzeit     = arbeitstag.Planzeiten.SingleOrDefault(x => x.ErledigtDurch?.Name == ma.Name) ?? arbeitstag.EmptyPlanzeitOhneMitarbeiter,
                        IsFeiertag   = arbeitstag.IsFeiertag,
                        HasGrossteam = arbeitstag.HasGrossteam
                    };

                    switch (dow)
                    {
                    case DayOfWeek.Monday:
                        pwmvm.Montag = ptvm;
                        break;

                    case DayOfWeek.Tuesday:
                        pwmvm.Dienstag = ptvm;
                        break;

                    case DayOfWeek.Wednesday:
                        pwmvm.Mittwoch = ptvm;
                        break;

                    case DayOfWeek.Thursday:
                        pwmvm.Donnerstag = ptvm;
                        break;

                    case DayOfWeek.Friday:
                        pwmvm.Freitag = ptvm;
                        break;

                    case DayOfWeek.Saturday:

                        break;

                    case DayOfWeek.Sunday:

                        break;

                    default:
                        throw new ArgumentOutOfRangeException();
                    }
                }

                pwmvms.Add(pwmvm);
            }

            vm.PlanungProMitarbeiterListe = new List <PlanungswocheMitarbeiterViewmodel>(pwmvms);

            return(vm);
        }