Esempio n. 1
0
 public static IList <Field23C> getAll(SwiftMessage msg)
 {
     if (msg == null || msg.Block4 == null || msg.Block4.Empty)
     {
         return(java.util.Collections.emptyList());
     }
     return(getAll(msg.Block4));
 }
Esempio n. 2
0
 public static Field23C get(SwiftMessage msg)
 {
     if (msg == null || msg.Block4 == null || msg.Block4.Empty)
     {
         return(null);
     }
     return(get(msg.Block4));
 }
Esempio n. 3
0
        public void Check_Tag57D()
        {
            string str;
            string value = "";

            using (StreamReader sr = File.OpenText(sample202))
            {
                str = sr.ReadToEnd();
            }

            SwiftMessage message = new SwiftMessage();

            message.ParseSwiftMessage(str.Trim());

            foreach (var block in message.Block4)
            {
                if (block.TagName == "57D")
                {
                    value = block.Value;
                }
            }
            Assert.AreEqual("FW021000ABA", value);
        }
Esempio n. 4
0
        public override void Parse()
        {
            base.ParseApplicationHeaderBlock();

            MT535Activity statementItem = new MT535Activity();

            try {
                string[] lines = SwiftMessage.Lines(source);

                bool gotAcc = false;
                int  stmtNo = 1;
                // Note on SWIFT tag....
                // Tag: 35B = Security ID (ISIN) and name
                // Tag: 93B = Balance
                foreach (string stmtLine in lines)
                {
                    string tag      = (stmtLine.Substring(1, 2));
                    int    startPos = -1;
                    int    endPos   = -1;


                    int bicBlockStartPos = stmtLine.IndexOf("{2:");
                    if (bicBlockStartPos != -1)   // the header block that contains the bic
                    {
                        StatementNo   = stmtNo++; // tag 13a is statement number but is optional and cant rely on it being sent
                        SenderAddress = stmtLine.Substring(bicBlockStartPos + 17, 12);
                    }
                    else if (stmtLine.Contains(":28E:"))    // page number, this should be unique across messages(pages)
                    {
                        var len = stmtLine.IndexOf("/") - 5;
                        StatementNo = int.Parse(stmtLine.Substring(5, len));
                    }
                    else if (stmtLine.Contains(":98A::STAT"))   // statement date line
                    {
                        #region Field 98a: Date/Time

                        /*
                         * FORMAT
                         * Option A :4!c//8!n - (Qualifier)(Date)
                         * Option C :4!c//8!n6!n - (Qualifier)(Date)(Time)
                         * Option E :4!c//8!n6!n[,3n][/[N]2!n[2!n]] - (Qualifier)(Date)(Time)(Decimals)(UTC Indicator)
                         *
                         * DEFINITION
                         * This qualified generic field specifies:
                         *
                         * PREP -  (Preparation Date/Time)   Date/time at which the message was prepared.
                         * STAT -  (Statement Date/Time) Date/time on which the statement is based (reflecting the situation at that date/time).
                         *
                         * NETWORK VALIDATED RULES
                         * Date must be a valid date expressed as YYYYMMDD (Error code(s): T50).
                         *
                         * Time must be a valid time expressed as HHMMSS (Error code(s): T38).
                         *
                         */

                        #endregion

                        Date = DateTime.ParseExact(stmtLine.Substring(stmtLine.Length - 8), "yyyyMMdd", new CultureInfo("en-GB")).Date;
                        if (DateTime.Now.Subtract(Date).TotalDays > 730135)
                        {
                            // Nearly 2,000 years ago. Must have been a two year date
                            Date = DateTime.ParseExact(stmtLine.Substring(stmtLine.Length - 6), "yyMMdd", new CultureInfo("en-GB")).Date;
                        }
                    }
                    else if (tag == "97")    // Account number
                    {
                        #region Field 97a: Account: Safekeeping Account

                        /*
                         * FORMAT
                         * Option A :4!c//35x (Qualifier)(Account Number)
                         * Option B :4!c/[8c]/4!c/35x (Qualifier)(Data Source Scheme)(Account Type Code)(Account Number)
                         *
                         * DEFINITION
                         * This qualified generic field specifies:
                         *
                         * SAFE - (Safekeeping Account) Account where financial instruments are maintained.
                         *
                         * In option B, Account Type Code specifies the type of account needed to fully identify the account.
                         *
                         * CODES
                         * In option B, the Data Source Scheme must be present and Account Type Code must contain the type of account as defined by the party identified in the Data Source Scheme.
                         *
                         */

                        #endregion

                        int accNoStart = stmtLine.IndexOf("//") + 2;
                        AccountNumber = stmtLine.Substring(accNoStart);
                        gotAcc        = true;
                    }
                    else if (stmtLine.Contains(":20C::SEME"))   // sender unique reference
                    {
                        SenderReference = stmtLine.Substring(12);
                    }
                    else if (tag == "35" && gotAcc)    // Statement Line found
                    {
                        #region Field 35B: Identification of the Financial Instrument

                        /*
                         * FORMAT
                         * Option B [ISIN1!e12!c] - (Identification of Security)
                         * [4*35x] - (Description of Security)
                         *
                         * PRESENCE
                         * Mandatory in optional subsequence B1
                         *
                         * DEFINITION
                         * This field identifies the financial instrument.
                         *
                         * NETWORK VALIDATED RULES
                         * At least Identification of a Security (Subfield 1) or Description of Security (Subfield 2) must be present; both may be present (Error code(s): T17).
                         *
                         * ISIN is used at the beginning of Identification of Security (Subfield 1) and must be composed of uppercase letters only (Error code(s): T12).
                         *
                         * USAGE RULES
                         * When used in Description of Security (Subfield 2), codes must start and end with a slash '/'.
                         *
                         * When an ISIN identifier is not used it is strongly recommended that one of the following codes be used as the first four characters of the Description of Security (Subfield 2):
                         *
                         * [/2!a/] - The ISO two-digit country code, followed by the national scheme number.
                         *
                         * [/TS/] - Followed by the ticker symbol.
                         *
                         * [/XX/] - Bilaterally agreed or proprietary scheme which may be further identified by a code or short description identifying the scheme used.
                         *
                         * It is strongly recommended that the ISIN be used.
                         *
                         */
                        #endregion



                        startPos = stmtLine.IndexOf("ISIN", 1);
                        int posToAdd = 4;
                        if (startPos == -1)
                        {
                            startPos = stmtLine.IndexOf("ID", 1);
                            posToAdd = 2;
                        }
                        string isin    = "";
                        string secName = "";
                        if (startPos != -1) // ISIN
                        {
                            startPos = startPos + posToAdd;

                            if (stmtLine[startPos] == ' ')  // sometimes a space comes before the actual isin
                            {
                                startPos = startPos + 1;
                            }

                            //H.A. Had to change this because ISIN and Description were being read on the same line, even though the .out file appears on seperate lines.
                            //i.Identifiers.Add("ISIN", val.Substring(startPos, endPos - startPos).Trim());
                            isin = stmtLine.Substring(startPos, 12).Trim();

                            startPos = startPos + 12;
                            secName  = stmtLine.Substring(startPos, stmtLine.Length - startPos).Trim(); // in case we want it
                        }
                        else                                                                            // No ISIN found so simply use the other code plus description as name and ISIN
                        {
                            startPos = 5;                                                               // ignore the
                            secName  = stmtLine.Substring(startPos);
                            isin     = secName;
                        }

                        statementItem = new MT535Activity {
                            SecurityIdentifier = isin,
                            Description        = secName
                        };
                    }
                    else if (tag == "93" && gotAcc)
                    {
                        #region Field 93B: Balance

                        /*
                         * FORMAT
                         * Option B :4!c/[8c]/4!c/[N]15d - (Qualifier)(Data Source Scheme)(Quantity Type Code)(Sign)(Balance)
                         *
                         * DEFINITION
                         * This qualified generic field specifies:
                         *
                         * AGGR
                         * Aggregate Balance
                         * Total quantity of financial instruments for the referenced holding.
                         *
                         * AVAI
                         * Available Balance
                         * Total quantity of financial instruments of the aggregate balance that is available.
                         *
                         * NAVL
                         * Not Available Balance
                         * Total quantity of financial instruments of the aggregate balance that is NOT available.
                         *
                         * CODES
                         * If Data Source Scheme is not present, Quantity Type Code must contain one of the following codes (Error code(s): K93):
                         *
                         * AMOR
                         * Amortised Value
                         * Quantity expressed as an amount representing the current amortised face amount of a bond, for example, a periodic reduction/increase of a bond's principal amount.
                         *
                         * FAMT
                         * Face Amount
                         * Quantity expressed as an amount representing the face amount, that is, the principal, of a debt instrument.
                         *
                         * UNIT
                         * Unit Number
                         * Quantity expressed as a number, for example, a number of shares.
                         *
                         *
                         * NETWORK VALIDATED RULES
                         * The integer part of Balance must contain at least one digit. A decimal comma ',' is mandatory and is included in the maximum length (Error code(s): T40, T43).
                         *
                         * When Sign is present, Balance must not be zero (Error code(s): T14).
                         *
                         * USAGE RULES
                         * Sign must be present only when Balance is negative.
                         *
                         * If the Available Balance and Not Available Balance are both provided, the total of the Available Balance and the Not Available Balance must equal the Aggregate Balance provided in the same sequence.
                         *
                         */

                        #endregion

                        if (stmtLine.Contains("AGGR")) // HA 25.11.08 - Added as sometimes other balances are sent too, such as AVAI & NAVL
                        {
                            // This only needs adding once for each security found. AGGR may however appear twice
                            if (statementItem != null)
                            {
                                startPos = stmtLine.LastIndexOf("/", stmtLine.Length - 1);
                                endPos   = stmtLine.IndexOf(",");
                                if (startPos == -1)
                                {
                                    throw new Exception("The SWIFT code 93 does not contain an balance identifier, please check. \r\n" +
                                                        "LINE:  " + stmtLine);
                                }
                                else
                                {
                                    startPos++;
                                    switch (stmtLine.Substring(startPos, 1).ToUpper())
                                    {
                                    case "N":      // Negative amount
                                        statementItem.AggrBalance = Convert.ToDouble(stmtLine.Substring(startPos + 1, endPos - startPos).Trim()) * -1;
                                        break;

                                    default:
                                        statementItem.AggrBalance = Convert.ToDouble(stmtLine.Substring(startPos, endPos - startPos).Trim());
                                        break;
                                    }
                                }
                                MT535Activities.Add(statementItem);  // Add to list of items
                                statementItem = null;
                            }
                        }
                    }
                }
            } catch (Exception e) {
                throw new Exception("Error caught in MT535 Parse method.\r\n" + e.Message + "\r\n", e);
            }
        }
