Add ZIP-wrapped CAMT parsing and real bank file tests
Playwright Tests / test (push) Has been cancelled
Playwright Tests / test (push) Has been cancelled
- Support parsing camt.052 ZIP archives in CamtParser and BankingService
- Add CamtZipParserTests for ZIP parsing (single/multi/malformed/empty cases)
- Add CamtRealFileTests: integration tests for real bank exports (ZIP, XML, CAMT, MT940, STA) in git-ignored test data dir
- Update .gitignore and add README.md for test data usage
- Copy test data files in Fuchs.Tests.csproj; add .gitkeep
- Refactor BankingService CAMT mapping logic
- Overhaul connection string config: use {username}/{password} tokens, resolve from secrets at runtime, update appsettings and Key Vault keys
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
using System.Data;
|
||||
using System.Data;
|
||||
using System.Diagnostics;
|
||||
using CAMTParser;
|
||||
using Fuchs.Observability;
|
||||
@@ -45,10 +45,17 @@ public class BankingService : IBankingService
|
||||
}
|
||||
|
||||
string format;
|
||||
if (CamtParser.LooksLikeXml(bytes))
|
||||
if (CamtParser.LooksLikeZip(bytes))
|
||||
{
|
||||
format = "camt.zip";
|
||||
try { MapCamtEntries(tbl, new CamtParser().ParseZip(bytes)); }
|
||||
catch (Exception ex) { _logger.LogError(ex, "CAMT ZIP statement parse failed."); }
|
||||
}
|
||||
else if (CamtParser.LooksLikeXml(bytes))
|
||||
{
|
||||
format = "camt";
|
||||
FillFromCamt(tbl, bytes);
|
||||
try { MapCamtEntries(tbl, new CamtParser().Parse(bytes)); }
|
||||
catch (Exception ex) { _logger.LogError(ex, "CAMT statement parse failed."); }
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -129,53 +136,48 @@ public class BankingService : IBankingService
|
||||
}
|
||||
|
||||
// ── CAMT (ISO 20022) ───────────────────────────────────────────────────────
|
||||
private void FillFromCamt(DataTable tbl, byte[] bytes)
|
||||
private void MapCamtEntries(DataTable tbl, List<CamtStatement> statements)
|
||||
{
|
||||
void SetNfo(DataRow nr, string key, object? value)
|
||||
{
|
||||
if (tbl.Columns.Contains(key) && value != null) nr[key] = value;
|
||||
}
|
||||
|
||||
try
|
||||
foreach (var stmt in statements)
|
||||
{
|
||||
var statements = new CamtParser().Parse(bytes);
|
||||
foreach (var stmt in statements)
|
||||
if (string.IsNullOrEmpty(stmt.AccountIdentification)) continue;
|
||||
foreach (var e in stmt.Entries)
|
||||
{
|
||||
if (string.IsNullOrEmpty(stmt.AccountIdentification)) continue;
|
||||
foreach (var e in stmt.Entries)
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
var nr = tbl.NewRow();
|
||||
SetNfo(nr, "AccountIdentification", stmt.AccountIdentification);
|
||||
if (e.Amount.HasValue) SetNfo(nr, "Amount", e.Amount);
|
||||
if (e.EntryDate.HasValue) SetNfo(nr, "EntryDate", e.EntryDate);
|
||||
if (e.ValueDate.HasValue) SetNfo(nr, "ValueDate", e.ValueDate);
|
||||
SetNfo(nr, "FundsCode", e.Currency);
|
||||
SetNfo(nr, "DebitCreditMark", e.MarkAbbreviation);
|
||||
SetNfo(nr, "BankReference", e.BankReference);
|
||||
SetNfo(nr, "EndToEndReference", e.EndToEndReference);
|
||||
SetNfo(nr, "MandateReference", e.MandateReference);
|
||||
SetNfo(nr, "CustomerReference", e.CustomerReference);
|
||||
SetNfo(nr, "CreditorReference", e.CreditorReference);
|
||||
SetNfo(nr, "AccountNumberOfPayer", e.CounterpartyIban);
|
||||
SetNfo(nr, "BankCodeOfPayer", e.CounterpartyBic);
|
||||
SetNfo(nr, "NameOfPayer", e.CounterpartyName);
|
||||
SetNfo(nr, "PostingText", e.AdditionalInfo);
|
||||
SetNfo(nr, "TransactionTypeIdCode",e.BankTransactionCode);
|
||||
SetNfo(nr, "SepaRemittanceInformation",
|
||||
string.IsNullOrEmpty(e.RemittanceUnstructured) ? e.RemittanceStructured : e.RemittanceUnstructured);
|
||||
SetNfo(nr, "UnstructuredRemittanceInformation", e.RemittanceUnstructured);
|
||||
SetNfo(nr, "UnstructuredData", e.RemittanceUnstructured);
|
||||
SetNfo(nr, "IsUnstructuredData", e.IsUnstructuredData);
|
||||
var nr = tbl.NewRow();
|
||||
SetNfo(nr, "AccountIdentification", stmt.AccountIdentification);
|
||||
if (e.Amount.HasValue) SetNfo(nr, "Amount", e.Amount);
|
||||
if (e.EntryDate.HasValue) SetNfo(nr, "EntryDate", e.EntryDate);
|
||||
if (e.ValueDate.HasValue) SetNfo(nr, "ValueDate", e.ValueDate);
|
||||
SetNfo(nr, "FundsCode", e.Currency);
|
||||
SetNfo(nr, "DebitCreditMark", e.MarkAbbreviation);
|
||||
SetNfo(nr, "BankReference", e.BankReference);
|
||||
SetNfo(nr, "EndToEndReference", e.EndToEndReference);
|
||||
SetNfo(nr, "MandateReference", e.MandateReference);
|
||||
SetNfo(nr, "CustomerReference", e.CustomerReference);
|
||||
SetNfo(nr, "CreditorReference", e.CreditorReference);
|
||||
SetNfo(nr, "AccountNumberOfPayer", e.CounterpartyIban);
|
||||
SetNfo(nr, "BankCodeOfPayer", e.CounterpartyBic);
|
||||
SetNfo(nr, "NameOfPayer", e.CounterpartyName);
|
||||
SetNfo(nr, "PostingText", e.AdditionalInfo);
|
||||
SetNfo(nr, "TransactionTypeIdCode",e.BankTransactionCode);
|
||||
SetNfo(nr, "SepaRemittanceInformation",
|
||||
string.IsNullOrEmpty(e.RemittanceUnstructured) ? e.RemittanceStructured : e.RemittanceUnstructured);
|
||||
SetNfo(nr, "UnstructuredRemittanceInformation", e.RemittanceUnstructured);
|
||||
SetNfo(nr, "UnstructuredData", e.RemittanceUnstructured);
|
||||
SetNfo(nr, "IsUnstructuredData", e.IsUnstructuredData);
|
||||
|
||||
tbl.Rows.Add(nr);
|
||||
}
|
||||
catch (Exception ex) { _logger.LogWarning(ex, "CAMT entry parse error — account={Account}", stmt.AccountIdentification); }
|
||||
tbl.Rows.Add(nr);
|
||||
}
|
||||
catch (Exception ex) { _logger.LogWarning(ex, "CAMT entry parse error — account={Account}", stmt.AccountIdentification); }
|
||||
}
|
||||
}
|
||||
catch (Exception ex) { _logger.LogError(ex, "CAMT statement parse failed."); }
|
||||
}
|
||||
|
||||
private static DataTable BuildDefaultSchema()
|
||||
|
||||
Reference in New Issue
Block a user