using Elwig.Helpers; using Elwig.Models.Entities; using Elwig.ViewModels; using LinqKit; using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace Elwig.Services { public static class DeliveryScheduleService { public static void InitInputs(this DeliveryScheduleAdminViewModel vm) { if (vm.BranchSource.Count() == 1) vm.Branch = vm.BranchSource.First(); vm.AncmtFromTimeString = "00:00"; vm.AncmtToTimeString = "23:59"; } public static void ClearInputs(this DeliveryScheduleAdminViewModel vm) { } public static async Task FillInputs(this DeliveryScheduleAdminViewModel vm, DeliverySchedule s) { vm.Date = s.Date; vm.Branch = (Branch?)ControlUtils.GetItemFromSourceWithPk(vm.BranchSource, s.ZwstId); vm.Description = s.Description; vm.MaxWeight = s.MaxWeight; vm.IsCancelled = s.IsCancelled; vm.MainVarieties.Clear(); foreach (var v in s.Varieties.Where(v => v.Priority == 1)) { vm.MainVarieties.Add((WineVar)ControlUtils.GetItemFromSourceWithPk(vm.MainVarietiesSource, v.SortId)!); } vm.OtherVarieties.Clear(); foreach (var v in s.Varieties.Where(v => v.Priority != 1)) { vm.OtherVarieties.Add((WineVar)ControlUtils.GetItemFromSourceWithPk(vm.OtherVarietiesSource, v.SortId)!); } vm.Attribute = ControlUtils.GetItemFromSourceWithPk(vm.AttributeSource, s.AttrId) as WineAttr; vm.Cultivation = ControlUtils.GetItemFromSourceWithPk(vm.CultivationSource, s.CultId) as WineCult; vm.AncmtFrom = s.AncmtFrom; vm.AncmtTo = s.AncmtTo?.AddSeconds(-1); } public static async Task<(List, IQueryable, List)> GetFilters(this DeliveryScheduleAdminViewModel vm, AppDbContext ctx) { List filterNames = []; IQueryable deliveryScheduleQuery = ctx.DeliverySchedules; if (vm.FilterSeason != null) { deliveryScheduleQuery = deliveryScheduleQuery.Where(s => s.Year == vm.FilterSeason); filterNames.Add($"{vm.FilterSeason}"); } if (vm.FilterOnlyUpcoming) { deliveryScheduleQuery = deliveryScheduleQuery.Where(s => s.DateString.CompareTo(Utils.Today.ToString("yyyy-MM-dd")) >= 0); filterNames.Add($"ab {Utils.Today:dd.MM.yyyy}"); } var filterVar = new List(); var filterNotVar = new List(); var filterZwst = new List(); var filterDate = new List<(string?, string?)>(); var filter = vm.TextFilter; if (filter.Count > 0) { var var = await ctx.WineVarieties.ToDictionaryAsync(v => v.SortId, v => v); var zwst = await ctx.Branches.ToDictionaryAsync(b => b.Name.ToLower().Split(" ")[0], b => b); for (int i = 0; i < filter.Count; i++) { var e = filter[i]; if (e.ToLower() is "r" or "rot") { filterVar.AddRange(var.Values.Where(v => v.IsRed).Select(v => v.SortId)); filter.RemoveAt(i--); filterNames.Add("Rotweinsorten"); } else if (e.ToLower() is "w" or "weiß" or "weiss") { filterVar.AddRange(var.Values.Where(v => v.IsWhite).Select(v => v.SortId)); filter.RemoveAt(i--); filterNames.Add("Weißweinsorten"); } else if (e.Length == 2 && var.ContainsKey(e.ToUpper())) { filterVar.Add(e.ToUpper()); filter.RemoveAt(i--); filterNames.Add(var[e.ToUpper()].Name); } else if (e.Length == 3 && e[0] == '!' && var.ContainsKey(e[1..].ToUpper())) { filterNotVar.Add(e[1..].ToUpper()); filter.RemoveAt(i--); filterNames.Add("außer " + var[e[1..].ToUpper()].Name); } else if (zwst.ContainsKey(e.ToLower())) { var b = zwst[e.ToLower()]; filterZwst.Add(b.ZwstId); filter.RemoveAt(i--); filterNames.Add($"Zweigstelle {b.Name}"); } else if (DateOnly.TryParse(e, out var date)) { var s = date.ToString("yyyy-MM-dd"); filterDate.Add((s, s)); filter.RemoveAt(i--); if (filterNames.Contains($"{vm.FilterSeason}") && vm.FilterSeason == date.Year) filterNames.Remove($"{vm.FilterSeason}"); filterNames.Add(date.ToString("dd.MM.yyyy")); } else if (Utils.DateFromToRegex.IsMatch(e)) { var parts = e.Split("-"); if (parts.Length == 1) { // single date var dParts = parts[0].Split('.'); var s = $"{dParts[2]}-{dParts[1].PadLeft(2, '0')}-{dParts[0].PadLeft(2, '0')}"; filterDate.Add((s, s)); filter.RemoveAt(i--); var n = string.Join('.', s.Split('-').Reverse()); if (dParts[2] == "") { filterNames.Remove($"{vm.FilterSeason}"); filterNames.Add(n + $"{vm.FilterSeason}"); } else { if ($"{vm.FilterSeason}" == dParts[2]) filterNames.Remove($"{vm.FilterSeason}"); filterNames.Add(n); } } else if (parts.Length == 2) { // from/to date var d1Parts = parts[0].Split('.'); var d2Parts = parts[1].Split('.'); var s1 = d1Parts.Length < 2 ? null : $"{d1Parts.ElementAtOrDefault(2)}-{d1Parts[1].PadLeft(2, '0')}-{d1Parts[0].PadLeft(2, '0')}"; var s2 = d2Parts.Length < 2 ? null : $"{d2Parts.ElementAtOrDefault(2)}-{d2Parts[1].PadLeft(2, '0')}-{d2Parts[0].PadLeft(2, '0')}"; filterDate.Add((s1, s2)); filter.RemoveAt(i--); var n1 = s1 == null ? null : string.Join('.', s1.Split('-').Reverse()); var n2 = s2 == null ? null : string.Join('.', s2.Split('-').Reverse()); if (n1 != null && n2 != null) { filterNames.Add($"{n1}–{n2}"); } else if (n1 != null) { filterNames.Add($"ab dem {n1}"); } else if (n2 != null) { filterNames.Add($"bis zum {n2}"); } } } else if (e.Length > 2 && e.StartsWith('"') && e.EndsWith('"')) { filter[i] = e[1..^1]; } else if (e.Length <= 2) { filter.RemoveAt(i--); } } if (filterDate.Count > 0) { var pr = PredicateBuilder.New(false); foreach (var (d1, d2) in filterDate) pr.Or(p => (d1 == null || d1.CompareTo(p.DateString.Substring(10 - d1.Length)) <= 0) && (d2 == null || d2.CompareTo(p.DateString.Substring(10 - d2.Length)) >= 0)); deliveryScheduleQuery = deliveryScheduleQuery.Where(pr); } if (filterVar.Count > 0) deliveryScheduleQuery = deliveryScheduleQuery.Where(s => s.Varieties.Any(v => filterVar.Contains(v.SortId))); if (filterNotVar.Count > 0) deliveryScheduleQuery = deliveryScheduleQuery.Where(s => s.Varieties.All(v => !filterNotVar.Contains(v.SortId))); if (filterZwst.Count > 0) deliveryScheduleQuery = deliveryScheduleQuery.Where(s => filterZwst.Contains(s.Branch.ZwstId)); } return (filterNames, deliveryScheduleQuery, filter); } public static async Task UpdateDeliverySchedule(this DeliveryScheduleAdminViewModel vm, int? oldYear, int? oldDsNr) { int year = vm.Date!.Value.Year; using (var ctx = new AppDbContext()) { var s = new DeliverySchedule { Year = oldYear ?? year, DsNr = oldDsNr ?? await ctx.NextDsNr(year), DateString = $"{vm.Date:yyyy-MM-dd}", ZwstId = vm.Branch!.ZwstId, Description = vm.Description, AttrId = vm.Attribute?.AttrId, CultId = vm.Cultivation?.CultId, MaxWeight = vm.MaxWeight, IsCancelled = vm.IsCancelled, AncmtFrom = vm.AncmtFrom, AncmtTo = vm.AncmtTo?.AddMinutes(1), }; if (oldDsNr != null) { ctx.Update(s); } else { ctx.Add(s); } ctx.UpdateDeliveryScheduleWineVarieties(s, (await ctx.DeliveryScheduleWineVarieties .Where(v => v.Year == s.Year && v.DsNr == s.DsNr) .Select(v => new { v.Variety, v.Priority }) .ToListAsync()) .Select(v => (v.Variety, v.Priority)) .ToList(), vm.MainVarieties.Select(v => (v, 1)).Union(vm.OtherVarieties.Select(v => (v, 2))).ToList()); await ctx.SaveChangesAsync(); } App.HintContextChange(); } } }