Skip to content

Commit

Permalink
Enables mapping multiple accounts in a single OFX/QFX file (#15)
Browse files Browse the repository at this point in the history
* Enables mapping multiple accounts in a single OFX/QFX file

* Enables mapping multiple accounts in a single OFX/QFX file

* Delete trace.txt

* Adds tests and minor changes suggested by @jjcarstens

* Adds test cases for multiple bank accounts and creditcard accounts
  • Loading branch information
nikhilmore54 authored and jjcarstens committed Oct 13, 2018
1 parent b40d970 commit eb5a6b4
Show file tree
Hide file tree
Showing 7 changed files with 251 additions and 23 deletions.
12 changes: 10 additions & 2 deletions lib/ofex.ex
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,16 @@ defmodule Ofex do

defp parse_message_set("SIGNUPMSGSRSV1", message_set), do: SignonAccounts.create(message_set)
defp parse_message_set("SIGNONMSGSRSV1", message_set), do: Signon.create(message_set)
defp parse_message_set("BANKMSGSRSV1", message_set), do: BankAccount.create(message_set)
defp parse_message_set("CREDITCARDMSGSRSV1", message_set), do: CreditCardAccount.create(message_set)
defp parse_message_set("BANKMSGSRSV1", message_set) do
message_set
|> xpath(~x"./STMTTRNRS"l)
|> Enum.map(&BankAccount.create(&1))
end
defp parse_message_set("CREDITCARDMSGSRSV1", message_set) do
message_set
|> xpath(~x"./CCSTMTTRNRS"l)
|> Enum.map(&CreditCardAccount.create(&1))
end

defp parse_message_set(message_set_name, message_set) do
Logger.warn("Skipping unsupported message set: #{message_set_name}")
Expand Down
41 changes: 32 additions & 9 deletions test/bank_account_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@ defmodule Ofex.BankAccountTest do
@ofx_raw File.read!("test/fixtures/banking_account.ofx")

test "can parse banking account details" do
{:ok, %{accounts: [account]}} = Ofex.parse(@ofx_raw)
%{transactions: transactions} = account
{:ok, %{accounts: [account1, account2]}} = Ofex.parse(@ofx_raw)
%{transactions: transactions1} = account1
%{transactions: transactions2} = account2

assert account == %{
account_number: "00000000012345678910",
assert account1 == %{
account_number: "00000000085245679130",
name: nil,
balance: 1000001.0,
balance_date: ~D[2017-01-27],
Expand All @@ -19,18 +20,37 @@ defmodule Ofex.BankAccountTest do
routing_number: "019283745",
status_code: "0",
status_severity: "INFO",
transactions: transactions,
transactions: transactions1,
transactions_end_date: nil,
transactions_start_date: nil,
type: "CHECKING"
}

assert account2 == %{
account_number: "00000000012345678910",
balance: 1000001.0,
balance_date: ~D[2017-01-27],
currency: "USD",
generic_type: "CHECKING",
name: nil,
positive_balance: 1000001.0,
request_id: "0",
routing_number: "019283745",
status_code: "0",
status_severity: "INFO",
transactions: transactions2,
transactions_end_date: ~D[2017-01-27],
transactions_start_date: ~D[1970-01-01],
type: "CHECKING"
}
end

test "can parse bank account transactions" do
{:ok, %{accounts: [account]}} = Ofex.parse(@ofx_raw)
%{transactions: transactions} = account
{:ok, %{accounts: [account1, account2]}} = Ofex.parse(@ofx_raw)
%{transactions: transactions1} = account1
%{transactions: transactions2} = account2

assert transactions == [
assert transactions2 == [
%{
amount: -7.0,
check_number: nil,
Expand All @@ -52,7 +72,10 @@ defmodule Ofex.BankAccountTest do
positive_amount: 372.07,
posted_date: ~D[2017-01-20],
type: "CREDIT"
},
}
]

assert transactions1 == [
%{
amount: -40.0,
check_number: "275",
Expand Down
37 changes: 29 additions & 8 deletions test/credit_card_account_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,27 @@ defmodule Ofex.CreditCardAccountTest do
@ofx_raw File.read!("test/fixtures/credit_card_response.ofx")

test "can parse credit card account details" do
{:ok, %{accounts: [account]}} = Ofex.parse(@ofx_raw)
%{transactions: transactions} = account
{:ok, %{accounts: [account1, account2]}} = Ofex.parse(@ofx_raw)
%{transactions: transactions1} = account1
%{transactions: transactions2} = account2

assert account == %{
assert account1 == %{
account_number: "456712345678910",
name: nil,
balance: -304.0,
balance_date: ~D[2017-02-06],
currency: "USD",
positive_balance: 304.0,
request_id: "0",
status_code: "0",
status_severity: "INFO",
transactions: transactions1,
transactions_end_date: ~D[2017-02-06],
transactions_start_date: ~D[1970-01-01],
type: "CREDIT_CARD"
}

assert account2 == %{
account_number: "000012345678910",
name: nil,
balance: -304.0,
Expand All @@ -17,18 +34,19 @@ defmodule Ofex.CreditCardAccountTest do
request_id: "0",
status_code: "0",
status_severity: "INFO",
transactions: transactions,
transactions: transactions2,
transactions_end_date: ~D[2017-02-06],
transactions_start_date: ~D[1970-01-01],
type: "CREDIT_CARD"
}
end

test "can parse credit card transactions" do
{:ok, %{accounts: [account]}} = Ofex.parse(@ofx_raw)
%{transactions: transactions} = account
{:ok, %{accounts: [account1, account2]}} = Ofex.parse(@ofx_raw)
%{transactions: transactions1} = account1
%{transactions: transactions2} = account2

assert transactions == [
assert transactions2 == [
%{
amount: 87.4,
check_number: nil,
Expand All @@ -50,7 +68,10 @@ defmodule Ofex.CreditCardAccountTest do
positive_amount: 137.87,
posted_date: ~D[2016-12-29],
type: "DEBIT"
},
}
]

assert transactions1 = [
%{
amount: 105.51,
check_number: nil,
Expand Down
21 changes: 21 additions & 0 deletions test/fixtures/banking_account.ofx
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,27 @@
<NAME>BUYING ALL THE THINGS</NAME>
<MEMO>#YOLO</MEMO>
</STMTTRN>
</BANKTRANLIST>
<LEDGERBAL>
<BALAMT>1000001.00</BALAMT>
<DTASOF>20170127120000</DTASOF>
</LEDGERBAL>
</STMTRS>
</STMTTRNRS>
<STMTTRNRS>
<TRNUID>0</TRNUID>
<STATUS>
<CODE>0</CODE>
<SEVERITY>INFO</SEVERITY>
</STATUS>
<STMTRS>
<CURDEF>USD</CURDEF>
<BANKACCTFROM>
<BANKID>019283745</BANKID>
<ACCTID>00000000085245679130</ACCTID>
<ACCTTYPE>CHECKING</ACCTTYPE>
</BANKACCTFROM>
<BANKTRANLIST>
<STMTTRN>
<TRNTYPE>CHECK</TRNTYPE>
<DTPOSTED>20170113120000</DTPOSTED>
Expand Down
21 changes: 21 additions & 0 deletions test/fixtures/credit_card_response.ofx
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,27 @@
<FITID>448915304272642016122920161229002531</FITID>
<NAME>CRAZY FUN EVENT CENTER</NAME>
</STMTTRN>
</BANKTRANLIST>
<LEDGERBAL>
<BALAMT>-304.0</BALAMT>
<DTASOF>20170206120000</DTASOF>
</LEDGERBAL>
</CCSTMTRS>
</CCSTMTTRNRS>
<CCSTMTTRNRS>
<TRNUID>0</TRNUID>
<STATUS>
<CODE>0</CODE>
<SEVERITY>INFO</SEVERITY>
</STATUS>
<CCSTMTRS>
<CURDEF>USD</CURDEF>
<CCACCTFROM>
<ACCTID>456712345678910</ACCTID>
</CCACCTFROM>
<BANKTRANLIST>
<DTSTART>19700101120000</DTSTART>
<DTEND>20170206120000</DTEND>
<STMTTRN>
<TRNTYPE>CREDIT</TRNTYPE>
<DTPOSTED>20161209120000</DTPOSTED>
Expand Down
134 changes: 134 additions & 0 deletions test/fixtures/multiple_accounts.ofx
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>

<?OFX OFXHEADER="200" VERSION="200" SECURITY="NONE" OLDFILEUID="NONE" NEWFILEUID="NONE"?>

<OFX>
<SIGNONMSGSRSV1>
<SONRS>
<STATUS>
<CODE>0</CODE>
<SEVERITY>INFO</SEVERITY>
</STATUS>
<DTSERVER>20170127110131.603[-5:EST]</DTSERVER>
<LANGUAGE>ENG</LANGUAGE>
<FI>
<ORG>Whip & Whirl</ORG>
</FI>
</SONRS>
</SIGNONMSGSRSV1>
<BANKMSGSRSV1>
<STMTTRNRS>
<TRNUID>0</TRNUID>
<STATUS>
<CODE>0</CODE>
<SEVERITY>INFO</SEVERITY>
</STATUS>
<STMTRS>
<CURDEF>USD</CURDEF>
<BANKACCTFROM>
<BANKID>019283745</BANKID>
<ACCTID>00000000012345678910</ACCTID>
<ACCTTYPE>CHECKING</ACCTTYPE>
</BANKACCTFROM>
<BANKTRANLIST>
<DTSTART>19700101120000</DTSTART>
<DTEND>20170127120000</DTEND>
<STMTTRN>
<TRNTYPE>DEBIT</TRNTYPE>
<DTPOSTED>20170123120000</DTPOSTED>
<DTUSER>20170123120000</DTUSER>
<TRNAMT>-7.0</TRNAMT>
<FITID>4614806509201701231</FITID>
<NAME>This is where the name is</NAME>
<MEMO>This is where a memo goes</MEMO>
</STMTTRN>
<STMTTRN>
<TRNTYPE>CREDIT</TRNTYPE>
<DTPOSTED>20170120120000</DTPOSTED>
<DTUSER>20170120120000</DTUSER>
<TRNAMT>372.07</TRNAMT>
<FITID>4614806509201701201</FITID>
<NAME>BUYING ALL THE THINGS</NAME>
<MEMO>#YOLO</MEMO>
</STMTTRN>
<STMTTRN>
<TRNTYPE>CHECK</TRNTYPE>
<DTPOSTED>20170113120000</DTPOSTED>
<DTUSER>20170113120000</DTUSER>
<TRNAMT>-40.0</TRNAMT>
<FITID>3113342346901135</FITID>
<CHECKNUM>275</CHECKNUM>
<NAME>CHECK 275 342857403598</NAME>
</STMTTRN>
</BANKTRANLIST>
<LEDGERBAL>
<BALAMT>1000001.00</BALAMT>
<DTASOF>20170127120000</DTASOF>
</LEDGERBAL>
</STMTRS>
</STMTTRNRS>
<STMTTRNRS>
<TRNUID>0</TRNUID>
<STATUS>
<CODE>0</CODE>
<SEVERITY>INFO</SEVERITY>
</STATUS>
<STMTRS>
<CURDEF>USD</CURDEF>
<BANKACCTFROM>
<BANKID>019283745</BANKID>
<ACCTID>0000000007539546821</ACCTID>
<ACCTTYPE>CHECKING</ACCTTYPE>
</BANKACCTFROM>
<BANKTRANLIST>
<DTSTART>19700101120000</DTSTART>
<DTEND>20170127120000</DTEND>
<STMTTRN>
<TRNTYPE>DEBIT</TRNTYPE>
<DTPOSTED>20170123120000</DTPOSTED>
<DTUSER>20170123120000</DTUSER>
<TRNAMT>-7.0</TRNAMT>
<FITID>4614806509201701231</FITID>
<NAME>This is where the name is</NAME>
<MEMO>This is where a memo goes</MEMO>
</STMTTRN>
</BANKTRANLIST>
<LEDGERBAL>
<BALAMT>85263.00</BALAMT>
<DTASOF>20170127120000</DTASOF>
</LEDGERBAL>
</STMTRS>
</STMTTRNRS>
</BANKMSGSRSV1>
<CREDITCARDMSGSRSV1>
<CCSTMTTRNRS>
<TRNUID>0</TRNUID>
<STATUS>
<CODE>0</CODE>
<SEVERITY>INFO</SEVERITY>
</STATUS>
<CCSTMTRS>
<CURDEF>USD</CURDEF>
<CCACCTFROM>
<ACCTID>000012345678910</ACCTID>
</CCACCTFROM>
<BANKTRANLIST>
<DTSTART>19700101120000</DTSTART>
<DTEND>20170206120000</DTEND>
<STMTTRN>
<TRNTYPE>CREDIT</TRNTYPE>
<DTPOSTED>20170106120000</DTPOSTED>
<DTUSER>20170106120000</DTUSER>
<TRNAMT>87.4</TRNAMT>
<FITID>4489153042781763450170106002711</FITID>
<NAME>ONLINE BANKING PAYMENT PAYPOINT</NAME>
</STMTTRN>
</BANKTRANLIST>
<LEDGERBAL>
<BALAMT>-304.0</BALAMT>
<DTASOF>20170206120000</DTASOF>
</LEDGERBAL>
</CCSTMTRS>
</CCSTMTTRNRS>
</CREDITCARDMSGSRSV1>
</OFX>
8 changes: 4 additions & 4 deletions test/ofex_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,13 @@ defmodule OfexTest do
end

test "can parse QFX data" do
ofx_raw = File.read!("test/fixtures/bank_account.qfx")
{:ok, %{accounts: [_bank_account]}} = Ofex.parse(ofx_raw)
ofx_raw = File.read!("test/fixtures/multiple_accounts.ofx")
{:ok, %{accounts: [_bank_account1, _bank_account2, _cc_account]}} = Ofex.parse(ofx_raw)
end

test "can parse! QFX data" do
ofx_raw = File.read!("test/fixtures/bank_account.qfx")
%{accounts: [_bank_account]} = Ofex.parse!(ofx_raw)
ofx_raw = File.read!("test/fixtures/multiple_accounts.ofx")
%{accounts: [_bank_account1, _bank_account2, _cc_account]} = Ofex.parse!(ofx_raw)
end

test "can parse file with unsafe &" do
Expand Down

0 comments on commit eb5a6b4

Please sign in to comment.