defmodule ExCnab.Cnab240.Templates.Details.ModelB do
@moduledoc """
Template to generate an cnab 240 object from file, following the B-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 B-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)
│
├── CNAB (15..17)
│
│── Dados complementares
│ ├── Favorecido
│ │ ├── Inscrição
│ │ │ ├── Tipo (18..18)
│ │ │ └── Número (19..32)
│ │ │
│ │ ├── Logradouro (33..62)
│ │ │
│ │ ├── Número (63..67)
│ │ │
│ │ ├── Complemento (68..82)
│ │ │
│ │ ├── Bairro (83..97)
│ │ │
│ │ ├── Cidade (98..117)
│ │ │
│ │ ├── CEP (118..122)
│ │ │
│ │ ├── Complemento CEP (123..125)
│ │ │
│ │ └── Estado (126..127)
│ │
│ ├── PAGTO
│ │ │
│ │ ├── Vencimento (128..135)
│ │ │
│ │ ├── Valor documento (136..150)
│ │ │
│ │ ├── Abatimento (151..165)
│ │ │
│ │ ├── Desconto (166..180)
│ │ │
│ │ ├── Mora (181..195)
│ │ │
│ │ └── Multa (196..210)
│ │
│ └── Cód/Doc. Favorec. (211..225)
│
├── Aviso (226..226)
│
├── Código UG Centralizadora (227..232)
│
└── Identificação do banco no SPB (233..240)
Para Pix
CNAB
├── Controle
│ ├── Banco (1..3)
│ ├── Lote (4..7)
│ └── Registro (8..8)
│
├── Serviço
│ ├── N do registro (9..13)
│ └── Segmento (14..14)
│
├── Identificador favorecido (15..17)
│
│── Dados complementares
│ ├── informação 10 (18..32)
│ ├── informação 11 (33..127)
│ └── informação 12 (128..226)
│
├── Código UG Centralizadora (227..232)
│
└── Identificação do banco no SPB (233..240)
```
"""
alias ExCnab.Cnab240.Validator.Details.ModelB, as: ModelBValidator
@spec generate(String.t()) :: {:ok, Map.t()}
def generate(raw_string) do
pix_type = convert_position(raw_string, 15, 17)
raw_string
|> build_with_type(pix_type)
|> ModelBValidator.call(raw_string)
end
defp build_with_type(raw_string, pix_type) when pix_type === " " do
control_fields = control_fields(raw_string)
service_fields = service_fields(raw_string)
beneficiary_fields = beneficiary_fields(raw_string)
payer_fields = payer_fields(raw_string)
%{
controle: control_fields,
servico: service_fields,
cnab: convert_position(raw_string, 15, 17),
dados_complementares: %{
favorecido: beneficiary_fields,
pagto: payer_fields,
cod_favorecido: convert_position(raw_string, 211, 225)
},
aviso: convert_position(raw_string, 226, 226),
codigo_ug_centralizadora: convert_position(raw_string, 227, 232),
id_banco_spb: convert_position(raw_string, 233, 240)
}
end
defp build_with_type(raw_string, pix_type) do
control_fields = control_fields(raw_string)
service_fields = service_fields(raw_string)
%{
controle: control_fields,
servico: service_fields,
id_favorecido: pix_type,
inscricao: %{
tipo: convert_position(raw_string, 18),
numero: convert_position(raw_string, 19, 32)
},
dados_complementares: %{
informacao_10: convert_position(raw_string, 33, 62),
informacao_11: convert_position(raw_string, 63, 127),
informacao_12: convert_position(raw_string, 128, 226)
},
codigo_ug_centralizadora: convert_position(raw_string, 227, 232),
id_banco_spb: convert_position(raw_string, 233, 240)
}
end
defp control_fields(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_fields(raw_string) do
%{
n_registro: convert_position(raw_string, 9, 13),
segmento: convert_position(raw_string, 14)
}
end
defp beneficiary_fields(raw_string) do
%{
inscricao: %{
tipo: convert_position(raw_string, 18),
numero: convert_position(raw_string, 19, 32)
},
logradouro: convert_position(raw_string, 33, 62),
numero: convert_position(raw_string, 63, 67),
complemento: convert_position(raw_string, 68, 82),
bairro: convert_position(raw_string, 83, 97),
cidade: convert_position(raw_string, 98, 117),
cep: convert_position(raw_string, 118, 122),
complemento_cep: convert_position(raw_string, 123, 125),
estado: convert_position(raw_string, 126, 127)
}
end
defp payer_fields(raw_string) do
%{
vencimento: convert_position(raw_string, 128, 135),
valor_documento: convert_position(raw_string, 136, 150),
abatimento: convert_position(raw_string, 151, 165),
desconto: convert_position(raw_string, 166, 180),
mora: convert_position(raw_string, 181, 195),
multa: convert_position(raw_string, 196, 210)
}
end
def encode(%{
controle: %{
banco: banco,
lote: lote,
registro: registro
},
servico: %{
n_registro: n_registro,
segmento: segmento
},
cnab: cnab_01,
dados_complementares: %{
favorecido: %{
inscricao: %{
tipo: tipo_inscricao,
numero: numero_inscricao
},
logradouro: logradouro,
numero: numero,
complemento: complemento,
bairro: bairro,
cidade: cidade,
cep: cep,
complemento_cep: complemento_cep,
estado: estado
},
pagto: %{
vencimento: vencimento,
valor_documento: valor_documento,
abatimento: abatimento,
desconto: desconto,
mora: mora,
multa: multa
},
cod_favorecido: cod_favorecido
},
aviso: aviso,
codigo_ug_centralizadora: codigo_ug_centralizadora,
id_banco_spb: id_banco_spb
}) do
[
banco,
lote,
registro,
n_registro,
segmento,
cnab_01,
tipo_inscricao,
numero_inscricao,
logradouro,
numero,
complemento,
bairro,
cidade,
cep,
complemento_cep,
estado,
vencimento,
valor_documento,
abatimento,
desconto,
mora,
multa,
cod_favorecido,
aviso,
codigo_ug_centralizadora,
id_banco_spb
]
|> Enum.join()
end
def encode(%{
controle: %{
banco: banco,
lote: lote,
registro: registro
},
servico: %{
n_registro: n_registro,
segmento: segmento
},
id_favorecido: id_favorecido,
inscricao: %{
tipo: tipo_inscricao,
numero: numero_inscricao
},
dados_complementares: %{
informacao_10: informacao_10,
informacao_11: informacao_11,
informacao_12: informacao_12
},
codigo_ug_centralizadora: codigo_ug_centralizadora,
id_banco_spb: id_banco_spb
}) do
[
banco,
lote,
registro,
n_registro,
segmento,
id_favorecido,
tipo_inscricao,
numero_inscricao,
informacao_10,
informacao_11,
informacao_12,
codigo_ug_centralizadora,
id_banco_spb
]
|> Enum.join()
end
end