Ejemplo n.º 1
0
 public static bool IstFarbGruppe(this GruppenTyp gruppe)
 {
     return((gruppe & GruppenTyp.Gelb) == GruppenTyp.Gelb ||
            (gruppe & GruppenTyp.Gruen) == GruppenTyp.Gruen ||
            (gruppe & GruppenTyp.Rot) == GruppenTyp.Rot ||
            (gruppe & GruppenTyp.Nest) == GruppenTyp.Nest);
 }
Ejemplo n.º 2
0
        private void ChangePlanGruppeCommandExecute(GruppenTyp gt)
        {
            if (!CanChangePlanGruppeCommandExecute(gt))
            {
                return;
            }

            Planzeit.Gruppe = gt;

            OnPropertyChanged(nameof(EingeteiltSollTyp));
            OnPropertyChanged(nameof(Planzeit));
        }
Ejemplo n.º 3
0
        /// <summary>
        ///    <SolidColorBrush x:Key="ColorGruppeGelb" Color="DarkGoldenrod"/>
        ///    <SolidColorBrush x:Key="ColorGruppeGruen" Color="LightGreen"/>
        ///    <SolidColorBrush x:Key="ColorGruppeRot" Color="LightCoral"/>
        ///    <SolidColorBrush x:Key="ColorGruppeNest" Color="LightBlue"/>
        /// </summary>
        /// <param name="gruppe"></param>
        /// <returns></returns>
        public static SolidColorBrush GetFarbeFromResources(this GruppenTyp gruppe)
        {
            var farbe = new SolidColorBrush();

            if (!gruppe.IstFarbGruppe())
            {
                return(farbe);
            }

            var key = "";

            switch (gruppe)
            {
            case GruppenTyp.Gelb:
                key = "ColorGruppeGelb";
                break;

            case GruppenTyp.Gruen:
                key = "ColorGruppeGruen";
                break;

            case GruppenTyp.Rot:
                key = "ColorGruppeRot";
                break;

            case GruppenTyp.Nest:
                key = "ColorGruppeNest";
                break;
            }

            try
            {
                var color = Application.Current.TryFindResource(key) as SolidColorBrush;

                if (color == null)
                {
                    return(farbe);
                }

                farbe = color;
                return(farbe);
            }
            catch
            {
                return(farbe);
            }
        }
