defmodule ExCnab.Cnab240.Templates.Details.ModelN do
@moduledoc """
Template to generate an cnab 240 object from file, following the N-segment pattern;
"""
import Helpers.ConvertPosition
@doc """
This function generate a Header Chunk Map from a Cnab240 file, using the **FEBRABAN** convention. The fields follows the O-segment 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)
│
├── Serviço
│ ├── N do registro (9..13)
│ ├── Segmento (14..14)
│ └── Movimento
│ ├── Tipo (15..15)
│ └── Código (16..17)
│
├── Pagamento
│ ├── Seu numero (18..37)
│ │
│ ├── Nosso numero (38..57)
│ │
│ ├── Contribuinte (58..57)
│ │
│ ├── Data pagamento (88..95)
│ │
│ └── Valor pagamento (96..110)
│
├── Informacoes complementares (111..230)
│
└── Ocorrências (231..240)
"""
alias ExCnab.Cnab240.Validator.Details.ModelN, as: ModelNValidator
@spec generate(String.t()) :: {:ok, Map.t()}
def generate(raw_string) do
control_field = control_field(raw_string)
service_field = service_field(raw_string)
payment_field = payment_field(raw_string)
complementary_info =
raw_string
|> convert_position(133, 134)
|> complementary_info_fields(raw_string)
%{
controle: control_field,
servico: service_field,
pagamento: payment_field,
informacoes_complementares: complementary_info,
ocorrencias: convert_position(raw_string, 231, 240)
}
|> ModelNValidator.call(raw_string)
end
defp control_field(raw_string) do
%{
banco: convert_position(raw_string, 1, 3),
lote: convert_position(raw_string, 4, 7),
registro: convert_position(raw_string, 8)
}
end
defp service_field(raw_string) do
%{
n_registro: convert_position(raw_string, 9, 13),
segmento: convert_position(raw_string, 14),
movimento: %{
tipo: convert_position(raw_string, 15),
codigo: convert_position(raw_string, 16, 17)
}
}
end
defp payment_field(raw_string) do
%{
seu_numero: convert_position(raw_string, 18, 37),
nosso_numero: convert_position(raw_string, 38, 57),
contribuinte: convert_position(raw_string, 58, 87),
data_pagamento: convert_position(raw_string, 88, 95),
valor_pagamento: convert_position(raw_string, 96, 110)
}
end
# DARF
defp complementary_info_fields("16", raw_string) do
%{
receita: convert_position(raw_string, 111, 116),
tipo_id_contribuinte: convert_position(raw_string, 117, 118),
id_contribuinte: convert_position(raw_string, 119, 132),
id_tributo: convert_position(raw_string, 133, 134),
periodo: convert_position(raw_string, 135, 142),
referencia: convert_position(raw_string, 143, 159),
valor_principal: convert_position(raw_string, 160, 174),
valor_multa: convert_position(raw_string, 175, 189),
juros_e_encargos: convert_position(raw_string, 190, 204),
data_vencimento: convert_position(raw_string, 205, 212),
cnab: convert_position(raw_string, 213, 230)
}
end
# GPS
defp complementary_info_fields("17", raw_string) do
%{
receita: convert_position(raw_string, 111, 116),
tipo_id_contribuinte: convert_position(raw_string, 117, 118),
id_contribuinte: convert_position(raw_string, 119, 132),
id_tributo: convert_position(raw_string, 133, 134),
competencia: convert_position(raw_string, 135, 140),
valor_tributo: convert_position(raw_string, 141, 155),
valor_outras_entidades: convert_position(raw_string, 156, 170),
atualizacao_monetaria: convert_position(raw_string, 171, 185),
cnab: convert_position(raw_string, 186, 230)
}
end
# DARF SIMPLES
defp complementary_info_fields("18", raw_string) do
%{
receita: convert_position(raw_string, 111, 116),
tipo_id_contribuinte: convert_position(raw_string, 117, 118),
id_contribuinte: convert_position(raw_string, 119, 132),
id_tributo: convert_position(raw_string, 133, 134),
periodo: convert_position(raw_string, 135, 142),
receita_bruta: convert_position(raw_string, 143, 157),
percentual: convert_position(raw_string, 158, 164),
valor_principal: convert_position(raw_string, 165, 179),
valor_multa: convert_position(raw_string, 180, 194),
juros_e_encargos: convert_position(raw_string, 195, 209),
cnab: convert_position(raw_string, 210, 230)
}
end
def encode(detail) do
complementary_info =
encode_complementary_info(detail.informacoes_complementares.id_tributo, detail)
%{
controle: %{
banco: banco,
lote: lote,
registro: registro
},
servico: %{
n_registro: n_registro,
segmento: segmento,
movimento: %{
tipo: tipo_movimento,
codigo: codigo_movimento
}
},
pagamento: %{
seu_numero: seu_numero,
nosso_numero: nosso_numero,
contribuinte: contribuinte,
data_pagamento: data_pagamento,
valor_pagamento: valor_pagamento
},
ocorrencias: ocorrencias
} = detail
[
banco,
lote,
registro,
n_registro,
segmento,
tipo_movimento,
codigo_movimento,
seu_numero,
nosso_numero,
contribuinte,
data_pagamento,
valor_pagamento,
complementary_info,
ocorrencias
]
|> Enum.join()
end
defp encode_complementary_info("16", detail) do
%{
receita: receita,
tipo_id_contribuinte: tipo_id_contribuinte,
id_contribuinte: id_contribuinte,
id_tributo: id_tributo,
periodo: periodo,
referencia: referencia,
valor_principal: valor_principal,
valor_multa: valor_multa,
juros_e_encargos: juros_e_encargos,
data_vencimento: data_vencimento,
cnab: cnab
} = detail
[
receita,
tipo_id_contribuinte,
id_contribuinte,
id_tributo,
periodo,
referencia,
valor_principal,
valor_multa,
juros_e_encargos,
data_vencimento,
cnab
]
|> Enum.join()
end
defp encode_complementary_info("17", detail) do
%{
receita: receita,
tipo_id_contribuinte: tipo_id_contribuinte,
id_contribuinte: id_contribuinte,
id_tributo: id_tributo,
competencia: competencia,
valor_tributo: valor_tributo,
valor_outras_entidades: valor_outras_entidades,
atualizacao_monetaria: atualizacao_monetaria,
cnab: cnab
} = detail
[
receita,
tipo_id_contribuinte,
id_contribuinte,
id_tributo,
competencia,
valor_tributo,
valor_outras_entidades,
atualizacao_monetaria,
cnab
]
|> Enum.join()
end
defp encode_complementary_info("18", detail) do
%{
receita: receita,
tipo_id_contribuinte: tipo_id_contribuinte,
id_contribuinte: id_contribuinte,
id_tributo: id_tributo,
periodo: periodo,
receita_bruta: receita_bruta,
percentual: percentual,
valor_principal: valor_principal,
valor_multa: valor_multa,
juros_e_encargos: juros_e_encargos,
cnab: cnab
} = detail
[
receita,
tipo_id_contribuinte,
id_contribuinte,
id_tributo,
periodo,
receita_bruta,
percentual,
valor_principal,
valor_multa,
juros_e_encargos,
cnab
]
|> Enum.join()
end
end