189 lines
		
	
	
		
			9.9 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			189 lines
		
	
	
		
			9.9 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
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 void 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<string>, IQueryable<DeliverySchedule>, List<string>)> GetFilters(this DeliveryScheduleAdminViewModel vm, AppDbContext ctx) {
 | 
						||
            List<string> filterNames = [];
 | 
						||
            IQueryable<DeliverySchedule> 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<string>();
 | 
						||
            var filterNotVar = new List<string>();
 | 
						||
            var filterZwst = new List<string>();
 | 
						||
            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<DeliverySchedule>(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;
 | 
						||
 | 
						||
            await Task.Run(async () => {
 | 
						||
                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();
 | 
						||
            });
 | 
						||
        }
 | 
						||
    }
 | 
						||
}
 |