Ejemplo n.º 4
0
        public static bool CheckKernzeitAbgedeckt(this Arbeitstag arbeitstag, GruppenTyp gruppe)
        {
            if (!gruppe.IstFarbGruppe())
            {
                return(true);
            }

            var gruppenzeiten = arbeitstag.GetMitarbeiterArbeitszeiten(gruppe);

            if (gruppenzeiten.Count == 0)
            {
                return(false);
            }

            var tp         = new TimePeriodCollection(gruppenzeiten);
            var obKernzeit = tp.HasInside(arbeitstag.KernzeitBasisRange);

            return(obKernzeit);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Per Definition gilt das wenn mindestens eine Planzeit existiert das diese die KernzeitStart erfüllt
        /// Per Definition in der Planung können keine Lücken in der Kernzeit entstehen
        /// </summary>
        /// <param name="arbeitstag"></param>
        /// <param name="gruppe"></param>
        /// <param name="startzeitNichtAbgedeckt"></param>
        /// <param name="ticksNichtAbgedeckt"></param>
        /// <returns></returns>
        private static bool CheckKernzeitAbgedeckt(Arbeitstag arbeitstag, GruppenTyp gruppe, out DateTime startzeitNichtAbgedeckt, out short ticksNichtAbgedeckt)
        {
            startzeitNichtAbgedeckt = arbeitstag.KernzeitGruppeStart;
            ticksNichtAbgedeckt     = (short)((arbeitstag.KernzeitGruppeEnde - arbeitstag.KernzeitGruppeStart).TotalMinutes / 15);

            if (!arbeitstag.CheckKernzeitAbgedeckt(gruppe))
            {
                var planzeiten    = new TimePeriodCollection(arbeitstag.GetMitarbeiterArbeitszeiten(gruppe));
                var gapCalculator = new TimeGapCalculator <TimeRange>(new TimeCalendar());
                var gap           = gapCalculator.GetGaps(planzeiten, arbeitstag.KernzeitBasisRange).FirstOrDefault();

                if (gap == null)
                {
                    return(false);
                }

                startzeitNichtAbgedeckt = gap.Start;
                ticksNichtAbgedeckt     = (short)(gap.Duration.TotalMinutes / 15);

                return(false);
            }
            return(true);
        }
Ejemplo n.º 6
0
        private static void FillGruppenDiensteMitKernzeitPrio(List <Mitarbeiter> maList, Arbeitstag arbeitstag, GruppenTyp gruppe, List <Mitarbeiter> schonEingeteilt)
        {
            if (!arbeitstag.Planzeiten.Any(x =>
                                           ((x.Dienst & DienstTyp.Frühdienst) == DienstTyp.Frühdienst ||
                                            (x.Dienst & DienstTyp.AchtUhrDienst) == DienstTyp.AchtUhrDienst ||
                                            (x.Dienst & DienstTyp.KernzeitStartDienst) == DienstTyp.KernzeitStartDienst) &&
                                           (x.Gruppe & gruppe) == gruppe &&
                                           !x.ErledigtDurch.IsHelfer))
            {
                var ma = NextMitarbeiter(maList, schonEingeteilt, arbeitstag, ma4Diensttyp: DienstTyp.KernzeitStartDienst);
                if (ma == null)
                {
                    return;
                }

                schonEingeteilt.Add(ma);
                var plan = CreatePlanItem(arbeitstag, ma, ma.DefaultGruppe, DienstTyp.KernzeitStartDienst);
                arbeitstag.Planzeiten.Add(plan);
            }
            //ab hier gibt es einen Frühen vogel :)

            DateTime startzeit;
            short    ticks;

            while (!CheckKernzeitAbgedeckt(arbeitstag, gruppe, out startzeit, out ticks))
            {
                var maKernzeitende = NextMitarbeiter(maList, schonEingeteilt, arbeitstag);
                if (maKernzeitende == null)
                {
                    return;
                }

                var kernzeitEndeStart = arbeitstag.KernzeitGruppeEnde.AddMinutes(-1 * 15 * maKernzeitende.TagesQuarterTicks);
                if (kernzeitEndeStart < startzeit)
                {
                    startzeit = kernzeitEndeStart;
                }

                schonEingeteilt.Add(maKernzeitende);
                var trMa             = new TimeRange(startzeit, startzeit.AddMinutes(15 * maKernzeitende.TagesQuarterTicks));
                var planKernzeitende = CreatePlanItem(arbeitstag, maKernzeitende, maKernzeitende.DefaultGruppe, DienstTyp.KernzeitEndeDienst, trMa);
                arbeitstag.Planzeiten.Add(planKernzeitende);
            }

            //ab hier gibts ein "Frühen Dienst" und wenn möglich ein Dienst bis Kernzeitende oder drüber
            var ma9 = NextMitarbeiter(maList, schonEingeteilt, arbeitstag, ma4Diensttyp: DienstTyp.NeunUhrDienst);

            if (ma9 == null)
            {
                return;
            }

            schonEingeteilt.Add(ma9);
            var plan9 = CreatePlanItem(arbeitstag, ma9, ma9.DefaultGruppe, DienstTyp.NeunUhrDienst);

            arbeitstag.Planzeiten.Add(plan9);

            var ma10 = NextMitarbeiter(maList, schonEingeteilt, arbeitstag, ma4Diensttyp: DienstTyp.ZehnUhrDienst);

            if (ma10 == null)
            {
                return;
            }

            schonEingeteilt.Add(ma10);
            var plan10 = CreatePlanItem(arbeitstag, ma10, ma10.DefaultGruppe, DienstTyp.ZehnUhrDienst);

            arbeitstag.Planzeiten.Add(plan10);

            //hmm wenn immernoch welche übrig sind dann, halt um 9Uhr kommen
            while (true)
            {
                var ma = NextMitarbeiter(maList, schonEingeteilt, arbeitstag, ma4Diensttyp: DienstTyp.NeunUhrDienst);
                if (ma == null)
                {
                    return;
                }

                schonEingeteilt.Add(ma);
                var plan = CreatePlanItem(arbeitstag, ma, ma.DefaultGruppe, DienstTyp.NeunUhrDienst);
                arbeitstag.Planzeiten.Add(plan);
            }
        }
Ejemplo n.º 7
0
        private static PlanItem CreatePlanItem(Arbeitstag arbeitstag, Mitarbeiter ma, GruppenTyp gruppe, DienstTyp dienst, TimeRange vorgabe = null)
        {
            #region Planzeit ausrechnen
            var duration = ma.TagesQuarterTicks * 15;
            var start    = arbeitstag.KernzeitGruppeStart;
            var ende     = arbeitstag.KernzeitGruppeEnde;

            switch (dienst)
            {
            case DienstTyp.Frühdienst:
                start = arbeitstag.Frühdienst;
                ende  = arbeitstag.Frühdienst.AddMinutes(duration);
                break;

            case DienstTyp.AchtUhrDienst:
                start = arbeitstag.AchtUhrDienst;
                ende  = arbeitstag.AchtUhrDienst.AddMinutes(duration);
                break;

            case DienstTyp.KernzeitStartDienst:
                start = arbeitstag.KernzeitGruppeStart;
                ende  = arbeitstag.KernzeitGruppeStart.AddMinutes(duration);
                break;

            case DienstTyp.NeunUhrDienst:
                start = arbeitstag.NeunUhrDienst;
                ende  = arbeitstag.NeunUhrDienst.AddMinutes(duration);
                break;

            case DienstTyp.ZehnUhrDienst:
                start = arbeitstag.ZehnUhrDienst;
                ende  = arbeitstag.ZehnUhrDienst.AddMinutes(duration);
                break;

            case DienstTyp.FsjFrühdienst:
                start = arbeitstag.FrühdienstFsj;
                ende  = arbeitstag.FrühdienstFsj.AddMinutes(duration);
                break;

            case DienstTyp.FsjKernzeitdienst:
                start = arbeitstag.NormaldienstFsj;
                ende  = arbeitstag.NormaldienstFsj.AddMinutes(duration);
                break;

            case DienstTyp.FsjSpätdienst:
                start = arbeitstag.SpätdienstEndeFsj.AddMinutes(-1 * duration);
                ende  = arbeitstag.SpätdienstEndeFsj;
                break;

            case DienstTyp.KernzeitEndeDienst:
                start = arbeitstag.KernzeitGruppeEnde.AddMinutes(-1 * duration);
                ende  = arbeitstag.KernzeitGruppeEnde;
                break;

            case DienstTyp.SechszehnUhrDienst:
                start = arbeitstag.SechzehnUhrDienst.AddMinutes(-1 * duration);
                ende  = arbeitstag.SechzehnUhrDienst;
                break;

            case DienstTyp.SpätdienstEnde:
                start = arbeitstag.SpätdienstEnde.AddMinutes(-1 * duration);
                ende  = arbeitstag.SpätdienstEnde;
                break;

            case DienstTyp.Frei:
                duration = ma.TagesSollMinuten;
                start    = arbeitstag.KernzeitGruppeStart;
                ende     = arbeitstag.KernzeitGruppeStart.AddMinutes(duration);
                break;

            default:
                break;
            }
            var zeitraum = new TimeRange(start, ende);
            #endregion

            var result = new PlanItem();

            result.Arbeitstag    = arbeitstag;
            result.ErledigtDurch = ma;
            result.Thema         = ma?.DefaultThema ?? Themen.None;
            result.Zeitraum      = vorgabe ?? zeitraum;
            result.Gruppe        = gruppe;
            result.Dienst        = dienst;

            result.SetHatGrossteam();

            //Pausen mit Planen
            if (result.Zeitraum.Duration.TotalMinutes > 360)
            {
                if ((dienst & DienstTyp.KernzeitEndeDienst) == DienstTyp.KernzeitEndeDienst ||
                    (dienst & DienstTyp.SechszehnUhrDienst) == DienstTyp.SechszehnUhrDienst ||
                    (dienst & DienstTyp.SpätdienstEnde) == DienstTyp.SpätdienstEnde ||
                    (dienst & DienstTyp.FsjSpätdienst) == DienstTyp.FsjSpätdienst)

                {
                    result.Zeitraum.Start = result.Zeitraum.Start.AddMinutes(-1 * 30);
                }
                else
                {
                    result.Zeitraum.End = result.Zeitraum.End.AddMinutes(30);
                }
            }

            //Endzeiten einhalten
            AdjustEndzeitEnde(result);

            return(result);
        }
Ejemplo n.º 8
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]);
        }
