brcobranca 11.0.0 → 12.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5e7e6ba3c6d393e26064746e9de07257f87fda40035ecd14fe6909b90c8719bd
4
- data.tar.gz: ca8b03fda321d9e869876434d47e6706390abd234ac846b5ea3ddffce021b847
3
+ metadata.gz: 40b85b52a4ac810c6f1415906dd2099ca3f8ca623bcfc5f133a871e12ff1fa4d
4
+ data.tar.gz: 593a1178adce41b5922e815436eb83e5db3f626711b2059b0b43cf7e08399642
5
5
  SHA512:
6
- metadata.gz: 03db33f15833ac6f427e8bf14ec3fcf4135fc9e45663e34e8ce4208d549e6586deb7356721d472b58ddc34eb75b358b6b308ae6ebed79c9cd5ef156c3f6a57ec
7
- data.tar.gz: 4bed61dc5d28d553839853fb480496204cdaf0c1e215b30c3423fa0dcdee579cd743ed743c3ef3a70ac1a39271d7a9030e1063ce290d87085915a806e64c3260
6
+ metadata.gz: 1f8b46f27016dc18170876394015e9c575fdb6c302ec9ed5698744421aa1fbd6b5226345f5ebf79af24a5fc82e14ac948bd058612050da7c582432496e6bc399
7
+ data.tar.gz: 7968b70af83ef565021ba7f4666f7ffe35f64878ae2c6e9b36d454fb1cef8570012aa667c6de635eebe20c5587e4f5725f2738735d104105a07bd9d28068c309
data/README.md CHANGED
@@ -53,7 +53,7 @@ Criado pelo pessoal da [Akretion](http://www.akretion.com) muito TOP \o/
53
53
  | Caixa | 240 | 240 |
54
54
  | Citibank | Não | 400 |
55
55
  | HSBC | Não | Não |
56
- | Itaú | 400 | 400 |
56
+ | Itaú | 400 | 400 e 444 |
57
57
  | Santander | 400 e 240 | 400 e 240 |
58
58
  | Sicoob | 240 | 400 e 240 |
59
59
  | Sicredi | 240 | 240 |
@@ -65,6 +65,7 @@ Criado pelo pessoal da [Akretion](http://www.akretion.com) muito TOP \o/
65
65
  - Caixa Economica Federal (CNAB240) [Isabella](https://github.com/isabellaSantos) da [Zaez](http://www.zaez.net)
66
66
  - Bradesco (CNAB400) [Isabella](https://github.com/isabellaSantos) da [Zaez](http://www.zaez.net)
67
67
  - Itaú (CNAB400) [Isabella](https://github.com/isabellaSantos) da [Zaez](http://www.zaez.net)
68
+ - Itaú (CNAB444) [Junior Tada](https://github.com/juniortada)
68
69
  - Citibank (CNAB400)
69
70
  - Santander (CNAB400)
70
71
  - Santander (CNAB240)
@@ -88,4 +89,4 @@ Caso queira verificar(ou adicionar) alguma documentação, acesse [nosso wiki](h
88
89
 
89
90
 
90
91
  ## License
91
- [![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fkivanio%2Fbrcobranca.svg?type=large)](https://app.fossa.com/projects/git%2Bgithub.com%2Fkivanio%2Fbrcobranca?ref=badge_large)
92
+ [![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fkivanio%2Fbrcobranca.svg?type=large)](https://app.fossa.com/projects/git%2Bgithub.com%2Fkivanio%2Fbrcobranca?ref=badge_large)
@@ -91,6 +91,8 @@ module Brcobranca
91
91
  attr_accessor :cedente_endereco
92
92
  # <b>OPCIONAL</b>: EMV para gerar QRCode para pagamento via PIX
93
93
  attr_accessor :emv
94
+ # <b>OPCIONAL</b>: Descontos e abatimentos
95
+ attr_accessor :descontos_e_abatimentos
94
96
 
95
97
  # Validações
96
98
  validates_presence_of :agencia, :conta_corrente, :moeda, :especie_documento, :especie, :aceite, :nosso_numero,
@@ -126,6 +126,7 @@ module Brcobranca
126
126
 
127
127
  # Monta Recibo do Beneficiário
128
128
  def modelo_recibo_beneficiario(doc, boleto)
129
+ monta_logotipo(doc, boleto, 14.500, 26.850, 1.00)
129
130
  doc.moveto x: 4.28, y: 26.87
130
131
  doc.show truncar(boleto.cedente, 90), tag: :menor
131
132
  doc.moveto x: 4.28, y: 26.33
@@ -35,6 +35,15 @@ module Brcobranca
35
35
  modelo_generico(self, options.merge!(formato: formato))
36
36
  end
37
37
 
38
+ # Gera o boleto em usando o formato desejado [:pdf, :jpg, :tif, :png, :ps, :laserjet, ... etc]
39
+ #
40
+ # @return [Stream]
41
+ # @see http://wiki.github.com/shairontoledo/rghost/supported-devices-drivers-and-formats Veja mais formatos na documentação do rghost.
42
+ # @see Rghost#modelo_generico Recebe os mesmos parâmetros do Rghost#modelo_generico.
43
+ def lote(boletos, options = {})
44
+ modelo_generico_multipage(boletos, options)
45
+ end
46
+
38
47
  # Cria o métodos dinâmicos (to_pdf, to_gif e etc) com todos os fomátos válidos.
39
48
  #
40
49
  # @return [Stream]
@@ -93,6 +102,51 @@ module Brcobranca
93
102
  doc.render_stream(formato.to_sym, resolution: resolucao)
94
103
  end
95
104
 
105
+ # Retorna um stream para multiplos boletos pronto para gravação em arquivo.
106
+ #
107
+ # @return [Stream]
108
+ # @param [Array] Instâncias de classes de boleto.
109
+ # @param [Hash] options Opção para a criação do boleto.
110
+ # @option options [Symbol] :resolucao Resolução em pixels.
111
+ # @option options [Symbol] :formato Formato desejado [:pdf, :jpg, :tif, :png, :ps, :laserjet, ... etc]
112
+ def modelo_generico_multipage(boletos, options = {})
113
+ doc = Document.new paper: :A4 # 210x297
114
+
115
+ template_path = File.join(File.dirname(__FILE__), '..', '..', 'arquivos', 'templates', 'modelo_generico.eps')
116
+
117
+ raise 'Não foi possível encontrar o template. Verifique o caminho' unless File.exist?(template_path)
118
+
119
+ boletos.each_with_index do |boleto, index|
120
+ modelo_generico_template(doc, boleto, template_path)
121
+ modelo_generico_cabecalho(doc, boleto)
122
+ modelo_generico_rodape(doc, boleto)
123
+
124
+ # Gerando codigo de barra com rghost_barcode
125
+ if boleto.codigo_barras
126
+ doc.barcode_interleaved2of5(boleto.codigo_barras, width: '10.3 cm', height: '1.3 cm', x: "#{@x - 1.7} cm",
127
+ y: "#{@y - 1.67} cm")
128
+ end
129
+
130
+ # Gerando QRCode a partir de um emv
131
+ if boleto.emv
132
+ doc.barcode_qrcode(boleto.emv, width: '2.5 cm',
133
+ height: '2.5 cm',
134
+ eclevel: 'H',
135
+ x: "#{@x + 12.9} cm",
136
+ y: "#{@y - 2.50} cm")
137
+ move_more(doc, @x + 12.9, @y - 3.70)
138
+ doc.show 'Pague com PIX'
139
+ end
140
+
141
+ # Cria nova página se não for o último boleto
142
+ doc.next_page unless index == boletos.length - 1
143
+ end
144
+ # Gerando stream
145
+ formato = options.delete(:formato) || Brcobranca.configuration.formato
146
+ resolucao = options.delete(:resolucao) || Brcobranca.configuration.resolucao
147
+ doc.render_stream(formato.to_sym, resolution: resolucao)
148
+ end
149
+
96
150
  # Define o template a ser usado no boleto
97
151
  def modelo_generico_template(doc, _boleto, template_path)
98
152
  doc.define_template(:template, template_path, x: '0.5 cm', y: '2.7 cm')
@@ -155,7 +209,10 @@ module Brcobranca
155
209
  move_more(doc, 5, 0)
156
210
  doc.show boleto.valor_documento.to_currency
157
211
 
158
- move_more(doc, -15, -1.3)
212
+ move_more(doc, -15.8, -0.75)
213
+ doc.show boleto.descontos_e_abatimentos&.to_currency
214
+
215
+ move_more(doc, 0.8, -0.55)
159
216
  doc.show "#{boleto.sacado} - #{boleto.sacado_documento.formata_documento}"
160
217
 
161
218
  move_more(doc, 0, -0.3)
@@ -234,6 +291,10 @@ module Brcobranca
234
291
  move_more(doc, 10.1, 0)
235
292
  doc.show boleto.valor_documento.to_currency
236
293
 
294
+ move_more(doc, 0, -0.8)
295
+ doc.show boleto.descontos_e_abatimentos&.to_currency
296
+
297
+ move_more(doc, 0, 0.8)
237
298
  if boleto.instrucoes
238
299
  doc.text_area boleto.instrucoes, width: '14 cm',
239
300
  text_align: :left, x: "#{@x -= 15.8} cm",
@@ -25,13 +25,18 @@ module Brcobranca
25
25
  # Validações
26
26
  include Brcobranca::Validations
27
27
 
28
+ PAYMENT_CLASSES = [
29
+ Brcobranca::Remessa::Pagamento,
30
+ Brcobranca::Remessa::PagamentoPix
31
+ ].freeze
32
+
28
33
  validates_presence_of :pagamentos, :empresa_mae, message: 'não pode estar em branco.'
29
34
 
30
35
  validates_each :pagamentos do |record, attr, value|
31
36
  if value.is_a? Array
32
37
  record.errors.add(attr, 'não pode estar vazio.') if value.empty?
33
38
  value.each do |pagamento|
34
- if pagamento.is_a? Brcobranca::Remessa::Pagamento
39
+ if PAYMENT_CLASSES.include?(pagamento.class)
35
40
  pagamento.errors.full_messages.each { |msg| record.errors.add(attr, msg) } if pagamento.invalid?
36
41
  else
37
42
  record.errors.add(attr, 'cada item deve ser um objeto Pagamento.')
@@ -12,6 +12,7 @@ module Brcobranca
12
12
  validates_length_of :codigo_transmissao, maximum: 15, message: 'deve ter no máximo 15 dígitos.'
13
13
  validates_length_of :agencia, maximum: 4, message: 'deve ter 4 dígitos.'
14
14
  validates_length_of :conta_corrente, maximum: 9, message: 'deve ter 9 dígitos.'
15
+ validates_length_of :digito_conta, is: 1, message: 'deve ter 1 dígito.'
15
16
 
16
17
  def initialize(campos = {})
17
18
  campos = { emissao_boleto: ' ', distribuicao_boleto: ' ',
@@ -26,11 +27,7 @@ module Brcobranca
26
27
  def digito_agencia
27
28
  agencia.modulo11(mapeamento: { 10 => 'X', 11 => 'X' }).to_s
28
29
  end
29
-
30
- def digito_conta
31
- conta_corrente.modulo11(mapeamento: { 10 => 'X', 11 => 'X' }).to_s
32
- end
33
-
30
+
34
31
  def complemento_header
35
32
  ''.rjust(29, ' ')
36
33
  end
@@ -123,6 +120,10 @@ module Brcobranca
123
120
  ''.rjust(1, ' ')
124
121
  end
125
122
 
123
+ def dias_baixa(pagamento)
124
+ pagamento.dias_baixa.to_s.rjust(2, '0')
125
+ end
126
+
126
127
  def monta_header_arquivo
127
128
  header_arquivo = '' # CAMPO TAMANHO
128
129
  header_arquivo += cod_banco # codigo do banco 3
@@ -185,9 +186,9 @@ module Brcobranca
185
186
  segmento_p << formata_documento_ou_numero(pagamento) # identificacao titulo empresa 25
186
187
  segmento_p << pagamento.codigo_protesto # cod. para protesto 1
187
188
  segmento_p << pagamento.dias_protesto.to_s.rjust(2, '0') # dias para protesto 2
188
- segmento_p << '3' # cod. para baixa 1
189
+ segmento_p << codigo_baixa(pagamento) # cod. para baixa 1
189
190
  segmento_p << '0' # zero fixo 1
190
- segmento_p << '00' # dias para baixa 2
191
+ segmento_p << dias_baixa(pagamento) # dias para baixa 2
191
192
  segmento_p << '00' # cod. da moeda 2
192
193
  segmento_p << ''.rjust(11, ' ') # uso exclusivo 11
193
194
  segmento_p
@@ -81,6 +81,11 @@ module Brcobranca
81
81
  contador += 1
82
82
  ret << monta_descontos_adicionais(pagamento, contador)
83
83
  end
84
+
85
+ if pagamento.is_a?(Brcobranca::Remessa::PagamentoPix) && respond_to?(:monta_detalhe_pix)
86
+ contador += 1
87
+ ret << monta_detalhe_pix(pagamento, contador)
88
+ end
84
89
  end
85
90
  ret << monta_trailer(contador + 1)
86
91
 
@@ -114,8 +114,8 @@ module Brcobranca
114
114
  detalhe << pagamento.especie_titulo # especie do titulo X[02]
115
115
  detalhe << aceite # aceite (A/N) X[01]
116
116
  detalhe << pagamento.data_emissao.strftime('%d%m%y') # data de emissao 9[06]
117
- detalhe << pagamento.cod_primeira_instrucao # 1a instrucao - deixar zero X[02]
118
- detalhe << pagamento.cod_segunda_instrucao # 2a instrucao - deixar zero X[02]
117
+ detalhe << pagamento.cod_primeira_instrucao.to_s.rjust(2, '0') # 1a instrucao - deixar zero X[02]
118
+ detalhe << pagamento.cod_segunda_instrucao.to_s.rjust(2, '0') # 2a instrucao - deixar zero X[02]
119
119
  detalhe << pagamento.formata_valor_mora # valor mora ao dia 9[13]
120
120
  detalhe << pagamento.formata_data_desconto # data limite para desconto 9[06]
121
121
  detalhe << pagamento.formata_valor_desconto # valor do desconto 9[13]
@@ -140,7 +140,9 @@ module Brcobranca
140
140
  end
141
141
 
142
142
  def prazo_instrucao(pagamento)
143
- return '03' unless pagamento.cod_primeira_instrucao == '09'
143
+ return "03" unless %w[09 34 35].include?(
144
+ pagamento.cod_primeira_instrucao
145
+ )
144
146
 
145
147
  pagamento.dias_protesto.rjust(2, '0')
146
148
  end
@@ -103,7 +103,7 @@ module Brcobranca
103
103
  detalhe += Brcobranca::Util::Empresa.new(documento_cedente).tipo # tipo de identificacao da empresa 9[02]
104
104
  detalhe << documento_cedente.to_s.rjust(14, '0') # cpf/cnpj da empresa 9[14]
105
105
  detalhe << codigo_transmissao # Código de Transmissão 9[20]
106
- detalhe << pagamento.documento_ou_numero.to_s.ljust(25, ' ') # identificacao do tit. na empresa X[25]
106
+ detalhe << pagamento.documento_ou_numero.to_s.ljust(25, ' ') # identificacao do tit. na empresa X[25]
107
107
  detalhe << pagamento.nosso_numero.to_s.rjust(8, '0') # nosso numero 9[8]
108
108
  detalhe << pagamento.formata_data_segundo_desconto # data limite para o segundo desconto 9[06]
109
109
  detalhe << ''.rjust(1, ' ') # brancos X[1]
@@ -199,7 +199,7 @@ module Brcobranca
199
199
  end
200
200
 
201
201
  def conta_padrao_novo?
202
- !conta_corrente.blank? && conta_corrente.length > 8
202
+ !conta_corrente.nil? && conta_corrente.length > 8
203
203
  end
204
204
 
205
205
  # Valor total de todos os títulos
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Brcobranca
4
+ module Remessa
5
+ module Cnab400
6
+ class SantanderPix < Brcobranca::Remessa::Cnab400::Santander
7
+ # @see Brcobranca::Remessa::PagamentoPix::TIPOS_CHAVE_DICT
8
+ TIPOS_CHAVE_DICT = {
9
+ cpf: '1',
10
+ cnpj: '2',
11
+ telefone: '3',
12
+ email: '4',
13
+ chave_aleatoria: '5'
14
+ }.freeze
15
+
16
+ # Monta Registro Tipo de Pagamento e Dados Qr Code
17
+ #
18
+ # @param pagamento [PagamentoPix]
19
+ # objeto contendo as informacoes referentes ao pagamento via PIX
20
+ # @param sequencial
21
+ # num. sequencial do registro no arquivo
22
+ #
23
+ # @return [String]
24
+ def monta_detalhe_pix(pagamento, sequencial)
25
+ raise Brcobranca::RemessaInvalida, pagamento if pagamento.invalid?
26
+
27
+ detalhe = '8' # Codigo do Registro 9[001]
28
+ detalhe += tipo_pagamento_pix(pagamento.tipo_pagamento_pix) # Tipo de Pagamento 9[002]
29
+ detalhe << pagamento.quantidade_pagamentos_pix.to_s.rjust(2, '0') # Quantidade de Pagamentos possiveis 9[002]
30
+ detalhe << pagamento.tipo_valor_pix.to_s.rjust(1, '0') # Tipo do Valor Informado 9[001]
31
+ detalhe << pagamento.formata_valor_maximo_pix # Valor Maximo 9[013]
32
+ detalhe << pagamento.formata_percentual_maximo_pix # Percentual Maximo 9[005]
33
+ detalhe << pagamento.formata_valor_minimo_pix # Valor Minimo 9[013]
34
+ detalhe << pagamento.formata_percentual_minimo_pix # Percentual Minimo 9[005]
35
+ detalhe << tipo_chave_dict(pagamento.tipo_chave_dict) # Tipo de Chave DICT X[001]
36
+ detalhe << pagamento.codigo_chave_dict.ljust(77, ' ') # Codigo Chave DICT X[077]
37
+ detalhe << pagamento.txid.to_s.ljust(35, ' ') # Codigo de Identificacao do Qr Code X[035]
38
+ detalhe << ''.rjust(239, ' ') # Reservado (uso banco) X[239]
39
+ detalhe << sequencial.to_s.rjust(6, '0') # numero do registro no arquivo 9[006]
40
+ detalhe
41
+ end
42
+
43
+ private
44
+
45
+ # Identificacao do tipo de pagamento
46
+ # 00 - Conforme Perfil do Beneficiario
47
+ # 01 - Aceita qualquer valor
48
+ # 02 - Entre o minimo e o maximo
49
+ # 03 - Nao aceita pagamento com o valor divergente
50
+ def tipo_pagamento_pix(tipo_pagamento_pix)
51
+ tipo_pagamento_pix.to_i.to_s.rjust(2, '0')
52
+ end
53
+
54
+ def tipo_chave_dict(tipo_chave_dict)
55
+ TIPOS_CHAVE_DICT[tipo_chave_dict.to_sym]
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Brcobranca
4
+ module Remessa
5
+ module Cnab444
6
+ class Itau < Brcobranca::Remessa::Cnab400::Itau
7
+
8
+ # Detalhe do arquivo
9
+ #
10
+ # @param pagamento [PagamentoCnab444]
11
+ # objeto contendo as informacoes referentes ao boleto (valor, vencimento, cliente)
12
+ # @param sequencial
13
+ # num. sequencial do registro no arquivo
14
+ #
15
+ # @return [String]
16
+ #
17
+ def monta_detalhe(pagamento, sequencial)
18
+ detalhe = super(pagamento, sequencial)
19
+
20
+ detalhe + pagamento.chave_nfe.to_s.ljust(44, ' ') # chave da nota fiscal (NFe) X[44]
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -89,6 +89,8 @@ module Brcobranca
89
89
  attr_accessor :dias_baixa
90
90
  # <b>OPCIONAL</b>: Número da Parcela
91
91
  attr_accessor :parcela
92
+ # <b>OPCIONAL</b>: Chave da Nota Fiscal Eletrônica
93
+ attr_accessor :chave_nfe
92
94
 
93
95
  validates_presence_of :nosso_numero, :data_vencimento, :valor,
94
96
  :documento_sacado, :nome_sacado, :endereco_sacado,
@@ -311,7 +313,7 @@ module Brcobranca
311
313
  def format_value(attribute, tamanho)
312
314
  value = send(attribute)
313
315
 
314
- raise ValorInvalido, "Pagamento##{attribute}: Deve ser um Float" unless value.to_s.include?('.')
316
+ raise ValorInvalido, "#{self.class}##{attribute}: Deve ser um Float" unless value.to_s.include?('.')
315
317
 
316
318
  format('%.2f', value).delete('.').rjust(tamanho, '0')
317
319
  end
@@ -0,0 +1,118 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'uri'
4
+
5
+ module Brcobranca
6
+ module Remessa
7
+ class PagamentoPix < Pagamento
8
+ include Brcobranca::Validations
9
+
10
+ # Diretório de Identificadores de Contas Transacionais (DICT)
11
+ # @see https://www.bcb.gov.br/estabilidadefinanceira/dict
12
+ TIPOS_CHAVE_DICT = %w[
13
+ cpf
14
+ cnpj
15
+ email
16
+ telefone
17
+ chave_aleatoria
18
+ ].freeze
19
+
20
+ # <b>REQUERIDO</b>: Tipos de chave DICT.
21
+ # @see TIPOS_CHAVE_DICT
22
+ attr_accessor :tipo_chave_dict
23
+ # <b>REQUERIDO</b>: Chave PIX do recebedor
24
+ attr_accessor :codigo_chave_dict
25
+ # <b>OPCIONAL</b>: Identificacao de Tipo de Pagamento
26
+ attr_accessor :tipo_pagamento_pix
27
+ # <b>OPCIONAL</b>: Quantidade de pagamento possiveis
28
+ attr_accessor :quantidade_pagamentos_pix
29
+ # <b>OPCIONAL</b>: Identifica o tipo do valor informado
30
+ attr_accessor :tipo_valor_pix
31
+ # <b>OPCIONAL</b>: Valor Maximo
32
+ attr_accessor :valor_maximo_pix
33
+ # <b>OPCIONAL</b>: Percentual maximo
34
+ attr_accessor :percentual_maximo_pix
35
+ # <b>OPCIONAL</b>: Valor Minimo
36
+ attr_accessor :valor_minimo_pix
37
+ # <b>OPCIONAL</b>: Percentual minimo
38
+ attr_accessor :percentual_minimo_pix
39
+ # <b>OPCIONAL</b>: Codigo de identificacao do Qr Code (TXID)
40
+ attr_accessor :txid
41
+
42
+ validates_presence_of :codigo_chave_dict, :tipo_chave_dict, message: 'não pode estar em branco.'
43
+
44
+ validates_inclusion_of :tipo_chave_dict,
45
+ in: TIPOS_CHAVE_DICT,
46
+ message: "precisa ser um dos seguintes: #{TIPOS_CHAVE_DICT.join(', ')}"
47
+
48
+ validates_format_of :codigo_chave_dict,
49
+ with: /^\d{11}$/,
50
+ if: :tipo_chave_cpf?,
51
+ message: 'deve ter 11 dígitos.'
52
+
53
+ validates_format_of :codigo_chave_dict,
54
+ with: URI::MailTo::EMAIL_REGEXP,
55
+ if: :tipo_chave_email?,
56
+ message: 'não é válido.'
57
+
58
+ validates_format_of :codigo_chave_dict,
59
+ with: /^[\da-zA-Z]{12}\d{2}$/,
60
+ if: :tipo_chave_cnpj?,
61
+ message: 'deve ter 14 caracteres.'
62
+
63
+ validates_format_of :codigo_chave_dict,
64
+ with: /^\+\d{12,13}$/,
65
+ if: :tipo_chave_telefone?,
66
+ message: 'deve estar no formato +55DDNNNNNNNNN.'
67
+
68
+ validates_length_of :codigo_chave_dict,
69
+ in: 1..77,
70
+ if: :tipo_chave_chave_aleatoria?,
71
+ message: 'deve ter entre 1 e 77 caracteres.'
72
+
73
+ def initialize(campos = {})
74
+ padrao = {
75
+ tipo_chave_dict: 'cnpj',
76
+ tipo_pagamento_pix: '00',
77
+ quantidade_pagamentos_pix: '01',
78
+ tipo_valor_pix: '1',
79
+ valor_maximo_pix: 100.0,
80
+ percentual_maximo_pix: 100.0,
81
+ valor_minimo_pix: 100.0,
82
+ percentual_minimo_pix: 100.0,
83
+ txid: nil
84
+ }
85
+
86
+ super(padrao.merge!(campos))
87
+ end
88
+
89
+ # @param tamanho [Float] tamanho do campo
90
+ def formata_valor_maximo_pix(tamanho = 13)
91
+ format_value(:valor_maximo_pix, tamanho)
92
+ end
93
+
94
+ # @param tamanho [Float] tamanho do campo
95
+ def formata_valor_minimo_pix(tamanho = 13)
96
+ format_value(:valor_minimo_pix, tamanho)
97
+ end
98
+
99
+ # @param tamanho [Float] tamanho do campo
100
+ def formata_percentual_maximo_pix(tamanho = 5)
101
+ format_value(:percentual_maximo_pix, tamanho)
102
+ end
103
+
104
+ # @param tamanho [Float] tamanho do campo
105
+ def formata_percentual_minimo_pix(tamanho = 5)
106
+ format_value(:percentual_minimo_pix, tamanho)
107
+ end
108
+
109
+ private
110
+
111
+ TIPOS_CHAVE_DICT.each do |tipo|
112
+ define_method(:"tipo_chave_#{tipo}?") do
113
+ tipo_chave_dict == tipo
114
+ end
115
+ end
116
+ end
117
+ end
118
+ end
@@ -6,6 +6,11 @@ module Brcobranca
6
6
  class Base
7
7
  attr_accessor :codigo_registro, :agencia_com_dv, :agencia_sem_dv, :cedente_com_dv, :convenio, :nosso_numero,
8
8
  :documento_numero, :tipo_cobranca, :tipo_cobranca_anterior, :natureza_recebimento, :carteira_variacao, :desconto, :iof, :carteira, :comando, :data_liquidacao, :data_vencimento, :valor_titulo, :banco_recebedor, :agencia_recebedora_com_dv, :especie_documento, :codigo_ocorrencia, :motivo_ocorrencia, :data_ocorrencia, :data_credito, :valor_tarifa, :outras_despesas, :juros_desconto, :iof_desconto, :valor_abatimento, :desconto_concedito, :valor_recebido, :juros_mora, :outros_recebimento, :abatimento_nao_aproveitado, :valor_lancamento, :indicativo_lancamento, :indicador_valor, :valor_ajuste, :sequencial, :arquivo
9
+
10
+ # Campos especificos para cobranca hibrida
11
+ attr_accessor :tipo_chave_dict,
12
+ :codigo_chave_dict,
13
+ :txid
9
14
  end
10
15
  end
11
16
  end
@@ -14,14 +14,11 @@ module Brcobranca
14
14
  def self.load_lines(file, options = {})
15
15
  default_options = { except: [1] } # por padrao ignora a primeira linha que é header
16
16
  options = default_options.merge!(options)
17
- super(file, options)
17
+ super
18
18
  end
19
19
 
20
- fixed_width_layout do |parse|
21
- # Todos os campos descritos no documento em ordem
22
- # identificacao do registro transacao
23
- # começa do 0 então contar com +1 as posições
24
- parse.field :codigo_registro, 0..0
20
+ # 1 - Registro Movimento
21
+ def self.parse_registro_movimento(parse)
25
22
  parse.field :agencia_com_dv, 17..20
26
23
  parse.field :cedente_com_dv, 23..28
27
24
  parse.field :nosso_numero, 62..69
@@ -50,6 +47,24 @@ module Brcobranca
50
47
  parse.field :juros_mora, 266..278
51
48
  parse.field :outros_recebimento, 279..291
52
49
  parse.field :data_credito, 295..300
50
+ end
51
+
52
+ # 2 - Registro Movimento – Identificacao dos dados Qr Code (PIX).
53
+ def self.parse_registro_pix(parse)
54
+ parse.field :tipo_chave_dict, 1..1
55
+ parse.field :codigo_chave_dict, 2..78
56
+ parse.field :txid, 79..113
57
+ end
58
+
59
+ fixed_width_layout do |parse|
60
+ # Todos os campos descritos no documento em ordem
61
+ # identificacao do registro transacao
62
+ # comeca do 0 entao contar com +1 as posicoes
63
+ parse.field :codigo_registro, 0..0
64
+
65
+ parse_registro_movimento(parse)
66
+ parse_registro_pix(parse)
67
+
53
68
  parse.field :sequencial, 394..399
54
69
  end
55
70
  end
@@ -13,7 +13,7 @@ module Brcobranca
13
13
  end
14
14
 
15
15
  module ClassMethods
16
- attr_reader :presences, :lengths, :numericals, :inclusions, :eachs
16
+ attr_reader :presences, :lengths, :numericals, :inclusions, :eachs, :with_formats
17
17
 
18
18
  def validates_presence_of(*attr_names)
19
19
  @presences ||= []
@@ -35,6 +35,11 @@ module Brcobranca
35
35
  @inclusions = @inclusions << attr_names
36
36
  end
37
37
 
38
+ def validates_format_of(*attr_names)
39
+ @with_formats ||= []
40
+ @with_formats = @with_formats << attr_names
41
+ end
42
+
38
43
  def validates_each(*attr_names, &block)
39
44
  @eachs ||= {}
40
45
  attr_names.each do |attr_name|
@@ -58,6 +63,7 @@ module Brcobranca
58
63
  all_valid = false unless check_numericals
59
64
  all_valid = false unless check_lengths
60
65
  all_valid = false unless check_inclusions
66
+ all_valid = false unless check_with_formats
61
67
  all_valid
62
68
  end
63
69
 
@@ -95,6 +101,8 @@ module Brcobranca
95
101
  all_present = true
96
102
  presences.each do |presence|
97
103
  presence.select { |p| p.is_a? Symbol }.each do |variable|
104
+ next unless valid_condition?(presence[-1])
105
+
98
106
  if blank?(send(variable))
99
107
  all_present = false
100
108
  errors.add variable, presence[-1][:message]
@@ -113,6 +121,8 @@ module Brcobranca
113
121
  all_numerical = true
114
122
  numericals.each do |numerical|
115
123
  numerical.select { |p| p.is_a? Symbol }.each do |variable|
124
+ next unless valid_condition?(numerical[-1])
125
+
116
126
  if respond_to?(variable) && send(variable) && (send(variable).to_s =~ /\A[+-]?\d+\z/).nil?
117
127
  all_numerical = false
118
128
  errors.add variable, numerical[-1][:message]
@@ -133,6 +143,7 @@ module Brcobranca
133
143
  lengths.each do |rule|
134
144
  variable = rule[0]
135
145
  next unless respond_to?(variable)
146
+ next unless valid_condition?(rule[-1])
136
147
 
137
148
  value = send(variable)
138
149
  if rule[-1][:in]
@@ -186,6 +197,7 @@ module Brcobranca
186
197
  next unless value
187
198
 
188
199
  next unless rule[-1][:in]
200
+ next unless valid_condition?(rule[-1])
189
201
 
190
202
  unless rule[-1][:in].include?(value)
191
203
  all_checked = false
@@ -195,6 +207,34 @@ module Brcobranca
195
207
  all_checked
196
208
  end
197
209
 
210
+ def check_with_formats
211
+ with_formats = []
212
+ if self.class.superclass.superclass.respond_to?(:with_formats)
213
+ with_formats = self.class.superclass.superclass.with_formats || []
214
+ end
215
+ with_formats += self.class.superclass.with_formats || [] if self.class.superclass.respond_to?(:with_formats)
216
+ with_formats += self.class.with_formats if self.class.with_formats
217
+ return true unless with_formats
218
+
219
+ all_checked = true
220
+ with_formats.each do |rule|
221
+ variable = rule[0]
222
+ next unless respond_to?(variable)
223
+
224
+ value = send(variable)
225
+ next unless value
226
+
227
+ next unless rule[-1][:with]
228
+ next unless valid_condition?(rule[-1])
229
+
230
+ unless value&.match?(rule[-1][:with])
231
+ all_checked = false
232
+ errors.add variable, rule[-1][:message]
233
+ end
234
+ end
235
+ all_checked
236
+ end
237
+
198
238
  def variable_name(symbol)
199
239
  symbol.to_s.tr('_', ' ').capitalize
200
240
  end
@@ -204,5 +244,17 @@ module Brcobranca
204
244
 
205
245
  obj.respond_to?(:empty?) ? obj.empty? : !obj
206
246
  end
247
+
248
+ def valid_condition?(rule)
249
+ return true unless rule[:if]
250
+
251
+ if rule[:if].is_a?(Symbol)
252
+ send(rule[:if])
253
+ elsif rule[:if].is_a?(Proc)
254
+ rule[:if].call(self)
255
+ else
256
+ raise ArgumentError, 'Condition must be a symbol or a proc'
257
+ end
258
+ end
207
259
  end
208
260
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Brcobranca
4
- VERSION = '11.0.0'
4
+ VERSION = '12.0.0'
5
5
  end
data/lib/brcobranca.rb CHANGED
@@ -160,6 +160,7 @@ module Brcobranca
160
160
  module Remessa
161
161
  autoload :Base, 'brcobranca/remessa/base'
162
162
  autoload :Pagamento, 'brcobranca/remessa/pagamento'
163
+ autoload :PagamentoPix, 'brcobranca/remessa/pagamento_pix'
163
164
 
164
165
  module Cnab400
165
166
  autoload :Base, 'brcobranca/remessa/cnab400/base'
@@ -169,6 +170,7 @@ module Brcobranca
169
170
  autoload :Itau, 'brcobranca/remessa/cnab400/itau'
170
171
  autoload :Citibank, 'brcobranca/remessa/cnab400/citibank'
171
172
  autoload :Santander, 'brcobranca/remessa/cnab400/santander'
173
+ autoload :SantanderPix, 'brcobranca/remessa/cnab400/santander_pix'
172
174
  autoload :Sicoob, 'brcobranca/remessa/cnab400/sicoob'
173
175
  autoload :BancoNordeste, 'brcobranca/remessa/cnab400/banco_nordeste'
174
176
  autoload :BancoBrasilia, 'brcobranca/remessa/cnab400/banco_brasilia'
@@ -176,6 +178,10 @@ module Brcobranca
176
178
  autoload :Credisis, 'brcobranca/remessa/cnab400/credisis'
177
179
  end
178
180
 
181
+ module Cnab444
182
+ autoload :Itau, 'brcobranca/remessa/cnab444/itau'
183
+ end
184
+
179
185
  module Cnab240
180
186
  autoload :Base, 'brcobranca/remessa/cnab240/base'
181
187
  autoload :BaseCorrespondente, 'brcobranca/remessa/cnab240/base_correspondente'
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: brcobranca
3
3
  version: !ruby/object:Gem::Version
4
- version: 11.0.0
4
+ version: 12.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kivanio Barbosa
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2024-01-12 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: fast_blank
@@ -42,14 +41,14 @@ dependencies:
42
41
  name: rghost
43
42
  requirement: !ruby/object:Gem::Requirement
44
43
  requirements:
45
- - - ">="
44
+ - - '='
46
45
  - !ruby/object:Gem::Version
47
46
  version: 0.9.8
48
47
  type: :runtime
49
48
  prerelease: false
50
49
  version_requirements: !ruby/object:Gem::Requirement
51
50
  requirements:
52
- - - ">="
51
+ - - '='
53
52
  - !ruby/object:Gem::Version
54
53
  version: 0.9.8
55
54
  - !ruby/object:Gem::Dependency
@@ -166,9 +165,12 @@ files:
166
165
  - lib/brcobranca/remessa/cnab400/credisis.rb
167
166
  - lib/brcobranca/remessa/cnab400/itau.rb
168
167
  - lib/brcobranca/remessa/cnab400/santander.rb
168
+ - lib/brcobranca/remessa/cnab400/santander_pix.rb
169
169
  - lib/brcobranca/remessa/cnab400/sicoob.rb
170
170
  - lib/brcobranca/remessa/cnab400/unicred.rb
171
+ - lib/brcobranca/remessa/cnab444/itau.rb
171
172
  - lib/brcobranca/remessa/pagamento.rb
173
+ - lib/brcobranca/remessa/pagamento_pix.rb
172
174
  - lib/brcobranca/retorno/base.rb
173
175
  - lib/brcobranca/retorno/cnab240/ailos.rb
174
176
  - lib/brcobranca/retorno/cnab240/base.rb
@@ -198,7 +200,6 @@ homepage: https://github.com/kivanio/brcobranca
198
200
  licenses: []
199
201
  metadata:
200
202
  rubygems_mfa_required: 'true'
201
- post_install_message:
202
203
  rdoc_options: []
203
204
  require_paths:
204
205
  - lib
@@ -214,8 +215,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
214
215
  version: '0'
215
216
  requirements:
216
217
  - GhostScript > 9.0, para gerar PDF e código de Barras
217
- rubygems_version: 3.5.4
218
- signing_key:
218
+ rubygems_version: 3.6.7
219
219
  specification_version: 4
220
220
  summary: Gem que permite trabalhar com boletos e CNABs para bancos brasileiros.
221
221
  test_files: []