Esempio n. 5
0
        public override void Parse()
        {
            base.ParseApplicationHeaderBlock();

            try {
                string[] lines = SwiftMessage.Lines(source);
                string   tag = "", previousTag = "";

                foreach (string stmtLine in lines)
                {
                    string settDate    = "";
                    string amount      = "";
                    string description = "";
                    previousTag = tag;

                    try {
                        if (stmtLine.Length > 3)
                        {
                            tag = (stmtLine.Substring(1, 3));
                        }
                        else
                        {
                            tag = "n/a";
                        }
                    } catch (Exception ex) {
                        Program.Log(ex.Message, true, ConsoleColor.Red);
                    }
                    // Tags we look for = 25, 28C, 60F, 60M, 61, 62F, 62M, 64

                    if (tag.Contains("25"))  // Account info
                    {
                        #region  Field 25: Account Identification

                        /*
                         * FORMAT
                         * 35x (Account)
                         *
                         * Presence
                         * Mandatory
                         *
                         * Definition
                         * This field identifies the account for which the statement is sent.
                         *
                         */

                        #endregion

                        AccountNumber = stmtLine.Substring(4);
                    }
                    else if (tag.Contains("28C"))
                    {
                        #region Field 28C: Statement Number/Sequence Number

                        /*
                         * Format
                         * Option C 5n[/5n] (Statement Number)(Sequence Number)
                         *
                         * Presence
                         * Mandatory
                         *
                         * Definition
                         * This field contains the sequential number of the statement, optionally followed by the sequence number of the message within that statement when more than one message is sent for one statement.
                         *
                         * Usage Rules
                         * The statement number should be reset to 1 on 1 January of each year.
                         *
                         * If used, the sequence number always starts with 1. When several messages are sent to convey information about a single statement, the first message must contain '/1' in Sequence Number.
                         *
                         * The sequence number must be incremented by one for each additional message.
                         *
                         * Both the statement number and sequence number enable the Receiver to put the different messages into sequence and thus form the complete statement.
                         *
                         * Example
                         * The first message of a statement is :28C:235/1
                         *
                         * The second message is :28C:235/2 and so on.
                         *
                         */

                        #endregion

                        int seperatorIndex = stmtLine.IndexOf("/");
                        if (seperatorIndex != -1)
                        {
                            StatementNo = Convert.ToInt32(stmtLine.Substring(5, seperatorIndex - 5));
                            SequenceNo  = Convert.ToInt32(stmtLine.Substring(seperatorIndex + 1, stmtLine.Length - seperatorIndex - 1));
                        }
                        else
                        {
                            StatementNo = Convert.ToInt32(stmtLine.Substring(5));
                            SequenceNo  = 1; // if none present then there must just be one message in the statement
                        }
                    }
                    else if ((tag.Contains("60F") || tag.Contains("60M")))    // Opening/intermediate balance found (containing ccy)
                    {
                        #region Field 60a: Opening Balance

                        /*
                         * Format
                         * Option F 1!a6!n3!a15d - (D/C Mark)(Date)(Currency)(Amount)
                         * Option M 1!a6!n3!a15d - (D/C Mark)(Date)(Currency)(Amount)
                         *
                         *
                         * Presence
                         * Mandatory
                         *
                         * Definition
                         * This field specifies, for the (intermediate) opening balance, whether it is a debit or credit balance, the date, the currency and the amount of the balance.
                         *
                         * Codes
                         * In option F, or M, D/C Mark must contain one of the following codes (Error code(s): T51):
                         *
                         * C
                         * The (intermediate) opening balance is a credit balance
                         *
                         * D
                         * The (intermediate) opening balance is a debit balance
                         *
                         *
                         * Network Validated Rules
                         * Date must be a valid date expressed as YYMMDD (Error code(s): T50).
                         *
                         * Currency must be a valid ISO 4217 currency code (Error code(s): T52).
                         *
                         * The integer part of Amount must contain at least one digit. The decimal comma ',' is mandatory and is included in the maximum length. The number of digits following the comma must not exceed the maximum number allowed for the specified currency (Error code(s): C03, T40, T43).
                         *
                         * Usage Rules
                         * This field must always be the same as field 62a (closing balance) of the previous statement message for this account.
                         *
                         * The first statement message for a specified period must contain field 60F (first opening balance); additional statement messages for the same statement period must contain field 60M (intermediate opening balance).
                         *
                         */

                        #endregion


                        // currency is only stored in the opening and closing balance lines.
                        // We can then assume, that everthing in between is of that currency too.

                        //swiftStatement.OpeningBalance.Date = Convert.ToDateTime(val.Substring(6, 6));
                        Currency       = stmtLine.Substring(12, 3);
                        OpeningBalance = ExtractBalance(stmtLine);
                    }
                    else if (tag == "61:")    // Statement Line found
                    {
                        #region Field 61: Statement Line

                        /*
                         * Format
                         * 6!n[4!n]2a[1!a]15d1!a3!c16x[//16x]
                         * [34x]
                         *
                         * where subfields are:
                         *
                         * Subfield
                         * Format
                         * Name
                         *
                         * 1 6!n (Value Date)
                         * 2 [4!n] (Entry Date)
                         * 3 2a (Debit/Credit Mark)
                         * 4 [1!a] (Funds Code)
                         * 5 15d (Amount)
                         * 6 1!a3!c (Transaction Type Identification Code)
                         * 7 16x (Reference for the Account Owner)
                         * 8 [//16x]
                         * (Account Servicing Institution's Reference)
                         *
                         * 9 [34x] (Supplementary Details)
                         *
                         *
                         * Presence
                         * Optional
                         *
                         * Definition
                         * This field contains the details of each transaction.
                         *
                         * Subfield 1 Value Date is a date expressed in full ISO 8601 format YYMMDD.
                         *
                         * Subfield 2 Entry Date is a date expressed in reduced ISO 8601 format MMDD.
                         *
                         * Subfield 4 Funds Code is the 3rd character of the currency code, if needed.
                         *
                         * Codes
                         * Subfield 3 Debit/Credit Mark must contain one of the following codes (Error code(s): T51):
                         *
                         * C
                         * Credit
                         *
                         * D
                         * Debit
                         *
                         * RC
                         * Reversal of Credit (debit entry)
                         *
                         * RD
                         * Reversal of Debit (credit entry)
                         *
                         *
                         * Codes
                         * Subfield 6 Transaction Type Identification Code must contain one of the following codes (Error code(s): T53):
                         *
                         * S
                         * 3!n
                         * For entries related to SWIFT transfer instructions and subsequent charge messages. The last three characters will indicate the message type of the SWIFT message causing the entry (for debit entries) or the message type of the SWIFT message used to advise the account owner (for credit entries).
                         *
                         * N
                         * 3!c
                         * For entries related to payment and transfer instructions, including related charges messages, not sent through SWIFT or where an alpha description is preferred. The last three characters, that is, 3!c, may contain a code (see below).
                         *
                         * F
                         * 3!c
                         * For entries being first advised by the statement (items originated by the account servicing institution). The last three characters, that is, 3!c, may contain a code (see below).
                         *
                         *
                         * Codes
                         * When the first character of subfield 6 Transaction Type Identification Code is 'N' or 'F', the remaining characters may contain one of the following codes:
                         *
                         * BNK
                         * Securities Related Item - Bank Fees
                         *
                         * BOE
                         * Bill of Exchange
                         *
                         * BRF
                         * Brokerage Fee
                         *
                         * CAR
                         * Securities Related Item - Corporate Actions Related (should only be used when no specific corporate action event code is available)
                         *
                         * CAS
                         * Securities Related Item - Cash in Lieu
                         *
                         * CHG
                         * Charges and Other Expenses
                         *
                         * CHK
                         * Cheques
                         *
                         * CLR
                         * Cash Letters/Cheques Remittance
                         *
                         * CMI
                         * Cash Management Item - No Detail
                         *
                         * CMN
                         * Cash Management Item - Notional Pooling
                         *
                         * CMP
                         * Compensation Claims
                         *
                         * CMS
                         * Cash Management Item - Sweeping
                         *
                         * CMT
                         * Cash Management Item -Topping
                         *
                         * CMZ
                         * Cash Management Item - Zero Balancing
                         *
                         * COL
                         * Collections (used when entering a principal amount)
                         *
                         * COM
                         * Commission
                         *
                         * CPN
                         * Securities Related Item - Coupon Payments
                         *
                         * DCR
                         * Documentary Credit (used when entering a principal amount)
                         *
                         * DDT
                         * Direct Debit Item
                         *
                         * DIS
                         * Securities Related Item - Gains Disbursement
                         *
                         * DIV
                         * Securities Related Item - Dividends
                         *
                         * EQA
                         * Equivalent Amount
                         *
                         * EXT
                         * Securities Related Item - External Transfer for Own Account
                         *
                         * FEX
                         * Foreign Exchange
                         *
                         * INT
                         * Interest
                         *
                         * LBX
                         * Lock Box
                         *
                         * LDP
                         * Loan Deposit
                         *
                         * MAR
                         * Securities Related Item - Margin Payments/Receipts
                         *
                         * MAT
                         * Securities Related Item - Maturity
                         *
                         * MGT
                         * Securities Related Item - Management Fees
                         *
                         * MSC
                         * Miscellaneous
                         *
                         * NWI
                         * Securities Related Item - New Issues Distribution
                         *
                         * ODC
                         * Overdraft Charge
                         *
                         * OPT
                         * Securities Related Item - Options
                         *
                         * PCH
                         * Securities Related Item - Purchase (including STIF and Time deposits)
                         *
                         * POP
                         * Securities Related Item - Pair-off Proceeds
                         *
                         * PRN
                         * Securities Related Item - Principal Pay-down/Pay-up
                         *
                         * REC
                         * Securities Related Item - Tax reclaim
                         *
                         * RED
                         * Securities Related Item - Redemption/Withdrawal
                         *
                         * RIG
                         * Securities Related Item - Rights
                         *
                         * RTI
                         * Returned Item
                         *
                         * SAL
                         * Securities Related Item - Sale (including STIF and Time deposits)
                         *
                         * SEC
                         * Securities (used when entering a principal amount)
                         *
                         * SLE
                         * Securities Related Item - Securities Lending Related
                         *
                         * STO
                         * Standing Order
                         *
                         * STP
                         * Securities Related Item - Stamp Duty
                         *
                         * SUB
                         * Securities Related Item - Subscription
                         *
                         * SWP
                         * Securities Related Item - SWAP Payment
                         *
                         * TAX
                         * Securities Related Item - Withholding Tax Payment
                         *
                         * TCK
                         * Travellers Cheques
                         *
                         * TCM
                         * Securities Related Item - Tripartite Collateral Management
                         *
                         * TRA
                         * Securities Related Item - Internal Transfer for Own Account
                         *
                         * TRF
                         * Transfer
                         *
                         * TRN
                         * Securities Related Item - Transaction Fee
                         *
                         * UWC
                         * Securities Related Item - Underwriting Commission
                         *
                         * VDA
                         * Value Date Adjustment (used with an entry made to withdraw an incorrectly dated entry - it will be followed by the correct entry with the relevant code)
                         *
                         * WAR
                         * Securities Related Item - Warrant
                         *
                         *
                         * Network Validated Rules
                         * Subfield 1, Value Date, must be a valid date expressed as YYMMDD (Error code(s): T50).
                         *
                         * The SWIFT System validates subfield 2, Entry Date (Date in reduced ISO form MMDD), using current System Year (Error code(s): T50).
                         *
                         * The integer part of Amount must contain at least one digit. The decimal comma ',' is mandatory and is included in the maximum length (Error code(s): T40, T43).
                         *
                         * When the first character of subfield 6, Transaction Type Identification Code, is an 'S', the remaining characters must be in the range 100-999 (Error code(s): T18).
                         *
                         * Usage Rules
                         * This field may be repeated within the constraints of the maximum input message length.
                         *
                         * 'Original' advice for charges, that is, the first time the account owner is informed of a charge, must be identified in subfield 6, Transaction Type Identification Code, with the transaction type code 'FCHG'.
                         *
                         * The following rules apply to subfield 7, Reference for the Account Owner:
                         *
                         * At least one valid character other than a blank must be present.
                         *
                         * For debit entries, the purpose of this subfield is to identify, to the account owner, the instruction which caused the debit. Therefore, the content of this subfield is the field 20 Sender's Transaction Reference Number (or its equivalent) of the original instruction.
                         *
                         * Credit entries may be the result of one of the following situations:
                         *
                         * The account servicing institution is identifying, to the account owner the receipt of funds for its account as a result of a related transaction. In this case, the content of subfield 7, Reference for the Account Owner is the reference for the beneficiary (for example, field 21 Related Reference) of the related transaction.
                         *
                         * The account servicing institution has issued a payment instruction to the account owner and the credit identified in this subfield is for that payment. The content of subfield 7, Reference for the Account Owner is the field 20 Transaction Reference Number (or its equivalent) of the payment instruction issued by the account servicing institution.
                         *
                         * If no reference is available for subfield 7, Reference for the Account Owner, the code NONREF shall be used. The account servicing institution must then supply, in subfield 9, Supplementary Details, what it considers to be the best alternative information.
                         *
                         * This reference must be quoted in all cases when available. In cases where a transaction passes through several financial institutions, the original reference must always be forwarded.
                         *
                         * This reference must always be quoted against any charges or fees debited by the account servicing institution.
                         *
                         * Debits against standing instructions must show the reference of the standing instruction.
                         *
                         * In cases where a mutually agreed alternative reference exists (for example, in foreign exchange or money market transactions), this reference should then be used.
                         *
                         * If the statement entry concerns a cheque, the cheque number should be indicated in this subfield.
                         *
                         * The following rules apply to subfield 8, Account Servicing Institution's Reference:
                         *
                         * The content of this subfield is the account servicing institution's own reference for the transaction.
                         *
                         * When the transaction has been initiated by the account servicing institution, this reference may be identical to subfield 7, Reference for the Account Owner. If this is the case, Account Servicing Institution's Reference, subfield 8 may be omitted.
                         *
                         * The following rules apply to subfield 9, Supplementary Details:
                         *
                         * When no reference for the account owner is available, that is, subfield 7, Reference for the Account Owner contains NONREF, the account servicing institution should provide the best available alternative information in this subfield.
                         *
                         * Supplementary details may be provided when an advice has not been sent for a transaction, or to provide additional information to facilitate reconciliation.
                         *
                         * Example
                         * (1) :61:0901230122C3500,25FCHK304955//4958843
                         *
                         * (2) :61:0901230122C3500,25FCHK304955//4958843
                         * ADDITIONAL INFORMATION
                         *
                         */

                        #endregion


                        // Date is in US format and from index 5 to 10 (i.e. :61:070328)
                        settDate = stmtLine.Substring(8, 2) + "/" + stmtLine.Substring(6, 2) + "/" + stmtLine.Substring(4, 2);

                        //Find the Debit/Credit Mark :-
                        //  D/DR = Debit,
                        //  C/CR = Credit,
                        //  RD = Reversal of Debit (Credit Entry),
                        //  RC = Reversal of Credit (Debit Entry)

                        int tempCount = stmtLine.IndexOf(","); // the comma is the decimal part of the amount which is always there.

                        // GH 201000422 the start pos could be after 14 or 10
                        int startPos = -1;
                        // try the 14th pos as that is the usual start point
                        bool ok = DetermineStartPos(14, stmtLine, ref amount, ref startPos);
                        // and if that does not work then try the 10th pos
                        if (!ok)
                        {
                            ok = DetermineStartPos(10, stmtLine, ref amount, ref startPos);
                        }
                        // and if that does not work report an error
                        if (!ok)
                        {
                            throw new Exception("The SWIFT code 61 does not contain a Credit/Debit identifier, please check. \r\n" +
                                                "LINE:  " + stmtLine);
                        }

                        int endPos = stmtLine.IndexOf(",");
                        // We only want the numbers so don't include the DR or CR characters
                        //startPos += 2;

                        // Sometimes we get CR/DR sometimes we just get C/D, so just replace if they exist.
                        //amount = amount + val.Substring(startPos, endPos - startPos).Trim(("DCR").ToCharArray());
                        amount = amount + stmtLine.Substring(startPos, endPos - startPos);

                        string dec = "";
                        // Anything after decimal place
                        int  decInt = 0;
                        bool isnum  = Int32.TryParse(stmtLine.Substring(stmtLine.IndexOf(",") + 1, 1), out decInt); // do we have 1 dp
                        if (isnum)                                                                                  //first one is a number so store and look for the next
                        {
                            dec   = decInt.ToString();
                            isnum = Int32.TryParse(stmtLine.Substring(stmtLine.IndexOf(",") + 2, 1), out decInt);  // do we have a 2nd dp
                            if (isnum)
                            {
                                dec = dec + decInt.ToString();  // if so then set it
                            }
                        }

                        amount = amount + "." + dec;

                        endPos += dec.Length + 1;


                        description = stmtLine.Substring(endPos, stmtLine.Length - endPos).Trim();

                        // Create the recItem
                        MT950Activity swiftItem = new MT950Activity {
                            Amount      = Convert.ToDouble(amount),
                            Description = description,
                            ValueDate   = Convert.ToDateTime(settDate)
                        };

                        MT950Activities.Add(swiftItem);
                    }
                    else if (tag == "86:")   // Description appendage to Tag 61
                    {
                        if (previousTag == "61:")
                        {
                            MT950Activity activity = MT950Activities[MT950Activities.Count - 1]; // last activity added
                            activity.Description += ".  " + stmtLine.Substring(4);
                        }
                    }
                    else if ((tag == "62F" || tag == "62M"))    // using either final or intermediate as we store both now
                    {
                        #region Field 62a: Closing Balance (Booked Funds)

                        /*
                         * Format
                         * Option F 1!a6!n3!a15d (D/C Mark)(Date)
                         * (Currency)(Amount)
                         * Option M 1!a6!n3!a15d (D/C Mark)(Date)
                         * (Currency)(Amount)
                         *
                         *
                         * Presence
                         * Mandatory
                         *
                         * Definition
                         * This field specifies, for the (intermediate) closing balance, whether it is a debit or credit balance, the date, the currency and the amount of the balance.
                         *
                         * Codes
                         * In option F, or M, D/C Mark must contain one of the following codes (Error code(s): T51):
                         *
                         * C
                         * The (intermediate) closing balance is a credit balance
                         *
                         * D
                         * The (intermediate) closing balance is a debit balance
                         *
                         *
                         * Network Validated Rules
                         * Date must be a valid date expressed as YYMMDD (Error code(s): T50).
                         *
                         * Currency must be a valid ISO 4217 currency code (Error code(s): T52).
                         *
                         * The integer part of Amount must contain at least one digit. The decimal comma ',' is mandatory and is included in the maximum length. The number of digits following the comma must not exceed the maximum number allowed for the specified currency (Error code(s): C03, T40, T43).
                         *
                         * Usage Rules
                         * The contents of this field will be repeated in field 60a of the subsequent statement message for this account.
                         *
                         * If there is only one statement message transmitted for the period, this field must use tag option F, that is, 62F (final closing balance). When several messages are transmitted for the same statement period, all messages except the last message must contain field 62M (intermediate closing balance); the last message of the statement must contain field 62F.
                         *
                         */

                        #endregion


                        // tag found but it must be the last one in the file, so overwrite if found

                        //get the balance date
                        string dateStr = stmtLine.Substring(10, 2) + "/" + stmtLine.Substring(8, 2) + "/" + stmtLine.Substring(6, 2);

                        Date = Convert.ToDateTime(dateStr); // date of the closing balance is statement date

                        try {
                            ClosingBalance = ExtractBalance(stmtLine);
                        } catch (Exception ex) {
                            ClosingBalance = -1.1;
                            throw new Exception("Balance couldn't be updated: \r\n" + ex.Message, ex);
                        }
                    }
                    else if (tag == "64:")    // use 64 if it is present (it is an optional tag)  - available funds
                    {
                        #region Field 64: Closing Available Balance (Available Funds)

                        /*
                         * Format
                         * 1!a6!n3!a15d (D/C Mark)(Date)(Currency)(Amount)
                         *
                         *
                         * Presence
                         * Optional
                         *
                         * Definition
                         * This field indicates the funds which are available to the account owner (if credit balance) or the balance which is subject to interest charges (if debit balance).
                         *
                         * Codes
                         * D/C Mark must contain one of the following codes (Error code(s): T51):
                         *
                         * C
                         * The closing available balance is a credit balance
                         *
                         * D
                         * The closing available balance is a debit balance
                         *
                         *
                         * Network Validated Rules
                         * Date must be a valid date expressed as YYMMDD (Error code(s): T50).
                         *
                         * Currency must be a valid ISO 4217 currency code (Error code(s): T52).
                         *
                         * The integer part of Amount must contain at least one digit. The decimal comma ',' is mandatory and is included in the maximum length. The number of digits following the comma must not exceed the maximum number allowed for the specified currency (Error code(s): C03, T40, T43).
                         *
                         */

                        #endregion


                        string dateStr = stmtLine.Substring(9, 2) + "/" + stmtLine.Substring(7, 2) + "/" + stmtLine.Substring(5, 2);

                        Date = Convert.ToDateTime(dateStr); // date of the closing balance is statement date

                        try {
                            ClosingBalance = ExtractBalance(stmtLine);
                        } catch (Exception ex) {
                            ClosingBalance = -1.1;
                            throw new Exception("Balance couldn't be updated: \r\n" + ex.Message, ex);
                        }
                    }
                }
            } catch (Exception e) {
                throw new Exception("Error caught in MT950 Parse method.\r\n" + e.Message + "\r\n", e);
            }
        }
