Current section
Files
Jump to
Current section
Files
lib/customer_statement_message.ex
defmodule MT940.CustomerStatementMessage do
require Record
@moduledoc ~S"""
This is a beautification wrapper around the low-level `MT940.Parser.parse!`
command. Use it in order to make dealing with data easier.
"""
Record.defrecordp :message, __MODULE__,
account: nil,
statement_lines: [],
closing_balance: nil
@typep message :: record(:message, account: MT940.Account, statement_lines: list, closing_balance: MT940.ClosingBalance)
@spec parse_file!(binary) :: list
def parse_file!(filename) when is_binary(filename) do
filename
|> File.read!
|> parse!
end
@spec parse!(binary) :: list
def parse!(data) when is_binary(data) do
data
|> MT940.Parser.parse!
|> Enum.map(&new/1)
end
defp new(lines) do
account = lines
|> Stream.filter(fn
%MT940.Account{} -> true
_ -> false
end)
|> Enum.at(0)
lines |> ensure_structure!
statement_lines = lines
|> Stream.filter(fn
%MT940.StatementLine{} -> true
%MT940.StatementLineInformation{} -> true
_ -> false
end)
|> Enum.chunk(2)
|> Enum.map(&MT940.StatementLineBundle.new(&1 |> Enum.at(0), &1 |> Enum.at(1)))
closing_balance = lines
|> Stream.filter(fn
%MT940.ClosingBalance{} -> true
_ -> false
end)
|> Enum.at(-1)
message(
account: account,
statement_lines: statement_lines,
closing_balance: closing_balance
)
end
@spec bank_code(message) :: binary
def bank_code(message) when Record.is_record(message) do
message(message, :account).bank_code
end
@spec account_number(message) :: binary
def account_number(message) when Record.is_record(message) do
message(message, :account).account_number
end
@spec statement_lines(message) :: list
def statement_lines(message) when Record.is_record(message) do
message(message, :statement_lines)
end
@spec closing_balance(message) :: MT940.ClosingBalance
def closing_balance(message) when Record.is_record(message) do
message(message, :closing_balance)
end
defp ensure_structure!([%MT940.StatementLine{}, %MT940.StatementLineInformation{} | lines]) do
ensure_structure!(lines)
end
defp ensure_structure!([%MT940.StatementLine{}, t2 | _]) do
raise UnexpectedStructureError, expected: MT940.StatementLineInformation, actual: t2.__struct__
end
defp ensure_structure!([%MT940.StatementLine{}]) do
raise UnexpectedStructureError, expected: MT940.StatementLineInformation, actual: "(none)"
end
defp ensure_structure!([t1, %MT940.StatementLineInformation{} | _]) do
raise UnexpectedStructureError, expected: MT940.StatementLine, actual: t1.__struct__
end
defp ensure_structure!([%MT940.StatementLineInformation{} | _]) do
raise UnexpectedStructureError, expected: MT940.StatementLine, actual: nil
end
defp ensure_structure!([_ | lines]) do
ensure_structure!(lines)
end
defp ensure_structure!([]) do
end
end