Ejemplo n.º 9
0
 /// <summary>
 /// Gibt die Mitarbeiter Arbeitszeiten für eine Arbeitstag und eine Gruppe zurück
 /// </summary>
 /// <param name="arbeitstag"></param>
 /// <param name="gruppe"></param>
 /// <returns></returns>
 public static IList <TimeRange> GetMitarbeiterArbeitszeiten(this Arbeitstag arbeitstag, GruppenTyp gruppe)
 {
     return
         (arbeitstag.Planzeiten
          .Where(x => x.Gruppe == gruppe &&
                 x.Dienst != DienstTyp.Frei &&
                 (!x.ErledigtDurch?.IsHelfer ?? false))
          .Select(x => x.Zeitraum)
          .ToList());
 }
Ejemplo n.º 10
0
 /// <summary>
 /// Gibt die Mitarbeiter Planitems für eine Arbeitstag und eine Gruppe zurück
 /// </summary>
 /// <param name="arbeitstag"></param>
 /// <param name="gruppe"></param>
 /// <returns></returns>
 public static IList <PlanItem> GetMitarbeiterArbeitsplanzeiten(this Arbeitstag arbeitstag, GruppenTyp gruppe)
 {
     return
         (arbeitstag.Planzeiten.Where(x => x.Gruppe == gruppe && !x.ErledigtDurch.IsHelfer)
          .Select(x => x)
          .ToList());
 }
