defmodule Fintech.Fio.TransparentAccount do @moduledoc """ FIO Banka - transparent account. """ require Logger @public_accounts_url "https://www.fio.cz/bankovni-sluzby/bankovni-ucty/transparentni-ucet/vypis-transparentnich-uctu" @doc """ Get links of all transparent accounts. ## Examples iex> Fintech.Fio.TransparentAccount.list_all [%{account: "2600088789", link: "https://www.fio.cz/ib2/transparent?a=2600088789", name: "A centrum - Váš průvodce těhotenstvím a rodičovstvím, o. p. s.", url: "http://www.acentrum.eu/"}, %{account: "2800396030", link: "https://www.fio.cz/ib2/transparent?a=2800396030", name: "AA - anonymní alkoholici o.s.", url: nil}, %{account: "2801230649", link: "https://www.fio.cz/ib2/transparent?a=2801230649", ...}, %{account: "2101191407", ...}, %{...}, ...] """ def list_all do case HTTPoison.get(@public_accounts_url) do {:ok, res} -> last = Floki.find(:iconv.convert("windows-1250", "utf-8", res.body), "div.paginator a") |> List.last {_, href, childs} = last {_, link} = List.first(href) {last_offset, _} = Regex.run(~r/.*offset=(\d+)/, link) |> List.last |> Integer.parse {last_page, _} = Floki.text(childs) |> Integer.parse per_page = round(last_offset / (last_page - 1)) 1..(last_page) |> Enum.map(fn(a) -> "https://www.fio.cz/bankovni-sluzby/bankovni-ucty/transparentni-ucet/vypis-transparentnich-uctu?offset=#{(a - 1) * per_page}" end) |> Enum.map(&Fintech.Fio.TransparentAccount.list/1) |> List.flatten _ -> [] end end @doc """ Get links of transparent accounts on specified page. ## Examples iex> Fintech.Fio.TransparentAccount.list("https://www.fio.cz/bankovni-sluzby/bankovni-ucty/transparentni-ucet/vypis-transparentnich-uctu") [%{account: "2600088789", link: "https://www.fio.cz/ib2/transparent?a=2600088789", name: "A centrum - Váš průvodce těhotenstvím a rodičovstvím, o. p. s.", url: "http://www.acentrum.eu/"}, %{account: "2800396030", link: "https://www.fio.cz/ib2/transparent?a=2800396030", name: "AA - anonymní alkoholici o.s.", url: nil}, %{account: "2801230649", link: "https://www.fio.cz/ib2/transparent?a=2801230649", ...}, %{account: "2101191407", ...}, %{...}, ...] """ def list(url) do Logger.debug "Getting #{url}" case HTTPoison.get(url) do {:ok, res} -> Floki.find(:iconv.convert("windows-1250", "utf-8", res.body), "table.tbl2.tbl-sazby tbody tr") |> Enum.map(fn({_, _, e}) -> first = Enum.fetch!(e, 0) url = Floki.find(first, "a") |> Floki.attribute("href") |> List.first account = Floki.text(Enum.fetch!(e, 1)) %{ name: Floki.text(first), account: account, url: url, link: "https://www.fio.cz/ib2/transparent?a=#{account}" } end) _ -> [] end end @doc """ Get transactions of specified transparent account. ## Examples iex> Fintech.Fio.TransparentAccount.transactions("2501277007") [%{amount: "0,01 CZK", date: "11.09.2017", id: "28ecdee954bc961ac9c79f9dd4dc74be63af227a89d58b52e0b2649dc7190f51", index: 8855, ks: "2200", msg: "xx", name: "Sloupenský, Michal", ss: "226566874", type: "Platba převodem uvnitř banky", vs: "84456"}, %{amount: "0,01 CZK", date: "11.09.2017", id: "c9ce082b2a5c28c51ba2f1d1a4161d6ed8d008b1a2389644b3abf689c1382dd8", ...}, %{amount: "0,01 CZK", date: "11.09.2017", ...}, %{amount: "0,01 CZK", ...}, %{...}, ...] """ def transactions(account_id, from \\ "01.01.2007", to \\ Timex.format!(Timex.now, "%d.%m.%Y", :strftime)) do case HTTPoison.get("https://www.fio.cz/ib2/transparent?a=#{account_id}&f=#{from}&t=#{to}") do {:ok, res} -> data = res.body |> Floki.find("div.content > table > tbody > tr") len = length(data) data |> Enum.map(fn e -> Floki.find(e, "td") end) |> Enum.with_index(1) |> Enum.map(fn {e, idx} -> tmp = %{ date: Floki.text(Enum.fetch!(e, 0)), # Timex.parse!(Floki.text(Enum.fetch!(e, 0)), "%d.%m.%Y", :strftime), amount: String.trim(Floki.text(Enum.fetch!(e, 1))), type: String.trim(Floki.text(Enum.fetch!(e, 2))), name: String.trim(Floki.text(Enum.fetch!(e, 3))), msg: String.trim(Floki.text(Enum.fetch!(e, 4))), ks: String.trim(Floki.text(Enum.fetch!(e, 5))), vs: String.trim(Floki.text(Enum.fetch!(e, 6))), ss: String.trim(Floki.text(Enum.fetch!(e, 7))), index: len - idx } id = :crypto.hash(:sha256, Poison.encode_to_iodata!(tmp, pretty: true)) |> Base.encode16 |> String.downcase Map.put(tmp, :id, id) end) end end end