Esempio n. 6
0
        public void GetSwiftMessage_SwiftFileOutput_ReturnSwiftMessage()
        {
            string messageText = "";

            using (StreamReader stream = new StreamReader(@"..\..\..\SwiftFiles\GetSwiftMessage_SwiftFileOutput_ReturnSwiftMessage"))
            {
                messageText = stream.ReadToEnd();
            }
            SwiftMessage swiftMessage = new SwiftMessage()
            {
                Block1 = new SwiftBlock1()
                {
                    ApplicationId          = "F",
                    ServiceId              = "01",
                    LogicalTerminalAddress = "TESTBIC12XXX",
                    SessionNumber          = "0360",
                    SequenceNumber         = "105154",
                },
                Block2 = new SwiftBlock2Output()
                {
                    Direction             = Direction.Output,
                    MessageType           = "564",
                    InputTime             = "1057",
                    MessageInputReference = new MessageInputReference()
                    {
                        InputDate = "130214",
                        LogicalTerminalAddress = "TESTBIC34XXX",
                        SessionNumber          = "2626",
                        SequenceNumber         = "493828"
                    },
                    ReceiverOutputDate = "130214",
                    ReceiverOutputTime = "1757",
                    MessagePriority    = "N"
                },
                Block3 = new SwiftBlock3()
                {
                    new SwiftTag("103", "CAD"),
                    new SwiftTag("108", "2RDRQDHM3WO"),
                },
                Block4 = new SwiftBlock4()
                {
                    new SwiftTag("16R", "GENL"),
                    new SwiftTag("20C", ":CORP//1234567890123456"),
                    new SwiftTag("20C", ":SEME//9876543210987654"),
                    new SwiftTag("23G", "NEWM"),
                    new SwiftTag("22F", ":CAEV//INTR"),
                    new SwiftTag("22F", ":CAMV//MAND"),
                    new SwiftTag("98C", ":PREP//20220202105733"),
                    new SwiftTag("25D", ":PROC//ENTL"),
                    new SwiftTag("16S", "GENL"),
                    new SwiftTag("16R", "USECU"),
                    new SwiftTag("35B", "ISIN CH0101010101\r\n/XS/232323232\r\nFINANCIAL INSTRUMENT ACME"),
                    new SwiftTag("16R", "FIA"),
                    new SwiftTag("22F", ":MICO//A007"),
                    new SwiftTag("16S", "FIA"),
                    new SwiftTag("16R", "ACCTINFO"),
                    new SwiftTag("97A", ":SAFE//99999"),
                    new SwiftTag("94F", ":SAFE//NCSD/TESTBIC0ABC"),
                    new SwiftTag("93B", ":ELIG//FAMT/500000,"),
                    new SwiftTag("93B", ":SETT//FAMT/500000,"),
                    new SwiftTag("16S", "ACCTINFO"),
                    new SwiftTag("16S", "USECU"),
                    new SwiftTag("16R", "CADETL"),
                    new SwiftTag("98A", ":ANOU//20220113"),
                    new SwiftTag("98A", ":RDTE//20220113"),
                    new SwiftTag("69A", ":INPE//20220214/20220214"),
                    new SwiftTag("99A", ":DAAC//360"),
                    new SwiftTag("92K", ":INTR//UKWN"),
                    new SwiftTag("22F", ":ADDB//CAPA"),
                    new SwiftTag("16S", "CADETL"),
                    new SwiftTag("16R", "CAOPTN"),
                    new SwiftTag("13A", ":CAON//001"),
                    new SwiftTag("22F", ":CAOP//CASH"),
                    new SwiftTag("11A", ":OPTN//USD"),
                    new SwiftTag("17B", ":DFLT//Y"),
                    new SwiftTag("16R", "CASHMOVE"),
                    new SwiftTag("22H", ":CRDB//CRED"),
                    new SwiftTag("22H", ":CONT//ACTU"),
                    new SwiftTag("97A", ":CASH//89898"),
                    new SwiftTag("19B", ":ENTL//USD3333,"),
                    new SwiftTag("19B", ":TXFR//USD3333,"),
                    new SwiftTag("19B", ":NETT//USD3333,"),
                    new SwiftTag("98A", ":PAYD//20220214"),
                    new SwiftTag("98A", ":VALU//20220214"),
                    new SwiftTag("98A", ":EARL//20220214"),
                    new SwiftTag("92A", ":INTP//0,75"),
                    new SwiftTag("92A", ":TAXR//0,"),
                    new SwiftTag("16S", "CASHMOVE"),
                    new SwiftTag("16S", "CAOPTN"),
                    new SwiftTag("16R", "ADDINFO"),
                    new SwiftTag("70E", ":ADTX//PAYMENT UPON RECEIPT OF FUNDS - \r\nTIMELY PAYMENT EXPECTED"),
                    new SwiftTag("16S", "ADDINFO"),
                },
                Block5 = new SwiftBlock5()
                {
                    new SwiftTag("CHK", "C77F8E009597")
                }
            };
            SwiftParser parser = new SwiftParser();
            var         result = parser.GetSwiftMessage(messageText);

            Assert.AreEqual(result, swiftMessage);
        }