Ejemplo n.º 11
0
        public static bool CheckKernzeitDoppelBesetzungAbgedeckt(this Arbeitstag arbeitstag, GruppenTyp gruppe)
        {
            if (!gruppe.IstFarbGruppe())
            {
                return(true);
            }

            var gruppenzeiten = arbeitstag.GetMitarbeiterArbeitszeiten(gruppe);

            if (gruppenzeiten.Count < 2)
            {
                return(false);
            }

            if (gruppenzeiten.Count == 2)
            {
                var anzDoppelBesetzung = 0;
                foreach (var range in gruppenzeiten)
                {
                    var tp = new TimePeriodCollection(new List <ITimePeriod>()
                    {
                        range
                    });
                    if (tp.HasInside(arbeitstag.KernzeitDoppelBesetzungRange))
                    {
                        anzDoppelBesetzung++;
                    }
                }
                return(anzDoppelBesetzung >= 2);
            }

            //07:00-11:00
            //09:00-13:00
            //11:00-16:00
            var zeitzeiger = arbeitstag.KernzeitDoppelBesetzungRange.Start;

            while (zeitzeiger <= arbeitstag.KernzeitDoppelBesetzungRange.End)
            {
                var count = gruppenzeiten.Count(x => x.HasInside(zeitzeiger));
                if (count < 2)
                {
                    return(false);
                }

                zeitzeiger = zeitzeiger.AddMinutes(1);
            }

            return(true);
        }
Ejemplo n.º 12
0
 private bool CanChangePlanGruppeCommandExecute(GruppenTyp gt)
 {
     return(Planzeit.Gruppe != gt);
 }