private void Hochzaehlen(DigitalisierungsKontingent kontingent, ref DateTime termin) { for (var i = 0; i < kontingent.InAnzahlTagen; i++) { termin = termin.AddDays(1); EnsureIsWorkingDay(ref termin); } }
public async Task RecalcTermine(DigitalisierungsKategorie kategorie, DigitalisierungsKontingent kontingent) { var digipool = (await orderDataAccess.GetDigipool()).Where(d => d.Digitalisierunskategorie == (int)kategorie).ToArray(); var newTermine = new List <DigitalisierungsTermin>(); foreach (var digiItem in digipool) { var letzterTerminDesBenutzers = GetAeltesterDigitalisierungsTerminDesBenutzers(kategorie, digipool, digiItem); var grenze = letzterTerminDesBenutzers == DateTime.MinValue ? DateTime.MinValue : letzterTerminDesBenutzers.AddDays(-kontingent.InAnzahlTagen); var termineToCheck = await orderDataAccess.GetLatestDigitalisierungsTermine(digiItem.UserId, grenze, kategorie); var foundEntry = termineToCheck.Where(t => t.Termin < letzterTerminDesBenutzers).OrderBy(t => t.Termin).FirstOrDefault(); DateTime referenzTermin; if (foundEntry != null) // Wenn ja, wird der jüngste Termin als Referenz genommen { referenzTermin = foundEntry.Termin; } else // Wenn nein, wird der älteste Termin aus dem digipool genommen { referenzTermin = digipool.Where(d => d.UserId == digiItem.UserId).Min(d => d.TerminDigitalisierung); } var termin = referenzTermin; if (!newTermine.Any() && referenzTermin != letzterTerminDesBenutzers) { Hochzaehlen(kontingent, ref termin); EnsureIsWorkingDay(ref termin); } else { termin = GetNextPossibleTermin(referenzTermin, newTermine.Where(t => t.UserId == digiItem.UserId).ToList(), kontingent); } var index = newTermine.FindIndex(n => n.Termin == termin && n.UserId == digiItem.UserId); if (index >= 0) { newTermine[index].AnzahlAuftraege++; } else { newTermine.Add(new DigitalisierungsTermin { AnzahlAuftraege = 1, Termin = termin, UserId = digiItem.UserId }); } Log.Debug("Neuberechnung für Auftrag {ID} beendet, vorher: {TERMINALT}, jetzt: {TERMINNEU}", digiItem.OrderItemId, digiItem.TerminDigitalisierung, termin); await orderDataAccess.UpdateTermin(digiItem.OrderItemId, termin); } }
private void GetPossibleTerminInternal(int anzahlAuftraege, DigitalisierungsKontingent kontingent, List <DigitalisierungsTermin> nextTermine, DateTime nextTermin, ref DateTime termin, bool isWeekendDay) { if (anzahlAuftraege < kontingent.AnzahlAuftraege) { // Es hat noch freien Platz an diesem Tag termin = CreateReferenzTermin(nextTermin, isWeekendDay); return; } termin = CreateReferenzTermin(nextTermin, isWeekendDay); while (anzahlAuftraege >= kontingent.AnzahlAuftraege) { Hochzaehlen(kontingent, ref termin); termin = CreateReferenzTermin(termin, isWeekendDay); anzahlAuftraege = GetAnzahlAuftraegeAnDiesemTag(nextTermine, termin); } }
public DateTime GetNextPossibleTermin(DateTime orderDate, List <DigitalisierungsTermin> nextTermine, DigitalisierungsKontingent kontingent) { var isWeekendDay = IsWeekendDay(orderDate); var termin = CreateReferenzTermin(orderDate, isWeekendDay); var limite = termin.AddDays(-kontingent.InAnzahlTagen); var nextTermineRegardingLimit = nextTermine.Where(t => t.Termin >= limite).OrderByDescending(t => t.Termin).ToList(); // Beträgt die Anzahl Aufträge pro Anzahl Arbeitstage (X Aufträge in Y Arbeitstage) X > 1, werden für die Berechnung des Termins X-1 vorangehende Aufträge nicht berücksichtigt var toSkip = Math.Max(kontingent.AnzahlAuftraege - 1, 0); if (nextTermineRegardingLimit.Any() && (toSkip == 0 || toSkip == nextTermineRegardingLimit.Sum(t => t.AnzahlAuftraege))) { var nextTermin = nextTermineRegardingLimit.First(); var anzahlAuftraege = GetAnzahlAuftraegeAnDiesemTag(nextTermine, nextTermin.Termin); GetPossibleTerminInternal(anzahlAuftraege, kontingent, nextTermine, nextTermin.Termin, ref termin, isWeekendDay); } else if (toSkip > 0 && nextTermineRegardingLimit.Any()) { var latestTermin = termin; foreach (var nextTermin in nextTermineRegardingLimit.SkipWhile((dt, i) => SkipAuftraege(i, dt, toSkip))) { var anzahlAuftraege = GetAnzahlAuftraegeAnDiesemTag(nextTermine, nextTermin.Termin); if (toSkip > 0) { toSkip = Math.Max(toSkip - anzahlAuftraege, 0); continue; } if (anzahlAuftraege < kontingent.AnzahlAuftraege) { // Es hat noch freien Platz an diesem Tag termin = CreateReferenzTermin(nextTermin.Termin, isWeekendDay); EnsureIsWorkingDay(ref termin); return(termin); } latestTermin = nextTermin.Termin; break; } var anzahl = GetAnzahlAuftraegeAnDiesemTag(nextTermine, latestTermin); GetPossibleTerminInternal(anzahl, kontingent, nextTermine, latestTermin, ref termin, isWeekendDay); } EnsureIsWorkingDay(ref termin); return(termin); }