defmodule ExCnab.Cnab240.Templates.FileHeader do
@moduledoc """
Template for rendering a cnab240 header from a file
"""
import Helpers.ConvertPosition
@doc """
This function generate a Header File Map from a Cnab240 file, using the **FEBRABAN** convention. The fields follows the convention hierarchy,
and the returns is in PT BR.
You can see all hierarchy in the FEBRABAN documentation.
```md
CNAB
├── Controle
│ ├── Banco (1..3)
│ ├── Lote (4..7)
│ └── Registro (8..8)
│
├── CNAB - USO FEBRABAN (9..17)
│
├── Empresa
│ ├── Inscrição
│ │ ├── Tipo (18..18)
│ │ └── Número de inscrição (19..32)
│ │
│ ├── Convênio (33..52)
│ │
│ ├── Conta corrente
│ │ ├── Agência
│ │ │ ├── Código (53..57)
│ │ │ └── DV (58..58)
│ │ │
│ │ ├── Conta
│ │ │ └── Número DV
│ │ │ ├── Número da conta corrente (59..70)
│ │ │ └── Dígito verificador da conta (71..71)
│ │ │
│ │ └── DV (72..72)
│ │
│ └── Nome da empresa (73..102)
│
├── Nome do banco (103..132)
│
├── CNAB - USO FEBRABAN (133..142)
│
├── Arquivo
│ ├── Código remessa / retorno (143..143)
│ ├── Data geração (144..151)
│ ├── Hora geração (152..157)
│ ├── Sequência - NSA (158..163)
│ ├── Layout do arquivo (164..166)
│ └── Densidade (167..171)
│
├── Reservado banco (172..191)
│
├── Reservado empresa (192..211)
│
└── CNAB - USO FEBRABAN (212..240)
```
"""
alias ExCnab.Cnab240.Validator.FileHeader, as: FileHeaderValidator
@spec generate(String.t(), Map.t()) :: {:ok, Map.t()} | {:error, String.t(), String.t()}
def generate(raw_string, _attrs) do
control_fields = control_fields(raw_string)
company_fields = company_fields(raw_string)
about_fields = about_fields(raw_string)
%{
controle: control_fields,
uso_febraban_01: convert_position(raw_string, 9, 17),
empresa: company_fields,
nome_banco: convert_position(raw_string, 103, 132),
uso_febraban_02: convert_position(raw_string, 133, 142),
arquivo: about_fields,
uso_banco: convert_position(raw_string, 172, 191),
uso_empresa: convert_position(raw_string, 192, 211),
uso_febraban_03: convert_position(raw_string, 212, 240)
}
|> FileHeaderValidator.call(raw_string)
end
defp control_fields(raw_string) do
%{
codigo_do_banco: convert_position(raw_string, 1, 3),
lote: convert_position(raw_string, 4, 7),
registro: convert_position(raw_string, 8, 8)
}
end
defp company_fields(raw_string) do
%{
inscricao: %{
tipo_inscricao_empresa: convert_position(raw_string, 18, 18),
numero_inscricao_empresa: convert_position(raw_string, 19, 32)
},
codigo_convenio_banco: convert_position(raw_string, 33, 52),
conta_corrente: %{
agencia: %{
codigo_agencia: convert_position(raw_string, 53, 57),
digito_verificador_agencia: convert_position(raw_string, 58, 58)
},
conta: %{
numero_conta_corrente: convert_position(raw_string, 59, 70),
digito_verificador_conta: convert_position(raw_string, 71, 71)
},
digito_verificador_ag_conta: convert_position(raw_string, 72, 72)
},
nome_empresa: convert_position(raw_string, 73, 102)
}
end
defp about_fields(raw_string) do
%{
codigo_remessa_retorno: convert_position(raw_string, 143, 143),
data_geracao_arquivo: convert_position(raw_string, 144, 151),
hora_geracao_arquivo: convert_position(raw_string, 152, 157),
numero_sequencial_arquivo: convert_position(raw_string, 158, 163),
numero_versao_leiaute: convert_position(raw_string, 164, 166),
densidade_arquivo: convert_position(raw_string, 167, 171)
}
end
@spec encode(header :: Map.t()) :: String.t()
def encode(%{arquivo: file, controle: control, empresa: company} = params) do
%{codigo_do_banco: codigo_do_banco, lote: lote, registro: registro} = control
%{
codigo_remessa_retorno: codigo_remessa_retorno,
data_geracao_arquivo: data_geracao_arquivo,
hora_geracao_arquivo: hora_geracao_arquivo,
numero_sequencial_arquivo: numero_sequencial_arquivo,
numero_versao_leiaute: numero_versao_leiaute,
densidade_arquivo: densidade_arquivo
} = file
%{
agencia: %{
codigo_agencia: codigo_agencia,
digito_verificador_agencia: digito_verificador_agencia
},
conta: %{
digito_verificador_conta: digito_verificador_conta,
numero_conta_corrente: numero_conta_corrente
},
digito_verificador_ag_conta: digito_verificador_ag_conta
} = company.conta_corrente
%{
numero_inscricao_empresa: numero_inscricao_empresa,
tipo_inscricao_empresa: tipo_inscricao_empresa
} = company.inscricao
%{nome_empresa: nome_empresa, codigo_convenio_banco: codigo_convenio_banco} = company
%{
uso_empresa: uso_empresa,
uso_banco: uso_banco,
nome_banco: nome_banco,
uso_febraban_01: uso_febraban_01,
uso_febraban_02: uso_febraban_02,
uso_febraban_03: uso_febraban_03
} = params
[
codigo_do_banco,
lote,
registro,
uso_febraban_01,
tipo_inscricao_empresa,
numero_inscricao_empresa,
codigo_convenio_banco,
codigo_agencia,
digito_verificador_agencia,
numero_conta_corrente,
digito_verificador_conta,
digito_verificador_ag_conta,
nome_empresa,
nome_banco,
uso_febraban_02,
codigo_remessa_retorno,
data_geracao_arquivo,
hora_geracao_arquivo,
numero_sequencial_arquivo,
numero_versao_leiaute,
densidade_arquivo,
uso_banco,
uso_empresa,
uso_febraban_03
]
|> Enum.join()
end
end