private static void AssignDescriptionSubField(SWIFTTransaction transaction, string value, ref string lastSubfield) { string pattern = $@"^((?<designator>EREF|KREF|MREF|BREF|RREF|CRED|DEBT|COAM|OAMT|SVWZ|ABWA|ABWE|IBAN|BIC)\+)(?<content>.+)"; Match result = Regex.Match(value, pattern); if (result.Success) { if (SetDescriptionSubField(result.Groups["designator"].Value, transaction, result.Groups["content"].Value)) { lastSubfield = result.Groups["designator"].Value; } else { lastSubfield = string.Empty; } } else if (!string.IsNullOrEmpty(lastSubfield)) { SetDescriptionSubField(lastSubfield, transaction, value); } }
private static bool SetDescriptionSubField(string designator, SWIFTTransaction transaction, string value) { switch (designator) { case "ABWA": transaction.ABWA += value; break; case "EREF": transaction.EREF += value; break; case "KREF": transaction.KREF += value; break; case "MREF": transaction.MREF += value; break; case "BREF": transaction.BREF += value; break; case "RREF": transaction.RREF += value; break; case "CRED": transaction.CRED += value; break; case "DEBT": transaction.DEBT += value; break; case "COAM": transaction.COAM += value; break; case "OAMT": transaction.OAMT += value; break; case "SVWZ": transaction.SVWZ += value; break; case "ABWE": transaction.ABWE += value; break; case "IBAN": transaction.IBAN += value; break; case "BIC": transaction.BIC += value; break; default: //something is wrong here return(false); } return(true); }
private static void Data(string swiftTag, string swiftData) { if (SWIFTStatement != null) { SWIFTStatement.lines.Add(new SWIFTLine(swiftTag, swiftData)); } if (swiftTag == "OS") { // Ignore } else if (swiftTag == "20") { // 20 is used for each "page" of the SWIFTStatement; but we want to put all SWIFTTransactions together // the whole SWIFTStatement closes with 62F if (SWIFTStatement == null) { SWIFTStatement = new SWIFTStatement(); SWIFTStatement.lines.Add(new SWIFTLine(swiftTag, swiftData)); } } else if (swiftTag == "25") { int posSlash = swiftData.IndexOf("/"); SWIFTStatement.bankCode = swiftData.Substring(0, posSlash); SWIFTStatement.accountCode = LTrim(swiftData.Substring(posSlash + 1)); } else if (swiftTag.StartsWith("60")) { // 60M is the start balance on each page of the SWIFTStatement. // 60F is the start balance of the whole SWIFTStatement. // First character is D or C int DebitCreditIndicator = (swiftData[0] == 'D' ? -1 : +1); // Next 6 characters: YYMMDD // Next 3 characters: Currency // Last characters: Balance with comma for decimal point SWIFTStatement.currency = swiftData.Substring(7, 3); decimal balance = DebitCreditIndicator * Convert.ToDecimal(swiftData.Substring(10).Replace(",", Thread.CurrentThread.CurrentCulture.NumberFormat.CurrencyDecimalSeparator)); // We only want to use the first start balance if (swiftTag == "60F") { SWIFTStatement.startBalance = balance; SWIFTStatement.endBalance = balance; } else { // Check if the balance inside the SWIFTStatement is valid // Check it fits the balance of the previous page if (Convert.ToDecimal(Math.Round(SWIFTStatement.endBalance, 2)) != Convert.ToDecimal(balance)) { return; } } } else if (swiftTag == "28C") { // this contains the number of the SWIFTStatement and the number of the page // only use for first page if (SWIFTStatement.SWIFTTransactions.Count == 0) { if (swiftData.IndexOf("/") != -1) { SWIFTStatement.id = swiftData.Substring(0, swiftData.IndexOf("/")); } else { // Realtime SWIFTStatement. // Not use SWIFTStatement number 0, because Sparkasse has 0/1 for valid SWIFTStatements SWIFTStatement.id = string.Empty; } } } else if (swiftTag == "61") { // If there is no SWIFTStatement available, create one if (SWIFTStatement == null) { SWIFTStatement = new SWIFTStatement(); SWIFTStatement.lines.Add(new SWIFTLine(swiftTag, swiftData)); } SWIFTTransaction SWIFTTransaction = new SWIFTTransaction(); // Valuta date (YYMMDD) try { SWIFTTransaction.valueDate = new DateTime(2000 + Convert.ToInt32(swiftData.Substring(0, 2)), Convert.ToInt32(swiftData.Substring(2, 2)), Convert.ToInt32(swiftData.Substring(4, 2))); } catch (ArgumentOutOfRangeException) { // we have had the situation in the bank file with a date 30 Feb 2010. // probably because the instruction by the donor is to transfer the money on the 30 day each month // use the last day of the month int year = 2000 + Convert.ToInt32(swiftData.Substring(0, 2)); int month = Convert.ToInt32(swiftData.Substring(2, 2)); int day = DateTime.DaysInMonth(year, month); SWIFTTransaction.valueDate = new DateTime(year, month, day); } swiftData = swiftData.Substring(6); if (char.IsDigit(swiftData[0])) { // Posting date (MMDD) int year = SWIFTTransaction.valueDate.Year; int month = Convert.ToInt32(swiftData.Substring(0, 2)); int day = Convert.ToInt32(swiftData.Substring(2, 2)); // Posting date 30 Dec 2017, Valuta date 1 Jan 2018 if (month > SWIFTTransaction.valueDate.Month && month == SWIFTTransaction.valueDate.AddMonths(-1).Month) { year--; } // Posting date 1 Jan 2018, Valuta date 30 Dec 2017 else if (month < SWIFTTransaction.valueDate.Month && month == SWIFTTransaction.valueDate.AddMonths(1).Month) { year++; } SWIFTTransaction.inputDate = new DateTime(year, month, day); swiftData = swiftData.Substring(4); } else { SWIFTTransaction.inputDate = SWIFTTransaction.valueDate; } // Debit or credit, or storno debit or credit int debitCreditIndicator = 0; if (swiftData[0] == 'R') { // Storno means: reverse the debit credit flag debitCreditIndicator = (swiftData[1] == 'D' ? 1 : -1); swiftData = swiftData.Substring(2); } else { debitCreditIndicator = (swiftData[0] == 'D' ? -1 : 1); swiftData = swiftData.Substring(1); } // Sometimes there is something about currency if (Char.IsLetter(swiftData[0])) { // Just skip it for the moment swiftData = swiftData.Substring(1); } // The amount, finishing with N SWIFTTransaction.amount = debitCreditIndicator * Convert.ToDecimal(swiftData.Substring(0, swiftData.IndexOf("N")).Replace(",", Thread.CurrentThread.CurrentCulture.NumberFormat.CurrencyDecimalSeparator)); SWIFTStatement.endBalance += SWIFTTransaction.amount; swiftData = swiftData.Substring(swiftData.IndexOf("N")); // Geschaeftsvorfallcode swiftData = swiftData.Substring(4); // The following sub fields are ignored // Optional: customer reference; ends with // // Optional: bank reference; ends with CR/LF // Something else about original currency and SWIFTTransaction fees SWIFTStatement.SWIFTTransactions.Add(SWIFTTransaction); } else if (swiftTag == "86") { SWIFTTransaction SWIFTTransaction = SWIFTStatement.SWIFTTransactions[SWIFTStatement.SWIFTTransactions.Count - 1]; // Geschaeftsvorfallcode SWIFTTransaction.typecode = swiftData.Substring(0, 3); swiftData = swiftData.Substring(3); if (swiftData.Length == 0) { return; } char separator = swiftData[0]; swiftData = swiftData.Substring(1); string[] elements = swiftData.Split(new char[] { separator }); string lastDescriptionSubfield = string.Empty; foreach (string element in elements) { int key = 0; string value = element; try { key = Convert.ToInt32(element.Substring(0, 2)); value = element.Substring(2); } catch { // If there is a question mark in the description, then we get here } if (key == 0) { // Buchungstext SWIFTTransaction.text = value; } else if (key == 10) { // Primanotennummer } else if ((key >= 11) && (key <= 19)) { // Ignore // Unknown meaning } else if ((key >= 20) && (key <= 29)) { // No space between description lines SWIFTTransaction.description += value; AssignDescriptionSubField(SWIFTTransaction, value, ref lastDescriptionSubfield); } else if (key == 30) { SWIFTTransaction.bankCode = value; } else if (key == 31) { SWIFTTransaction.accountCode = value; } else if ((key == 32) || (key == 33)) { SWIFTTransaction.partnerName += value; } else if (key == 34) { // Textschlüsselergänzung } else if ((key == 35) || (key == 36)) { // Empfängername SWIFTTransaction.description += value; } else if ((key >= 60) && (key <= 63)) { SWIFTTransaction.description += value; AssignDescriptionSubField(SWIFTTransaction, value, ref lastDescriptionSubfield); } else { // Unknown key return; } } } else if (swiftTag.StartsWith("62")) { // 62M: Finish page // 62F: Finish SWIFTStatement int debitCreditIndicator = (swiftData[0] == 'D' ? -1 : 1); swiftData = swiftData.Substring(1); // Posting date YYMMDD DateTime postingDate = new DateTime(2000 + Convert.ToInt32(swiftData.Substring(0, 2)), Convert.ToInt32(swiftData.Substring(2, 2)), Convert.ToInt32(swiftData.Substring(4, 2))); swiftData = swiftData.Substring(6); // Currency swiftData = swiftData.Substring(3); // Sometimes, this line is the last line, and it has -NULNULNUL at the end if (swiftData.Contains("-\0")) { swiftData = swiftData.Substring(0, swiftData.IndexOf("-\0")); } // End balance decimal shouldBeBalance = debitCreditIndicator * Convert.ToDecimal(swiftData.Replace(",", Thread.CurrentThread.CurrentCulture.NumberFormat.CurrencyDecimalSeparator)); SWIFTStatement.endBalance = Math.Round(SWIFTStatement.endBalance, 2); if (Convert.ToDecimal(Math.Round(SWIFTStatement.endBalance, 2)) != Convert.ToDecimal(shouldBeBalance)) { // End balance does not match return; } if (swiftTag == "62F" || swiftTag == "62M") { SWIFTStatement.date = postingDate; SWIFTStatements.Add(SWIFTStatement); SWIFTStatement = null; } } else if (swiftTag == "64") { // Valutensaldo } else if (swiftTag == "65") { // Future valutensaldo } else { // Unknown tag return; } }