155 lines
6.8 KiB
C#
155 lines
6.8 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Numerics;
|
|
using System.Text.RegularExpressions;
|
|
using System.Xml.Serialization;
|
|
|
|
namespace dezentrale.model.money
|
|
{
|
|
[XmlType("BankTransfer")]
|
|
public class BankTransfer : MoneyTransfer
|
|
{
|
|
//This resembles an 1:1 data image from CSV entries.
|
|
[XmlElement] public string AccountInCharge { get; set; } = "";
|
|
[XmlElement] public DateTime BookingDate { get; set; }
|
|
[XmlElement] public string BookingText { get; set; } = "";
|
|
[XmlElement] public string CreditorID { get; set; } = "";
|
|
[XmlElement] public string MandateReference { get; set; } = "";
|
|
[XmlElement] public string ClientReference { get; set; } = "";
|
|
|
|
[XmlElement] public string Sammlerreferenz { get; set; } = "";
|
|
[XmlElement] public string LastschriftUrsprungsbetrag { get; set; } = "";
|
|
[XmlElement] public string AuslagenersatzRuecklastschrift { get; set; } = "";
|
|
|
|
[XmlElement] public string RecipientOrDebitor { get; set; } = "";
|
|
[XmlElement] public string IBAN { get; set; } = "";
|
|
[XmlElement] public string BIC { get; set; } = "";
|
|
[XmlElement] public string Info { get; set; } = "";
|
|
|
|
//During the CSV import process, generated BankTransfer objects will hold CsvFile/Line for later
|
|
//logging into member data / Main log (i.e. it is possible to track a MoneyTransfer from a
|
|
//Member object to a line from a specific csv file)
|
|
[XmlIgnore] public string CsvFile { get; set; } = null;
|
|
[XmlIgnore] public int CsvLine { get; set; } = 0;
|
|
|
|
public BankTransfer() : base() { }
|
|
public BankTransfer(List<string> csvHeadline, List<string> csvEntry, string csvFile = "", int csvLineNumber = 0) : base()
|
|
{
|
|
CsvFile = csvFile;
|
|
CsvLine = csvLineNumber;
|
|
|
|
int lc = csvEntry.Count;
|
|
if (lc > csvHeadline.Count) lc = csvHeadline.Count;
|
|
for (int i = 0; i < lc; i++)
|
|
{
|
|
switch (csvHeadline[i])
|
|
{
|
|
case "Auftragskonto": AccountInCharge = csvEntry[i]; break;
|
|
case "Buchungstag": BookingDate = DateTime.Parse(csvEntry[i]); break;
|
|
case "Valutadatum": ValutaDate = DateTime.Parse(csvEntry[i]); break;
|
|
case "Buchungstext": BookingText = csvEntry[i]; break;
|
|
case "Verwendungszweck": TransferReason = csvEntry[i]; break;
|
|
case "Glaeubiger ID": CreditorID = csvEntry[i]; break;
|
|
case "Mandatsreferenz": MandateReference = csvEntry[i]; break;
|
|
case "Kundenreferenz (End-to-End)": ClientReference = csvEntry[i]; break;
|
|
case "Sammlerreferenz": Sammlerreferenz = csvEntry[i]; break;
|
|
case "Lastschrift Ursprungsbetrag": LastschriftUrsprungsbetrag = csvEntry[i]; break;
|
|
case "Auslagenersatz Ruecklastschrift": AuslagenersatzRuecklastschrift = csvEntry[i]; break;
|
|
case "Beguenstigter/Zahlungspflichtiger": RecipientOrDebitor = csvEntry[i]; break;
|
|
case "Kontonummer/IBAN":
|
|
case "Kontonummer": IBAN = csvEntry[i].Trim(); break;
|
|
case "BIC (SWIFT-Code)":
|
|
case "BLZ": BIC = csvEntry[i].Trim(); break;
|
|
case "Betrag":
|
|
{
|
|
string sAmount = csvEntry[i].Replace(',', '.');
|
|
float fAmount = float.Parse(sAmount, System.Globalization.CultureInfo.InvariantCulture.NumberFormat);
|
|
Amount = Convert.ToInt64(fAmount * 100);
|
|
} break;
|
|
case "Waehrung": Currency = csvEntry[i]; break;
|
|
case "Info": Info = csvEntry[i]; break;
|
|
default:
|
|
throw new Exception($"invalid csv headline field: \"{csvHeadline[i]}\" csvFile {csvFile} line {csvLineNumber}");
|
|
}
|
|
}
|
|
}
|
|
|
|
private const string ibanPattern = "^[A-Z]{2}\\d{2}\\d{8}\\d{10}$";
|
|
public static string IbanRegexAssert(string iban, bool checkPz = true)
|
|
{
|
|
iban = iban.Replace(" ", "").Replace("-", "");
|
|
if (!Regex.IsMatch(iban, ibanPattern))
|
|
{
|
|
throw new FormatException("IBAN format invalid");
|
|
}
|
|
if(checkPz)
|
|
{
|
|
if(!_PzOk(iban))
|
|
{
|
|
throw new Exception("IBAN checksum error");
|
|
}
|
|
}
|
|
return iban;
|
|
}
|
|
private static int _CCodeToInt(string cCode)
|
|
{
|
|
char[] c = cCode.ToCharArray();
|
|
string ret = String.Format("{0}{1}", c[0] + 10 - 'A', c[1] + 10 - 'A');
|
|
return Convert.ToInt32(ret);
|
|
}
|
|
private static string _CalcPz(string cCode, string blz, string kto)
|
|
{
|
|
//https://www.iban.de/iban-pruefsumme.html
|
|
int cci = _CCodeToInt(cCode);
|
|
|
|
string modBaseS = String.Format("{0}{1}{2}00", blz, kto, cci);
|
|
//760909001234567890131400
|
|
BigInteger mod = BigInteger.Parse(modBaseS);
|
|
mod = BigInteger.Remainder(mod, new BigInteger(97));
|
|
string pz = String.Format("{0:D2}", 98 - mod);
|
|
return pz;
|
|
}
|
|
private static string _CalcPz(string iban)
|
|
{
|
|
return _CalcPz(iban.Substring(0, 2), iban.Substring(4, 8), iban.Substring(12,10));
|
|
}
|
|
public static string CalcPz(string iban)
|
|
{
|
|
iban = IbanRegexAssert(iban, false);
|
|
return _CalcPz(iban);
|
|
}
|
|
private static bool _PzOk(string iban)
|
|
{
|
|
return _CalcPz(iban).Equals(iban.Substring(2, 2));
|
|
}
|
|
public static bool PzOk(string iban)
|
|
{
|
|
iban = IbanRegexAssert(iban, false);
|
|
return _PzOk(iban);
|
|
}
|
|
public static string GetKtoFromIban(string iban)
|
|
{
|
|
iban = IbanRegexAssert(iban);
|
|
return iban.Substring(12);
|
|
}
|
|
public static string GetBlzFromIban(string iban)
|
|
{
|
|
iban = IbanRegexAssert(iban);
|
|
return iban.Substring(4, 8);
|
|
}
|
|
public static string GetCCodeFromIban(string iban)
|
|
{
|
|
iban = IbanRegexAssert(iban);
|
|
return iban.Substring(0,2);
|
|
}
|
|
public static string GetIbanFromKtoBlz(string cCode, string blz, string kto)
|
|
{
|
|
//build iban
|
|
string Pz = _CalcPz(cCode, blz, kto);
|
|
string iban = String.Format("{0}{1}{2}{3}", cCode, Pz, blz, kto);
|
|
|
|
return IbanRegexAssert(iban);
|
|
}
|
|
}
|
|
}
|