252 lines
13 KiB
C#
252 lines
13 KiB
C#
using System.IO.Compression;
|
|
using System.IO;
|
|
using System.Threading.Tasks;
|
|
using Elwig.Models.Entities;
|
|
using System.Collections.Generic;
|
|
using System;
|
|
using System.Text.Json.Nodes;
|
|
using System.Linq;
|
|
using System.Windows;
|
|
using Microsoft.EntityFrameworkCore;
|
|
|
|
namespace Elwig.Helpers.Export {
|
|
public static class ElwigData {
|
|
|
|
public static readonly string ImportedTxt = Path.Combine(App.DataPath, "imported.txt");
|
|
|
|
public static async Task<string[]> GetImportedFiles() {
|
|
try {
|
|
return await File.ReadAllLinesAsync(ImportedTxt, Utils.UTF8);
|
|
} catch {
|
|
return [];
|
|
}
|
|
}
|
|
|
|
public static async Task AddImportedFiles(IEnumerable<string> filenames) {
|
|
await File.AppendAllLinesAsync(ImportedTxt, filenames, Utils.UTF8);
|
|
}
|
|
|
|
public static Task Import(string filename, bool interactive) => Import([filename], interactive);
|
|
|
|
public static async Task Import(IEnumerable<string> filenames, bool interactive) {
|
|
try {
|
|
using var ctx = new AppDbContext();
|
|
var currentDids = await ctx.Deliveries
|
|
.GroupBy(d => d.Year)
|
|
.ToDictionaryAsync(g => g.Key, g => g.Max(d => d.DId));
|
|
|
|
var deliveries = new List<Delivery>();
|
|
var deliveryParts = new List<DeliveryPart>();
|
|
var modifiers = new List<DeliveryPartModifier>();
|
|
|
|
var metaData = new List<(string Name, int DeliveryNum, string Filters)>();
|
|
|
|
foreach (var filename in filenames) {
|
|
using var zip = ZipFile.Open(filename, ZipArchiveMode.Read);
|
|
|
|
var version = zip.GetEntry("version");
|
|
using (var reader = new StreamReader(version!.Open(), Utils.UTF8)) {
|
|
if (await reader.ReadToEndAsync() != "elwig:1")
|
|
throw new FileFormatException("Ungültige Export-Datei");
|
|
}
|
|
|
|
var metaJson = zip.GetEntry("meta.json");
|
|
var meta = await JsonNode.ParseAsync(metaJson!.Open());
|
|
var deliveryCount = meta!["deliveries"]?["count"]!.AsValue().GetValue<int>();
|
|
var deliveryFilters = meta!["deliveries"]?["filters"]!.AsArray().Select(f => f!.AsValue().GetValue<string>()).ToArray();
|
|
if (deliveryCount != null && deliveryFilters != null)
|
|
metaData.Add((Path.GetFileName(filename), (int)deliveryCount, string.Join(" / ", deliveryFilters)));
|
|
|
|
var membersJson = zip.GetEntry("members.json");
|
|
if (membersJson != null) {
|
|
using var reader = new StreamReader(membersJson.Open(), Utils.UTF8);
|
|
string? line;
|
|
while ((line = await reader.ReadLineAsync()) != null) {
|
|
var obj = JsonNode.Parse(line)!.AsObject();
|
|
// TODO import members.json
|
|
}
|
|
}
|
|
|
|
var areaComsJson = zip.GetEntry("area_commitments.json");
|
|
if (areaComsJson != null) {
|
|
using var reader = new StreamReader(areaComsJson.Open(), Utils.UTF8);
|
|
string? line;
|
|
while ((line = await reader.ReadLineAsync()) != null) {
|
|
var obj = JsonNode.Parse(line)!.AsObject();
|
|
// TODO import area_commitments.json
|
|
}
|
|
}
|
|
|
|
var deliveriesJson = zip.GetEntry("deliveries.json");
|
|
if (deliveriesJson != null) {
|
|
using var reader = new StreamReader(deliveriesJson.Open(), Utils.UTF8);
|
|
string? line;
|
|
while ((line = await reader.ReadLineAsync()) != null) {
|
|
var obj = JsonNode.Parse(line)!.AsObject();
|
|
var (d, parts, mods) = JsonToDelivery(obj, currentDids);
|
|
deliveries.Add(d);
|
|
deliveryParts.AddRange(parts);
|
|
modifiers.AddRange(mods);
|
|
}
|
|
}
|
|
}
|
|
|
|
var lsnrs = deliveries.Select(d => d.LsNr).ToList();
|
|
var duplicateLsNrs = await ctx.Deliveries
|
|
.Where(d => lsnrs.Contains(d.LsNr))
|
|
.Select(d => d.LsNr)
|
|
.ToListAsync();
|
|
var duplicateDIds = deliveries
|
|
.Where(d => duplicateLsNrs.Contains(d.LsNr))
|
|
.Select(d => (d.Year, d.DId))
|
|
.ToList();
|
|
bool overwriteDelivieries = false;
|
|
if (duplicateLsNrs.Count > 0) {
|
|
var res = MessageBox.Show($"Sollen {duplicateLsNrs.Count} Lieferungen überschreiben werden?", "Lieferungen überschreiben",
|
|
MessageBoxButton.YesNo, MessageBoxImage.Warning, MessageBoxResult.No);
|
|
overwriteDelivieries = res == MessageBoxResult.Yes;
|
|
}
|
|
if (overwriteDelivieries) {
|
|
ctx.RemoveRange(ctx.Deliveries.Where(d => duplicateLsNrs.Contains(d.LsNr)));
|
|
ctx.AddRange(deliveries);
|
|
ctx.AddRange(deliveryParts);
|
|
ctx.AddRange(modifiers);
|
|
} else {
|
|
ctx.AddRange(deliveries.Where(d => !duplicateDIds.Contains((d.Year, d.DId))));
|
|
ctx.AddRange(deliveryParts.Where(p => !duplicateDIds.Contains((p.Year, p.DId))));
|
|
ctx.AddRange(modifiers.Where(m => !duplicateDIds.Contains((m.Year, m.DId))));
|
|
}
|
|
await ctx.SaveChangesAsync();
|
|
await AddImportedFiles(filenames.Select(f => Path.GetFileName(f)));
|
|
await App.HintContextChange();
|
|
|
|
MessageBox.Show(
|
|
$"Das importieren der Daten war erfolgreich!\n" +
|
|
$"Folgendes wurde importiert:\n" +
|
|
$" Lieferungen: {deliveries.Count}\n" +
|
|
string.Join("\n", metaData.Select(d => $" {d.Name} ({d.DeliveryNum})\n {d.Filters}")) +
|
|
"\n", "Importieren erfolgreich",
|
|
MessageBoxButton.OK, MessageBoxImage.Information);
|
|
} catch (Exception exc) {
|
|
MessageBox.Show(exc.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
|
|
}
|
|
}
|
|
|
|
public static async Task ExportDeliveries(string filename, IEnumerable<Delivery> deliveries, IEnumerable<string> filters) {
|
|
File.Delete(filename);
|
|
using var zip = ZipFile.Open(filename, ZipArchiveMode.Create);
|
|
|
|
var version = zip.CreateEntry("version", CompressionLevel.NoCompression);
|
|
using (var writer = new StreamWriter(version.Open(), Utils.UTF8)) {
|
|
await writer.WriteAsync("elwig:1");
|
|
}
|
|
|
|
var meta = zip.CreateEntry("meta.json", CompressionLevel.NoCompression);
|
|
using (var writer = new StreamWriter(meta.Open(), Utils.UTF8)) {
|
|
await writer.WriteAsync(
|
|
$"{{\"timestamp\": \"{DateTime.UtcNow:yyyy-MM-ddTHH:mm:ssZ}\", " +
|
|
$"\"zwstid\": \"{App.ZwstId}\", \"device\": \"{Environment.MachineName}\", " +
|
|
$"\"deliveries\": {{" +
|
|
$"\"count\": {deliveries.Count()}, " +
|
|
$"\"parts\": {deliveries.Sum(d => d.Parts.Count)}, " +
|
|
$"\"filters\": [{string.Join(", ", filters.Select(f => '"' + f + '"'))}]" +
|
|
$"}}}}");
|
|
}
|
|
|
|
var json = zip.CreateEntry("deliveries.json");
|
|
using (var writer = new StreamWriter(json.Open(), Utils.UTF8)) {
|
|
foreach (var d in deliveries) {
|
|
await writer.WriteLineAsync(DeliveryToJson(d).ToJsonString());
|
|
}
|
|
}
|
|
}
|
|
|
|
public static JsonObject DeliveryToJson(Delivery d) {
|
|
return new JsonObject {
|
|
["lsnr"] = d.LsNr,
|
|
["year"] = d.Year,
|
|
["date"] = $"{d.Date:yyyy-MM-dd}",
|
|
["zwstid"] = d.ZwstId,
|
|
["lnr"] = d.LNr,
|
|
["time"] = d.Time != null ? $"{d.Time:HH:mm:ss}" : null,
|
|
["mgnr"] = d.MgNr,
|
|
["parts"] = new JsonArray(d.Parts.OrderBy(p => p.DPNr).Select(p => {
|
|
var obj = new JsonObject {
|
|
["dpnr"] = p.DPNr,
|
|
["sortid"] = p.SortId,
|
|
["attrid"] = p.AttrId,
|
|
["cultid"] = p.CultId,
|
|
["weight"] = p.Weight,
|
|
["kmw"] = p.Kmw,
|
|
["qualid"] = p.QualId,
|
|
["hkid"] = p.HkId,
|
|
["kgnr"] = p.KgNr,
|
|
["rdnr"] = p.RdNr,
|
|
["net_weight"] = p.IsNetWeight,
|
|
["manual_weighing"] = p.IsManualWeighing,
|
|
["modids"] = new JsonArray(p.Modifiers.Select(m => (JsonNode)m.ModId).ToArray()),
|
|
["comment"] = p.Comment,
|
|
};
|
|
if (p.IsSplCheck) obj["spl_check"] = p.IsSplCheck;
|
|
if (p.IsHandPicked != null) obj["hand_picked"] = p.IsHandPicked;
|
|
if (p.IsLesewagen != null) obj["lesewagen"] = p.IsLesewagen;
|
|
if (p.IsGebunden != null) obj["gebunden"] = p.IsGebunden;
|
|
if (p.Temperature != null) obj["temperature"] = p.Temperature;
|
|
if (p.Acid != null) obj["acid"] = p.Acid;
|
|
if (p.ScaleId != null) obj["scale_id"] = p.ScaleId;
|
|
if (p.WeighingId != null) obj["weighing_id"] = p.WeighingId;
|
|
if (p.WeighingReason != null) obj["weighing_reason"] = p.WeighingReason;
|
|
return obj;
|
|
}).ToArray()),
|
|
["comment"] = d.Comment,
|
|
};
|
|
}
|
|
|
|
public static (Delivery, List<DeliveryPart>, List<DeliveryPartModifier>) JsonToDelivery(JsonNode json, Dictionary<int, int> currentDids) {
|
|
var year = json["year"]!.AsValue().GetValue<int>();
|
|
var did = ++currentDids[year];
|
|
return (new Delivery {
|
|
Year = year,
|
|
DId = did,
|
|
DateString = json["date"]!.AsValue().GetValue<string>(),
|
|
TimeString = json["time"]?.AsValue().GetValue<string>(),
|
|
ZwstId = json["zwstid"]!.AsValue().GetValue<string>(),
|
|
LNr = json["lnr"]!.AsValue().GetValue<int>(),
|
|
LsNr = json["lsnr"]!.AsValue().GetValue<string>(),
|
|
MgNr = json["mgnr"]!.AsValue().GetValue<int>(),
|
|
Comment = json["comment"]?.AsValue().GetValue<string>(),
|
|
}, json["parts"]!.AsArray().Select(p => p!.AsObject()).Select(p => new DeliveryPart {
|
|
Year = year,
|
|
DId = did,
|
|
DPNr = p["dpnr"]!.AsValue().GetValue<int>(),
|
|
SortId = p["sortid"]!.AsValue().GetValue<string>(),
|
|
AttrId = p["attrid"]?.AsValue().GetValue<string>(),
|
|
CultId = p["cultid"]?.AsValue().GetValue<string>(),
|
|
Weight = p["weight"]!.AsValue().GetValue<int>(),
|
|
Kmw = p["kmw"]!.AsValue().GetValue<double>(),
|
|
QualId = p["qualid"]!.AsValue().GetValue<string>(),
|
|
HkId = p["hkid"]!.AsValue().GetValue<string>(),
|
|
KgNr = p["kgnr"]?.AsValue().GetValue<int>(),
|
|
RdNr = p["rdnr"]?.AsValue().GetValue<int>(),
|
|
IsNetWeight = p["net_weight"]!.AsValue().GetValue<bool>(),
|
|
IsManualWeighing = p["manual_weighing"]!.AsValue().GetValue<bool>(),
|
|
Comment = p["comment"]?.AsValue().GetValue<string>(),
|
|
IsSplCheck = p["spl_check"]?.AsValue().GetValue<bool>() ?? false,
|
|
IsHandPicked = p["hand_picked"]?.AsValue().GetValue<bool>(),
|
|
IsLesewagen = p["lesewagen"]?.AsValue().GetValue<bool>(),
|
|
IsGebunden = p["gebunden"]?.AsValue().GetValue<bool>(),
|
|
Temperature = p["temperature"]?.AsValue().GetValue<double>(),
|
|
Acid = p["acid"]?.AsValue().GetValue<double>(),
|
|
ScaleId = p["scale_id"]?.AsValue().GetValue<string>(),
|
|
WeighingId = p["weighing_id"]?.AsValue().GetValue<string>(),
|
|
WeighingReason = p["weighing_reason"]?.AsValue().GetValue<string>(),
|
|
}).ToList(), json["parts"]!.AsArray().SelectMany(p => p!["modids"]!.AsArray().Select(m => new DeliveryPartModifier {
|
|
Year = year,
|
|
DId = did,
|
|
DPNr = p["dpnr"]!.AsValue().GetValue<int>(),
|
|
ModId = m!.AsValue().GetValue<string>(),
|
|
})).ToList());
|
|
}
|
|
}
|
|
}
|