Ejemplo n.º 1
0
        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);
            }
        }
Ejemplo n.º 2
0
        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);
        }
Ejemplo n.º 3
0
        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;
            }
        }