defmodule Ofex.BankAccount do alias Ofex.Transaction import Ofex.Helpers import SweetXml @doc """ Parses `BANKMSGSRSV1` message set for bank account data. * `:account_number` * `:balance` * `:balance_date` `Date` representation (i.e. `~D[2017-01-27]`) * `:currency` 3 letter ISO-4217 currency identifier * `:generic_type` simple representation of the type (i.e. `MONEYMRKT` generic is `SAVINGS`) * `:positive_balance` some cases may strictly require a positive balance amount * `:request_id` * `:routing_number` * `:status_code` * `:status_severity` * `:transactions` parsed transactions formatted with `Ofex.Transaction` * `:type` Sample `BANKMSGSRSV1` message set: ```xml 0 0 INFO USD 019283745 00000000012345678910 CHECKING 19700101120000 20170127120000 DEBIT 20170123120000 20170123120000 -7.0 0192947576930 This is where the name is This is where a memo goes CREDIT 20170120120000 20170120120000 372.07 019274659302 BUYING ALL THE THINGS #YOLO CHECK 20170113120000 20170113120000 -40.0 8373020273630 275 CHECK 275 8383933737 1000001.00 20170127120000 ``` """ @spec create(binary) :: {:account, %{}} def create(ofx_data) do account = %{ account_number: xpath(ofx_data, ~x"//ACCTID/text()"s), balance: xpath(ofx_data, ~x"//BALAMT/text()"s) |> string_to_float, balance_date: xpath(ofx_data, ~x"//DTASOF/text()"s) |> string_to_date, currency: xpath(ofx_data, ~x"//CURDEF/text()"s), generic_type: xpath(ofx_data, ~x"//ACCTTYPE/text()"s) |> generic_type_from_type, name: xpath(ofx_data, ~x"//DESC/text()"s), positive_balance: xpath(ofx_data, ~x"//BALAMT/text()"s) |> convert_to_positive_float, request_id: xpath(ofx_data, ~x"//TRNUID/text()"s), routing_number: xpath(ofx_data, ~x"//BANKID/text()"s), status_code: xpath(ofx_data, ~x"//CODE/text()"s), status_severity: xpath(ofx_data, ~x"//SEVERITY/text()"s), transactions: xpath(ofx_data, ~x"//BANKTRANLIST/STMTTRN"l) |> parse_transactions, type: xpath(ofx_data, ~x"//ACCTTYPE/text()"s), } %{account: account} end defp generic_type_from_type("MONEYMRKT"), do: "SAVINGS" defp generic_type_from_type("CREDITLINE"), do: "LINE_OF_CREDIT" defp generic_type_from_type("CD"), do: "SAVINGS" defp generic_type_from_type(type), do: type defp parse_transactions(ofx_transactions) do Enum.map(ofx_transactions, &Transaction.create(&1)) end end