defmodule Banking.Fio.TransparentAccount do @moduledoc """ FIO Banka - transparent account. """ @public_accounts_url "https://www.fio.cz/bankovni-sluzby/bankovni-ucty/transparentni-ucet/vypis-transparentnich-uctu" @doc """ Fetch links to all transparent accounts. ## Examples iex> Banking.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(&Banking.Fio.TransparentAccount.list/1) |> List.flatten _ -> [] end end @doc """ Fetch links to transparent accounts on specified page. ## Examples iex> Banking.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 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 """ Fetch transactions of specified transparent account. ## Examples iex> Banking.Fio.TransparentAccount.transactions("2501277007") [%{amount: "0,01 CZK", date: "11.09.2017", id: "ddda30524588b54ee5e6711b4f45498a3a49e8c999c76d9a2ddc13af3d405ec6", index: 8877, msg: "Nezlobte se, že vás zase obtěžuju, ale já jsem si vzpomněl, že jsem se vás nezeptal, jestli má Mynář prověrku. Má Mynář prověrku?", name: "Pastucha, Zdeněk", type: "Platba převodem uvnitř banky"}, %{amount: "0,01 CZK", date: "11.09.2017", id: "132c54735818650ac301811eccbaf0e8b1d6b5943f3f42e5595e53bb3602e9a1", index: 8876, msg: "haaahaaa...odchozí poplatky se mi neúčtujou,mám FIO banku! Bohužel Miloš taky. Ale za pouhý 1hal ho můžu poslat do řiti: Mildo,bež do řiti!", name: "Karafa, Tomáš", type: "Platba převodem uvnitř banky"}, %{amount: "0,01 CZK", date: "11.09.2017", id: "0b6cd96659eb04c5168d742392818b83f29898d0e773e47adc810ac007d9d26d", ...}, %{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 end_date = Timex.format!(Timex.now, "%d.%m.%Y", :strftime) 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))), 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