defmodule ExCnab.Cnab240.Services.BuildDetails do @moduledoc """ Service to generate a details """ alias ExCnab.Cnab240.Templates.{ChunkFooter, ChunkHeader, Details} alias ExCnab.Cnab240.Validator.Details, as: DetailsValidator @payment_mapper %{ "03": %{ code: :boleto_eletronico, descricao: "Boleto Eletrônico", "30": %{ code: :liquidacao_titulos_banco, descricao: "Liquidação de Títulos do Próprio Banco" }, "31": %{ code: :liquidacao_titulos_outros_banco, descricao: "Pagamento de Títulos de Outros Bancos" } }, "20": %{ code: :pagamento_fornecedor, descricao: "Pagamento Fornecedor", "01": %{ code: :credito_conta, descricao: "Crédito em Conta-Corrente" }, "03": %{ code: :doc, descricao: "DOC" }, "10": %{ code: :op, descricao: "Ordem de Pagamento - OP" }, "41": %{ code: :ted, descricao: "TED - Transferência entre Clientes" }, "45": %{ code: :pix, descricao: "PIX - Transferência" } }, "22": %{ code: :pagamento_de_contas, descricao: "Pagamento de Contas, Tributos e Impostos", "11": %{ code: :pagamento_de_contas_codigo_barras, descricao: "Pagamento de Contas e Tributos com Código de Barras" }, "16": %{ code: :tributo_darf_normal, descricao: "Tributo DARF Normal" }, "17": %{ code: :tributo_gps, descricao: "Tributo GPS (Guia da Previdência Social)" }, "18": %{ code: :tributo_darf_simples, descricao: "Tributo DARF Simples" } }, "30": %{ code: :pagamento_salario, descricao: "Pagamento Salários/Folha de Pagamento", "01": %{ code: :credito_conta, descricao: "Crédito em Conta-Corrente" } } } @spec run(Map.t(), Map.t()) :: {:ok, Map.t()} | {:error, String.t(), String.t()} def run(%{chunks: batches}, _attrs) do with {:ok, builded_details} <- build_recursive(batches, [], batches, nil), {:ok, _} <- DetailsValidator.call(builded_details, batches) do {:ok, builded_details} end end defp build_recursive([], acc, _, nil), do: {:ok, acc} defp build_recursive([hd | tail], acc, original_batches, nil) do with index <- Enum.find_index(original_batches, &(&1 == hd)) + 1, detail_key_id <- :"chunk_register_#{index}", %{header: header, detail: details, footer: footer} <- hd[detail_key_id], {:ok, builded_header} <- ChunkHeader.generate(header), {:ok, builded_details} <- Details.generate(details), {:ok, builded_footer} <- ChunkFooter.generate(footer, builded_details), amount <- get_chunk_infos(builded_header, builded_footer) do details = [ %{ header_lote: builded_header, lotes: builded_details, trailer_lote: builded_footer, valor: amount } ] build_recursive(tail, acc ++ details, original_batches, nil) end end defp get_chunk_infos(header, %{total: %{valor: amount}}) do %{service_type: service_type} = get_payment_method(header) %{tipo: service_type, quantidade: amount} end defp get_payment_method(%{servico: payment_details}) do payment_input = @payment_mapper[:"#{payment_details.tipo_servico}"] service_type = payment_input[:"#{payment_details.forma_lancamento}"] %{payment_input: payment_input.code, service_type: service_type.code} end end