110 lines
4.8 KiB
C#
110 lines
4.8 KiB
C#
using Elwig.Helpers.Billing;
|
|
using Elwig.Models.Entities;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace Elwig.Helpers.Export {
|
|
public class Ebics : IBankingExporter {
|
|
|
|
public static string FileExtension => "xml";
|
|
|
|
private readonly StreamWriter _writer;
|
|
private readonly DateOnly _date;
|
|
private readonly int _year;
|
|
private readonly string _name;
|
|
private readonly int _nr;
|
|
|
|
public Ebics(PaymentVar variant, string filename) {
|
|
_writer = new(filename, false, Utils.UTF8);
|
|
_date = variant.TransferDate ?? DateOnly.Parse("2021-01-10"); //throw new ArgumentException("TransferDate has to be set in PaymentVar");
|
|
_year = variant.Year;
|
|
_name = variant.Name;
|
|
_nr = variant.AvNr;
|
|
}
|
|
|
|
public void Dispose() {
|
|
GC.SuppressFinalize(this);
|
|
_writer.Dispose();
|
|
}
|
|
|
|
public ValueTask DisposeAsync() {
|
|
GC.SuppressFinalize(this);
|
|
return _writer.DisposeAsync();
|
|
}
|
|
|
|
public void Export(IEnumerable<Transaction> transactions, IProgress<double>? progress = null) {
|
|
ExportAsync(transactions, progress).GetAwaiter().GetResult();
|
|
}
|
|
|
|
public async Task ExportAsync(IEnumerable<Transaction> transactions, IProgress<double>? progress = null) {
|
|
progress?.Report(0.0);
|
|
var nbOfTxs = transactions.Count();
|
|
int count = nbOfTxs + 2, i = 0;
|
|
var ctrlSum = Transaction.FormatAmountCent(transactions.Sum(tx => tx.AmountCent));
|
|
var msgId = $"ELWIG-{App.Client.NameToken}-{_year}-AV{_nr:00}";
|
|
var pmtInfId = $"{msgId}-1";
|
|
|
|
await _writer.WriteLineAsync($"""
|
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:pain.001.001.09"
|
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
xsi:schemaLocation="urn:iso:std:iso:20022:tech:xsd:pain.001.001.09 pain.001.001.09.xsd">
|
|
<CstmrCdtTrfInitn>
|
|
<GrpHdr>
|
|
<MsgId>{msgId}</MsgId>
|
|
<CreDtTm>{DateTime.UtcNow:o}</CreDtTm>
|
|
<NbOfTxs>{nbOfTxs}</NbOfTxs>
|
|
<CtrlSum>{ctrlSum}</CtrlSum>
|
|
<InitgPty><Nm>{App.Client.NameFull}</Nm></InitgPty>
|
|
</GrpHdr>
|
|
<PmtInf>
|
|
<PmtInfId>{pmtInfId}</PmtInfId>
|
|
<PmtMtd>TRF</PmtMtd>
|
|
<NbOfTxs>{nbOfTxs}</NbOfTxs>
|
|
<CtrlSum>{ctrlSum}</CtrlSum>
|
|
<ReqdExctnDt><Dt>{_date:yyyy-MM-dd}</Dt></ReqdExctnDt>
|
|
<Dbtr><Nm>{App.Client.NameFull}</Nm></Dbtr>
|
|
<DbtrAcct><Id><IBAN>{App.Client.Iban?.Replace(" ", "")}</IBAN></Id></DbtrAcct>
|
|
<DbtrAgt><FinInstnId><BICFI>{App.Client.Bic ?? "NOTPROVIDED"}</BICFI></FinInstnId></DbtrAgt>
|
|
""");
|
|
progress?.Report(100.0 * ++i / count);
|
|
|
|
foreach (var tx in transactions) {
|
|
var a = (IAddress?)tx.Member.BillingAddress ?? tx.Member;
|
|
var (a1, a2) = Utils.SplitAddress(a.Address);
|
|
var id = $"ELWIG-{App.Client.NameToken}-{_year}-TG{tx.Nr:0000}";
|
|
var info = $"{_name} - Traubengutschrift {_year}/{tx.Nr:000}";
|
|
await _writer.WriteLineAsync($"""
|
|
<CdtTrfTxInf>
|
|
<PmtId><EndToEndId>{id}</EndToEndId></PmtId>
|
|
<Amt><InstdAmt Ccy="{tx.Currency}">{Transaction.FormatAmountCent(tx.AmountCent)}</InstdAmt></Amt>
|
|
<Cdtr>
|
|
<Nm>{a.Name}</Nm>
|
|
<PstlAdr>
|
|
<StrtNm>{a1}</StrtNm><BldgNb>{a2}</BldgNb>
|
|
<PstCd>{a.PostalDest.AtPlz?.Plz}</PstCd><TwnNm>{a.PostalDest.AtPlz?.Ort.Name}</TwnNm>
|
|
<Ctry>{a.PostalDest.Country.Alpha2}</Ctry>
|
|
</PstlAdr>
|
|
</Cdtr>
|
|
<CdtrAcct><Id><IBAN>{tx.Member.Iban}</IBAN></Id><CdtrAcct>
|
|
<CdtrAgt><FinInstnId><BICFI>{tx.Member.Bic ?? "NOTPROVIDED"}</BICFI></FinInstnId></CdtrAgt>
|
|
<RmtInf><Ustrd>{info}</Ustrd></RmtInf>
|
|
</CdtTrfTxInf>
|
|
""");
|
|
progress?.Report(100.0 * ++i / count);
|
|
}
|
|
|
|
await _writer.WriteLineAsync("""
|
|
</PmtInf>
|
|
</CstmrCdtTrfInitn>
|
|
</Document>
|
|
""");
|
|
await _writer.FlushAsync();
|
|
progress?.Report(100.0);
|
|
}
|
|
}
|
|
}
|