Esempio n. 7
0
        public override void Parse()
        {
            base.ParseApplicationHeaderBlock();

            try
            {
                string[] lines = SwiftMessage.Lines(source);

                bool boughtSection = true; // bought section is the first Subsequence B1 section
                foreach (string line in lines)
                {
                    string tag = line.Substring(1, 3).ToUpper();

                    switch (tag)
                    {
                    case "20:":
                        SenderReference = line.Substring(4);
                        break;

                    case "22A":
                        TypeOfOperation = line.Substring(5);
                        break;

                    case "22C":
                        CommonReference = line.Substring(5);
                        break;

                    case "82A":
                        PartyA = line.Substring(5);
                        break;

                    case "87A":
                        PartyB = line.Substring(5);
                        break;

                    case "30T":
                        // Date is in US format and from index 5 to 10 (i.e. :61:070328)
                        TradeDate = DateTime.Parse(line.Substring(11, 2) + "/" + line.Substring(9, 2) + "/" + line.Substring(5, 4));
                        break;

                    case "30V":
                        ValueDate = DateTime.Parse(line.Substring(11, 2) + "/" + line.Substring(9, 2) + "/" + line.Substring(5, 4));
                        break;

                    case "36:":
                        ExchangeRate = double.Parse(line.Substring(4).Replace(",", "."));
                        break;

                    case "32B":
                        BoughtCurrency = line.Substring(5, 3);
                        BoughtAmount   = double.Parse(line.Substring(8).Replace(",", "."));
                        break;

                    case "57A":
                        if (boughtSection)
                        {
                            BoughtReceivingAgent = line.Substring(5);
                            boughtSection        = false;
                        }
                        else
                        {
                            SoldReceivingAgent = line.Substring(5);
                        }
                        break;

                    case "33B":
                        SoldCurrency = line.Substring(5, 3);
                        SoldAmount   = double.Parse(line.Substring(8).Replace(",", "."));
                        break;
                    }
                }
            }
            catch (Exception e)
            {
                throw new Exception("Error caught in MT300 Parse method.\r\n" + e.Message + "\r\n", e);
            }
        }