190 lines
9.9 KiB
C#
190 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 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<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;
|
||
|
||
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();
|
||
}
|
||
}
|
||
}
|