Export: Refactor interfaces and classes

This commit is contained in:
2023-09-07 00:44:28 +02:00
parent be734b880f
commit f9d95a48f2
8 changed files with 163 additions and 36 deletions

View File

@ -0,0 +1,14 @@
using Elwig.Models;
namespace Elwig.Helpers.Billing {
public class Transaction {
public readonly Member Member;
public readonly int AmountCent;
public Transaction(Member m, decimal amount) {
Member = m;
AmountCent = (int)(amount * 100);
}
}
}

View File

@ -1,4 +1,51 @@
using Elwig.Models;
using Microsoft.EntityFrameworkCore;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Elwig.Helpers.Export {
public class Bki {
public class Bki : Csv<DeliveryPart> {
private readonly string _clientData;
public Bki(string filename) : base(filename, ';', Encoding.Latin1) {
Header = """
EDV-Liste zum automatischen Einlesen in die Weindatenbank;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Stammdaten;;;;;;;;;;;;;;Transportschein;;;;;;;;;;;;;;;;
Empfänger:;;;;;;;Versender:;;;;;;;;;;;;;;;;;;;;;;;
Betriebsnr;Name od. Firmenname;Vorname;Straße;Hausnr;Plz;Ort;Betriebsnr;Name od. Firmenname;Vorname;Straße;Hausnr;Plz;Ort;Datum der Lieferung;Menge in kg;Art;Weiß;Rot;Sorte1;Sorte2;Sorte3;Qualitätsstufe;Jahrgang;Herkunft;°KMW;°Oe;Vollablieferer;Ha Gesamt;Ha Ertragsfähig;Flächenbindung in Ha für AMA
""";
var c = App.Client;
var (a1, a2) = Utils.SplitAddress(c.Address);
_clientData = $"{c.LfbisNr};{c.NameFull};;{a1};{a2};{c.Plz};{c.Ort}";
}
public async Task ExportAsync(AppDbContext ctx, int year) {
await ExportAsync(await ctx.DeliveryParts.Where(p => p.Year == year).ToListAsync());
}
public void Export(AppDbContext ctx, int year) {
ExportAsync(ctx, year).GetAwaiter().GetResult();
}
public override string FormatRow(DeliveryPart p) {
var d = p.Delivery;
var m = d.Member;
string memberData;
if (m.BillingAddress is BillingAddr a) {
var (n1, n2) = Utils.SplitName(a.Name, m.FamilyName);
var (a1, a2) = Utils.SplitAddress(a.Address);
memberData = $"{m.LfbisNr};{n1};{n2};{a1};{a2};{a.PostalDest.AtPlz?.Plz};{a.PostalDest.AtPlz?.Ort.Name}";
} else {
var (a1, a2) = Utils.SplitAddress(m.Address);
memberData = $"{m.LfbisNr};{m.FamilyName};{m.AdministrativeName2};{a1};{a2};{m.PostalDest.AtPlz?.Plz};{m.PostalDest.AtPlz?.Ort.Name}";
}
var s = p.Variant;
var deliveryData = $"{d.Date:dd.MM.yyyy};{p.Weight};TB;{(s.IsWhite ? "J" : "")};{(s.IsRed ? "J" : "")};{s.SortId};;;{p.QualId};{d.Year};{p.HkId};{p.Kmw};{p.Oe}";
var vollData = $"N;;;{m.AreaCommitments.Where(a => a.YearFrom <= d.Year && (a.YearTo == null || a.YearTo >= d.Year)).Sum(a => a.Area) / 10_000.0}";
return $"{_clientData};{memberData};{deliveryData};{vollData}";
}
}
}

View File

@ -1,4 +1,50 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading.Tasks;
namespace Elwig.Helpers.Export {
public class Csv {
public abstract class Csv<T> : IExporter<T> {
public static string FileExtension => "csv";
protected readonly StreamWriter Writer;
protected readonly char Separator;
protected string? Header;
public Csv(string filename, char separator = ';') : this(filename, separator, Encoding.UTF8) { }
public Csv(string filename, char separator, Encoding encoding) {
Writer = new StreamWriter(filename, false, encoding);
Separator = separator;
}
public void Dispose() {
GC.SuppressFinalize(this);
Writer.Dispose();
}
public ValueTask DisposeAsync() {
GC.SuppressFinalize(this);
return Writer.DisposeAsync();
}
public async Task ExportAsync(IEnumerable<T> data) {
if (Header != null) await Writer.WriteLineAsync(Header);
foreach (var row in data) {
await Writer.WriteLineAsync(FormatRow(row));
}
}
public void Export(IEnumerable<T> data) {
ExportAsync(data).GetAwaiter().GetResult();
}
public string FormatRow(IEnumerable row) {
return string.Join(Separator, row);
}
public abstract string FormatRow(T row);
}
}

View File

@ -1,14 +1,26 @@
using Elwig.Models;
using Elwig.Helpers.Billing;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Elwig.Helpers.Export {
public class Ebics : IBankingProvider {
public class Ebics : IBankingExporter {
public string FileExtension => "xml";
public static string FileExtension => "xml";
public Task Export(string filename, int avnr, IEnumerable<Member> members) {
public void Dispose() {
throw new NotImplementedException();
}
public ValueTask DisposeAsync() {
throw new NotImplementedException();
}
public void Export(IEnumerable<Transaction> data) {
throw new NotImplementedException();
}
public Task ExportAsync(IEnumerable<Transaction> data) {
throw new NotImplementedException();
}
}

View File

@ -1,14 +1,14 @@
using Elwig.Models;
using Elwig.Helpers.Billing;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Elwig.Helpers.Export {
public class Elba : IBankingProvider {
public class Elba : Csv<Transaction>, IBankingExporter {
public string FileExtension => "elba";
public static new string FileExtension => "elba";
public Task Export(string filename, int avnr, IEnumerable<Member> members) {
public Elba(string filename) : base(filename) { }
public override string FormatRow(Transaction row) {
throw new NotImplementedException();
}
}

View File

@ -0,0 +1,8 @@
using Elwig.Helpers.Billing;
namespace Elwig.Helpers.Export {
/// <summary>
/// Interface for exporting banking data
/// </summary>
public interface IBankingExporter : IExporter<Transaction> { }
}

View File

@ -1,24 +0,0 @@
using Elwig.Models;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Elwig.Helpers.Export {
/// <summary>
/// Interface for exporting banking data
/// </summary>
public interface IBankingProvider {
/// <summary>
/// The default file extension of the exported files to be used (whithout a preceding ".")
/// </summary>
string FileExtension { get; }
/// <summary>
/// Export the member payment data of the given payment variant to the given file.
/// (The amount of the last payed variant is deducted from the calculated amount.)
/// </summary>
/// <param name="filename">The file to export the data to</param>
/// <param name="avnr">The number of the payment variant to export</param>
/// <param name="members">The members whose data to include in the export</param>
Task Export(string filename, int avnr, IEnumerable<Member> members);
}
}

View File

@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Elwig.Helpers.Export {
public interface IExporter<T> : IDisposable, IAsyncDisposable {
/// <summary>
/// The default file extension of the exported files to be used (whithout a preceding ".")
/// </summary>
static string FileExtension { get; }
/// <summary>
/// Export the given data to the given file.
/// </summary>
/// <param name="data">The data to be exported</param>
void Export(IEnumerable<T> data);
/// <summary>
/// Export the given data to the given file.
/// </summary>
/// <param name="data">The data to be exported</param>
Task ExportAsync(IEnumerable<T> data);
}
}