diff --git a/.travis.yml b/.travis.yml
index b50a925..a735fb9 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -31,7 +31,7 @@ install:
- pip install git+https://github.com/aricaldeira/pybrasil.git
- pip install pyboleto
- pip install fixedwidth
- - pip install https://github.com/kmee/cnab240/archive/master.zip
+ - pip install git+https://github.com/kmee/cnab240.git@feature/pagamento
- travis_install_nightly
before_script:
diff --git a/l10n_br_account_banking_payment/__openerp__.py b/l10n_br_account_banking_payment/__openerp__.py
index a63ab3a..4329ce4 100644
--- a/l10n_br_account_banking_payment/__openerp__.py
+++ b/l10n_br_account_banking_payment/__openerp__.py
@@ -32,7 +32,6 @@
'website': 'https://github.com/odoo-brazil/odoo-brazil-banking',
'category': 'Banking addons',
'depends': [
- 'l10n_br_account',
'l10n_br_account',
'account_banking_payment_export',
],
@@ -42,7 +41,7 @@
'views/payment_mode.xml',
'views/payment_mode_type.xml',
'wizard/payment_order_create_view.xml',
- 'data/payment_mode_type.xml',
+ # 'data/payment_mode_type.xml',
],
'demo': [
],
diff --git a/l10n_br_account_banking_payment/models/account_payment.py b/l10n_br_account_banking_payment/models/account_payment.py
index cf4ca2a..29e1b39 100644
--- a/l10n_br_account_banking_payment/models/account_payment.py
+++ b/l10n_br_account_banking_payment/models/account_payment.py
@@ -26,6 +26,7 @@
from openerp import models, fields, api
from openerp.addons import decimal_precision as dp
from openerp.tools.float_utils import float_round as round
+from openerp.exceptions import ValidationError
class PaymentOrder(models.Model):
@@ -41,6 +42,17 @@ class PaymentOrder(models.Model):
def _compute_total(self):
self.total = sum(self.mapped('line_ids.amount') or [0.0])
+ @api.multi
+ def action_open(self):
+ """
+ Validacao para nao confirmar ordem de pagamento vazia
+ """
+ for record in self:
+ if not record.line_ids:
+ raise ValidationError("Impossivel confirmar linha vazia!")
+ res = super(PaymentOrder, self).action_open()
+ return res
+
class PaymentLine(models.Model):
_inherit = 'payment.line'
@@ -58,8 +70,8 @@ def _get_info_partner(self, cr, uid, partner_record, context=None):
cntry = partner_record.country_id and \
partner_record.country_id.name or ''
cnpj = partner_record.cnpj_cpf or ''
- return partner_record.legal_name + "\n" + cnpj + "\n" + st + ", " \
- + n + " " + st1 + "\n" + zip_city + "\n" + cntry
+ return partner_record.legal_name or '' + "\n" + cnpj + "\n" + st \
+ + ", " + n + " " + st1 + "\n" + zip_city + "\n" + cntry
@api.one
@api.depends('percent_interest', 'amount_currency')
diff --git a/l10n_br_account_banking_payment/views/account_payment.xml b/l10n_br_account_banking_payment/views/account_payment.xml
index f603877..59c507d 100644
--- a/l10n_br_account_banking_payment/views/account_payment.xml
+++ b/l10n_br_account_banking_payment/views/account_payment.xml
@@ -12,9 +12,6 @@
-
-
-
diff --git a/l10n_br_account_banking_payment_bradesco_tributos/model/payment_mode.py b/l10n_br_account_banking_payment_bradesco_tributos/model/payment_mode.py
index cbb1107..5e8faf4 100644
--- a/l10n_br_account_banking_payment_bradesco_tributos/model/payment_mode.py
+++ b/l10n_br_account_banking_payment_bradesco_tributos/model/payment_mode.py
@@ -26,10 +26,10 @@
class PaymentMode(models.Model):
_inherit = "payment.mode"
- payment_order_type = fields.Selection(
- selection_add=[
- ('tax', u'Tributos'),
- ])
+ # payment_order_type = fields.Selection(
+ # selection_add=[
+ # ('tax', u'Tributos'),
+ # ])
gnre_value_field = fields.Many2one(
'ir.model.fields', 'Value field',
domain=[('model_id', '=', 'account.invoice')])
@@ -40,24 +40,24 @@ class PaymentModeType(models.Model):
_inherit = 'payment.mode.type'
_description = 'Payment Mode Type'
- payment_order_type = fields.Selection(
- selection_add=[
- ('tax', u'Tributos'),
- ])
+ # payment_order_type = fields.Selection(
+ # selection_add=[
+ # ('tax', u'Tributos'),
+ # ])
class PaymentOrder(models.Model):
_inherit = 'payment.order'
- payment_order_type = fields.Selection(
- selection_add=[
- ('tax', u'Tributos'),
- ])
+ # payment_order_type = fields.Selection(
+ # selection_add=[
+ # ('tax', u'Tributos'),
+ # ])
class AccountMoveLine(models.Model):
_inherit = 'account.move.line'
- has_gnre = fields.Boolean(
- related='stored_invoice_id.has_gnre',
- string="Tem GNRE")
+ # has_gnre = fields.Boolean(
+ # related='stored_invoice_id.has_gnre',
+ # string="Tem GNRE")
diff --git a/l10n_br_account_banking_payment_cnab/__openerp__.py b/l10n_br_account_banking_payment_cnab/__openerp__.py
index d486b4a..c2b06d7 100644
--- a/l10n_br_account_banking_payment_cnab/__openerp__.py
+++ b/l10n_br_account_banking_payment_cnab/__openerp__.py
@@ -37,9 +37,9 @@
'l10n_br_account_payment_boleto',
'l10n_br_account_payment_mode',
'l10n_br_account_product',
- 'account_banking_payment_export',
],
'data': [
+ 'security/cnab_cobranca_security.xml',
'view/l10n_br_payment_cnab.xml',
'view/payment_order.xml',
'view/l10n_br_cnab_sequence.xml',
@@ -47,12 +47,18 @@
'view/l10n_br_cobranca_cnab_lines.xml',
'view/account_move_line.xml',
'view/res_partner_bank.xml',
+ 'view/l10n_br_cnab_retorno_view.xml',
'view/payment_mode.xml',
+ 'view/payment_line.xml',
+ 'view/bank_payment_line.xml',
'data/l10n_br_payment_export_type.xml',
- 'data/l10n_br_payment_mode.xml',
+ 'security/ir.model.access.csv',
+ ],
+ 'demo': [
+ # 'demo/l10n_br_payment_mode.xml',
],
'test': [
- 'tests/invoice_create.yml'
+ # 'tests/invoice_create.yml'
],
"installable": True,
"auto_install": False,
diff --git a/l10n_br_account_banking_payment_cnab/constantes.py b/l10n_br_account_banking_payment_cnab/constantes.py
new file mode 100644
index 0000000..393ed67
--- /dev/null
+++ b/l10n_br_account_banking_payment_cnab/constantes.py
@@ -0,0 +1,418 @@
+# -*- coding: utf-8 -*-
+
+COBRANCA = '01'
+BOLETO_PAGAMENTO_ELETRONICO = '03'
+CONCILIACAO_BANCARIA = '04'
+DEBITOS = '05'
+CUSTODIA_CHEQUES = '06'
+GESTAO_CAIXA = '07'
+CONSULTA_INFORMACAO_MARGEM = '08'
+AVERBACAO_CONSIGNACAO_RETENCAO = '09'
+PAGAMENTO_DIVIDENDOS = '10'
+MANUTENCAO_CONSIGNACAO = '11'
+CONSIGNACAO_PARCELAS = '12'
+GLOSA_CONSIGNACAO = '13'
+CONSULTA_TRIBUTOS_PAGAR = '14'
+PAGAMENTO_FORNECEDOR = '20'
+PAGAMENTO_CONTAS_TRIBUTOS_IMPOSTOS = '22'
+INTEROPERABILIDADE_CONTAS = '23'
+COMPROR = '25'
+COMPROR_ROTATIVO = '26'
+ALEGACAO_PAGADOR = '29'
+PAGAMENTO_SALARIOS = '30'
+PAGAMENTO_HONORARIOS = '32'
+PAGAMENTO_BOLSA_AUXILIO = '33'
+PAGAMENTO_PREBENDA = '34'
+VENDOR = '40'
+VENDOR_TERMO = '41'
+PAGAMENTO_SINISTROS_SEGURADOS = '50'
+PAGAMENTO_DESPESAS_VIAJANTE = '60'
+PAGAMENTO_AUTORIZADO = '70'
+PAGAMENTO_CREDENCIADOS = '75'
+PAGAMENTO_REMUNERACAO = '77'
+PAGAMENTO_REPRESENTANTES = '80'
+PAGAMENTO_BENEFICIOS = '90'
+PAGAMENTOS_DIVERSOS = '98'
+
+TIPO_SERVICO = [
+ (COBRANCA, COBRANCA + u' - Cobrança'),
+ (BOLETO_PAGAMENTO_ELETRONICO, BOLETO_PAGAMENTO_ELETRONICO +
+ u' - Boleto de Pagamento Eletrônico'),
+ (CONCILIACAO_BANCARIA, CONCILIACAO_BANCARIA + u' - Conciliação Bancária'),
+ (DEBITOS, DEBITOS + u' - Débitos'),
+ (CUSTODIA_CHEQUES, CUSTODIA_CHEQUES + u' - Custódia de Cheques'),
+ (GESTAO_CAIXA, GESTAO_CAIXA + u' - Gestão de Caixa'),
+ (CONSULTA_INFORMACAO_MARGEM, CONSULTA_INFORMACAO_MARGEM +
+ u' - Consulta/Informação Margem'),
+ (AVERBACAO_CONSIGNACAO_RETENCAO, AVERBACAO_CONSIGNACAO_RETENCAO +
+ u' - Averbação da Consignação/Retenção'),
+ (PAGAMENTO_DIVIDENDOS, PAGAMENTO_DIVIDENDOS + u' - Pagamento Dividendos'),
+ (MANUTENCAO_CONSIGNACAO, MANUTENCAO_CONSIGNACAO +
+ u' - Manutenção da Consignação'),
+ (CONSIGNACAO_PARCELAS, CONSIGNACAO_PARCELAS +
+ u' - Consignação de Parcelas'),
+ (GLOSA_CONSIGNACAO, GLOSA_CONSIGNACAO +
+ u' - Glosa da Consignação (INSS)'),
+ (CONSULTA_TRIBUTOS_PAGAR, CONSULTA_TRIBUTOS_PAGAR +
+ u' - Consulta de Tributos a pagar'),
+ (PAGAMENTO_FORNECEDOR, PAGAMENTO_FORNECEDOR +
+ u' - Pagamento Fornecedor'),
+ (PAGAMENTO_CONTAS_TRIBUTOS_IMPOSTOS, PAGAMENTO_CONTAS_TRIBUTOS_IMPOSTOS +
+ u' - Pagamento de Contas, Tributos e Impostos'),
+ (INTEROPERABILIDADE_CONTAS, INTEROPERABILIDADE_CONTAS +
+ u' - Interoperabilidade entre Contas de Instituições de Pagamentos'),
+ (COMPROR, COMPROR + u' - Compror'),
+ (COMPROR_ROTATIVO, COMPROR_ROTATIVO + u' - Compror Rotativo'),
+ (ALEGACAO_PAGADOR, ALEGACAO_PAGADOR + u' - Alegação do Pagador'),
+ (PAGAMENTO_SALARIOS, PAGAMENTO_SALARIOS + u' - Pagamento Salários'),
+ (PAGAMENTO_HONORARIOS, PAGAMENTO_HONORARIOS +
+ u' - Pagamento de honorários'),
+ (PAGAMENTO_BOLSA_AUXILIO, PAGAMENTO_BOLSA_AUXILIO +
+ u' - Pagamento de bolsa auxílio'),
+ (PAGAMENTO_PREBENDA, PAGAMENTO_PREBENDA +
+ u' - Pagamento de prebenda (remuneração a padres e sacerdotes)'),
+ (VENDOR, VENDOR + u' - Vendor'),
+ (VENDOR_TERMO, VENDOR_TERMO + u' - Vendor a Termo'),
+ (PAGAMENTO_SINISTROS_SEGURADOS, PAGAMENTO_SINISTROS_SEGURADOS +
+ u' - Pagamento Sinistros Segurados'),
+ (PAGAMENTO_DESPESAS_VIAJANTE, PAGAMENTO_DESPESAS_VIAJANTE +
+ u' - Pagamento Despesas Viajante em Trânsito'),
+ (PAGAMENTO_AUTORIZADO, PAGAMENTO_AUTORIZADO + u' - Pagamento Autorizado'),
+ (PAGAMENTO_CREDENCIADOS, PAGAMENTO_CREDENCIADOS +
+ u' - Pagamento Credenciados'),
+ (PAGAMENTO_REMUNERACAO, PAGAMENTO_REMUNERACAO +
+ u' - Pagamento de Remuneração'),
+ (PAGAMENTO_REPRESENTANTES, PAGAMENTO_REPRESENTANTES +
+ u' - Pagamento Representantes / Vendedores Autorizados'),
+ (PAGAMENTO_BENEFICIOS, PAGAMENTO_BENEFICIOS + u' - Pagamento Benefícios'),
+ (PAGAMENTOS_DIVERSOS, PAGAMENTOS_DIVERSOS + u' - Pagamentos Diversos'),
+]
+
+CREDITO_CONTA_CORRENTE_SALARIO = (
+ '01', u'01 - Crédito em Conta Corrente/Salário')
+CHEQUE_PAGAMENTO_ADMINISTRATIVO = (
+ '02', u'02 - Cheque Pagamento / Administrativo')
+DOC_TED = ('03', u'03 - DOC/TED (1) (2)')
+CARTAO_SALARIO = (
+ '04', u'04 - Cartão Salário (somente para Tipo de Serviço = \'30\')')
+CREDITO_CONTA_POUPANCA = ('05', u'05 - Crédito em Conta Poupança')
+OP_A_DISPOSICAO = ('10', u'10 - OP à Disposição')
+PAGAMENTO_CONTAS_TRIBUTOS_CODIGO_BARRAS = (
+ '11', u'11 - Pagamento de Contas e Tributos com Código de Barras')
+TRIBUTO_DARF_NORMAL = ('16', u'16 - Tributo - DARF Normal')
+TRIBUTO_GPS = ('17', u'17 - Tributo - GPS (Guia da Previdência Social)')
+TRIBUTO_DARF_SIMPLES = ('18', u'18 - Tributo - DARF Simples')
+TRIBUTO_IPTU_PREFEITURAS = ('19', u'19 - Tributo - IPTU – Prefeituras')
+PAGAMENTO_AUTENTICACAO = ('20', u'20 - Pagamento com Autenticação')
+TRIBUTO_DARJ = ('21', u'21 - Tributo – DARJ')
+TRIBUTO_GARE_SP_ICMS = ('22', u'22 - Tributo - GARE-SP ICMS')
+TRIBUTO_GARE_SP_DR = ('23', u'23 - Tributo - GARE-SP DR')
+TRIBUTO_GARE_SP_ITCMD = ('24', u'24 - Tributo - GARE-SP ITCMD')
+TRIBUTO_IPVA = ('25', u'25 - Tributo - IPVA')
+TRIBUTO_LICENCIAMENTO = ('26', u'26 - Tributo - Licenciamento')
+TRIBUTO_DPVAT = ('27', u'27 - Tributo – DPVAT')
+LIQUIDACAO_TITULOS_PROPRIO_BANCO = (
+ '30', u'30 - Liquidação de Títulos do Próprio Banco')
+PAGAMENTO_TITULOS_OUTROS_BANCOS = (
+ '31', u'31 - Pagamento de Títulos de Outros Bancos')
+EXTRATO_CONTA_CORRENTE = ('40', u'40 - Extrato de Conta Corrente')
+TED_OUTRA_TITULARIDADE = ('41', u'41 - TED – Outra Titularidade (1)')
+TED_MESMA_TITULARIDADE = ('43', u'43 - TED – Mesma Titularidade (1)')
+TED_TRANSFERENCIA_CONTA_INVESTIMENTO = (
+ '44', u'44 - TED para Transferência de Conta Investimento')
+DEBITO_CONTA_CORRENTE = ('50', u'50 - Débito em Conta Corrente')
+EXTRATO_GESTAO_CAIXA = ('70', u'70 - Extrato para Gestão de Caixa')
+DEPOSITO_JUDICIAL_CONTA_CORRENTE = (
+ '71', u'71 - Depósito Judicial em Conta Corrente')
+DEPOSITO_JUDICIAL_POUPANCA = ('72', u'72 - Depósito Judicial em Poupança')
+EXTRATO_CONTA_INVESTIMENTO = ('73', u'73 - Extrato de Conta Investimento')
+
+FORMA_LANCAMENTO = [
+ CREDITO_CONTA_CORRENTE_SALARIO,
+ CHEQUE_PAGAMENTO_ADMINISTRATIVO,
+ DOC_TED,
+ CARTAO_SALARIO,
+ CREDITO_CONTA_POUPANCA,
+ OP_A_DISPOSICAO,
+ PAGAMENTO_CONTAS_TRIBUTOS_CODIGO_BARRAS,
+ TRIBUTO_DARF_NORMAL,
+ TRIBUTO_GPS,
+ TRIBUTO_DARF_SIMPLES,
+ TRIBUTO_IPTU_PREFEITURAS,
+ PAGAMENTO_AUTENTICACAO,
+ TRIBUTO_DARJ,
+ TRIBUTO_GARE_SP_ICMS,
+ TRIBUTO_GARE_SP_DR,
+ TRIBUTO_GARE_SP_ITCMD,
+ TRIBUTO_IPVA,
+ TRIBUTO_LICENCIAMENTO,
+ TRIBUTO_DPVAT,
+ LIQUIDACAO_TITULOS_PROPRIO_BANCO,
+ PAGAMENTO_TITULOS_OUTROS_BANCOS,
+ EXTRATO_CONTA_CORRENTE,
+ TED_OUTRA_TITULARIDADE,
+ TED_MESMA_TITULARIDADE,
+ TED_TRANSFERENCIA_CONTA_INVESTIMENTO,
+ DEBITO_CONTA_CORRENTE,
+ EXTRATO_GESTAO_CAIXA,
+ DEPOSITO_JUDICIAL_CONTA_CORRENTE,
+ DEPOSITO_JUDICIAL_POUPANCA,
+ EXTRATO_CONTA_INVESTIMENTO,
+]
+
+CREDITO_EM_CONTA = ('01', u'01 - Crédito em Conta')
+PAGAMENTO_ALUGUEL = ('02', u'02 - Pagamento de Aluguel/Condomínio')
+PAGAMENTO_DUPLICATA_TITULOS = ('03', u'03 - Pagamento de Duplicata/Títulos')
+PAGAMENTO_DIVIDENDOS_C = ('04', u'04 - Pagamento de Dividendos')
+PAGAMENTO_MENSALIDADE_ESCOLAR = (
+ '05', u'05 - Pagamento de Mensalidade Escolar')
+PAGAMENTO_SALARIOS_C = ('06', u'06 - Pagamento de Salários')
+PAGAMENTO_FORNECEDORES = ('07', u'07 - Pagamento a Fornecedores')
+OPERACOES_CAMBIOS_FUNDOS_BOLSA = (
+ '08', u'08 - Operações de Câmbios/Fundos/Bolsa de Valores')
+REPASSE_ARRECADACAO = (
+ '09', u'09 - Repasse de Arrecadação/Pagamento de Tributos')
+TRANSFERECIA_INTERNACIONAL_EM_REAL = (
+ '10', u'10 - Transferência Internacional em Real')
+DOC_POUPANCA = ('11', u'11 - DOC para Poupança')
+DOC_DEPOSITO_JUDICIAL = ('12', u'12 - DOC para Depósito Judicial')
+OUTROS = ('13', u'13 - Outros')
+PAGAMENTO_BOLSA_AUXILIO_C = ('16', u'16 - Pagamento de bolsa auxílio')
+REMUNERACAO_COOPERADO = ('17', u'17 - Remuneração à cooperado')
+PAGAMENTO_HONORARIOS_C = ('18', u'18 - Pagamento de honorários')
+PAGAMENTO_PREBENDA_C = (
+ '19', u'19 - Pagamento de prebenda (Remuneração a padres e sacerdotes)')
+
+COMPLEMENTO_TIPO_SERVICO = [
+ CREDITO_EM_CONTA,
+ PAGAMENTO_ALUGUEL,
+ PAGAMENTO_DUPLICATA_TITULOS,
+ PAGAMENTO_DIVIDENDOS_C,
+ PAGAMENTO_MENSALIDADE_ESCOLAR,
+ PAGAMENTO_SALARIOS_C,
+ PAGAMENTO_FORNECEDORES,
+ OPERACOES_CAMBIOS_FUNDOS_BOLSA,
+ REPASSE_ARRECADACAO,
+ TRANSFERECIA_INTERNACIONAL_EM_REAL,
+ DOC_POUPANCA,
+ DOC_DEPOSITO_JUDICIAL,
+ OUTROS,
+ PAGAMENTO_BOLSA_AUXILIO_C,
+ REMUNERACAO_COOPERADO,
+ PAGAMENTO_HONORARIOS_C,
+ PAGAMENTO_PREBENDA_C,
+]
+
+# Codigo adotado pelo Banco Central para identificar a
+# finalidade da TED. Utitilizar os
+# códigos de finalidade cliente, disponíveis no site do Banco Central do Brasil
+# (www.bcb.gov.br), Sistema de Pagamentos Brasileiro,
+# Transferência de Arquivos,
+# Dicionários de Domínios para o SPB.
+CODIGO_FINALIDADE_TED = [
+ (' ', u'Padrão')
+]
+
+NAO_EMITE_AVISO = ('0', u'0 - Não Emite Aviso')
+EMITE_AVISO_REMETENTE = ('2', u'2 - Emite Aviso Somente para o Remetente')
+EMITE_AVISO_FAVORECIDO = ('5', u'5 - Emite Aviso Somente para o Favorecido')
+EMITE_AVISO_REMETENTE_FAVORECIDO = \
+ ('6', u'6 - Emite Aviso para o Remetente e Favorecido')
+EMITE_AVISO_FAVORECIDO_2_VIAS_REMETENTE = \
+ ('7', u'7 - Emite Aviso para o Favorecido e 2 Vias para o Remetente')
+
+AVISO_FAVORECIDO = [
+ NAO_EMITE_AVISO,
+ EMITE_AVISO_REMETENTE,
+ EMITE_AVISO_FAVORECIDO,
+ EMITE_AVISO_REMETENTE_FAVORECIDO,
+ EMITE_AVISO_FAVORECIDO_2_VIAS_REMETENTE,
+]
+
+INDICATIVO_FORMA_PAGAMENTO = [
+ ('01', u'01 - Débito em Conta Corrente'),
+ ('02', u'02 - Débito Empréstimo/Financiamento'),
+ ('03', u'03 - Débito Cartão de Crédito'),
+]
+
+TIPO_MOVIMENTO = [
+ ('0', u'0 - Indica INCLUSÃO'),
+ ('1', u'1 - Indica CONSULTA'),
+ ('2', u'2 - Indica SUSPENSÃO'),
+ ('3', u'3 - Indica ESTORNO (somente para retorno)'),
+ ('4', u'4 - Indica REATIVAÇÃO'),
+ ('5', u'5 - Indica ALTERAÇÃO'),
+ ('7', u'7 - Indica LIQUIDAÇAO'),
+ ('9', u'9 - Indica EXCLUSÃO'),
+]
+
+CODIGO_INSTRUCAO_MOVIMENTO = [
+ ('0', u'00 - Inclusão de Registro Detalhe Liberado'),
+ ('9', u'09 - Inclusão do Registro Detalhe Bloqueado'),
+ ('10', u'10 - Alteração do Pagamento Liberado para Bloqueado (Bloqueio)'),
+ ('11', u'11 - Alteração do Pagamento Bloqueado para Liberado (Liberação)'),
+ ('17', u'17 - Alteração do Valor do Título'),
+ ('19', u'19 - Alteração da Data de Pagamento'),
+ ('23', u'23 - Pagamento Direto ao Fornecedor - Baixar'),
+ ('25', u'25 - Manutenção em Carteira - Não Pagar'),
+ ('27', u'27 - Retirada de Carteira - Não Pagar'),
+ ('33', u'33 - Estorno por Devolução da Câmara Centralizadora '
+ u'(somente para Tipo de Movimento = \'3\')'),
+ ('40', u'40 - Alegação do Pagador'),
+ ('99', u'99 - Exclusão do Registro Detalhe Incluído Anteriormente'),
+]
+
+CODIGO_OCORRENCIAS = [
+ ('00', u'00 - Crédito ou Débito Efetivado'),
+ ('01', u'01 - Insuficiência de Fundos - Débito Não Efetuado'),
+ ('02', u'02 - Crédito ou Débito Cancelado pelo Pagador/Credor'),
+ ('03', u'03 - Débito Autorizado pela Agência - Efetuado'),
+ ('AA', u'AA - Controle Inválido'),
+ ('AB', u'AB - Tipo de Operação Inválido'),
+ ('AC', u'AC - Tipo de Serviço Inválido'),
+ ('AD', u'AD - Forma de Lançamento Inválida'),
+ ('AE', u'AE - Tipo/Número de Inscrição Inválido'),
+ ('AF', u'AF - Código de Convênio Inválido'),
+ ('AG', u'AG - Agência/Conta Corrente/DV Inválido'),
+ ('AH', u'AH - Nº Seqüencial do Registro no Lote Inválido'),
+ ('AI', u'AI - Código de Segmento de Detalhe Inválido'),
+ ('AJ', u'AJ - Tipo de Movimento Inválido'),
+ ('AK', u'AK - Código da Câmara de Compensação do Banco'
+ u' Favorecido/Depositário Inválido'),
+ ('AL', u'AL - Código do Banco Favorecido, Instituição de Pagamento'
+ u' ou Depositário Inválido'),
+ ('AM', u'AM - Agência Mantenedora da Conta Corrente do'
+ u' Favorecido Inválida'),
+ ('AN', u'AN - Conta Corrente/DV/Conta de Pagamento do'
+ u' Favorecido Inválido'),
+ ('AO', u'AO - Nome do Favorecido Não Informado'),
+ ('AP', u'AP - Data Lançamento Inválido'),
+ ('AQ', u'AQ - Tipo/Quantidade da Moeda Inválido'),
+ ('AR', u'AR - Valor do Lançamento Inválido'),
+ ('AS', u'AS - Aviso ao Favorecido - Identificação Inválida'),
+ ('AT', u'AT - Tipo/Número de Inscrição do Favorecido Inválido'),
+ ('AU', u'AU - Logradouro do Favorecido Não Informado'),
+ ('AV', u'AV - Nº do Local do Favorecido Não Informado'),
+ ('AW', u'AW - Cidade do Favorecido Não Informada'),
+ ('AX', u'AX - CEP/Complemento do Favorecido Inválido'),
+ ('AY', u'AY - Sigla do Estado do Favorecido Inválida'),
+ ('AZ', u'AZ - Código/Nome do Banco Depositário Inválido'),
+ ('BA', u'BA - Código/Nome da Agência Depositária Não Informado'),
+ ('BB', u'BB - Seu Número Inválido'),
+ ('BC', u'BC - Nosso Número Inválido'),
+ ('BD', u'BD - Inclusão Efetuada com Sucesso'),
+ ('BE', u'BE - Alteração Efetuada com Sucesso'),
+ ('BF', u'BF - Exclusão Efetuada com Sucesso'),
+ ('BG', u'BG - Agência/Conta Impedida Legalmente'),
+ ('BH', u'BH - Empresa não pagou salário'),
+ ('BI', u'BI - Falecimento do mutuário'),
+ ('BJ', u'BJ - Empresa não enviou remessa do mutuário'),
+ ('BK', u'BK - Empresa não enviou remessa no vencimento'),
+ ('BL', u'BL - Valor da parcela inválida'),
+ ('BM', u'BM - Identificação do contrato inválida'),
+ ('BN', u'BN - Operação de Consignação Incluída com Sucesso'),
+ ('BO', u'BO - Operação de Consignação Alterada com Sucesso'),
+ ('BP', u'BP - Operação de Consignação Excluída com Sucesso'),
+ ('BQ', u'BQ - Operação de Consignação Liquidada com Sucesso'),
+ ('BR', u'BR - Reativação Efetuada com Sucesso'),
+ ('BS', u'BS - Suspensão Efetuada com Sucesso'),
+ ('CA', u'CA - Código de Barras - Código do Banco Inválido'),
+ ('CB', u'CB - Código de Barras - Código da Moeda Inválido'),
+ ('CC', u'CC - Código de Barras - Dígito Verificador Geral Inválido'),
+ ('CD', u'CD - Código de Barras - Valor do Título Inválido'),
+ ('CE', u'CE - Código de Barras - Campo Livre Inválido'),
+ ('CF', u'CF - Valor do Documento Inválido'),
+ ('CG', u'CG - Valor do Abatimento Inválido'),
+ ('CH', u'CH - Valor do Desconto Inválido'),
+ ('CI', u'CI - Valor de Mora Inválido'),
+ ('CJ', u'CJ - Valor da Multa Inválido'),
+ ('CK', u'CK - Valor do IR Inválido'),
+ ('CL', u'CL - Valor do ISS Inválido'),
+ ('CM', u'CM - Valor do IOF Inválido'),
+ ('CN', u'CN - Valor de Outras Deduções Inválido'),
+ ('CO', u'CO - Valor de Outros Acréscimos Inválido'),
+ ('CP', u'CP - Valor do INSS Inválido'),
+ ('HA', u'HA - Lote Não Aceito'),
+ ('HB', u'HB - Inscrição da Empresa Inválida para o Contrato'),
+ ('HC', u'HC - Convênio com a Empresa Inexistente/Inválido'
+ u' para o Contrato'),
+ ('HD', u'HD - Agência/Conta Corrente da Empresa Inexistente/Inválido'
+ u' para o Contrato'),
+ ('HE', u'HE - Tipo de Serviço Inválido para o Contrato'),
+ ('HF', u'HF - Conta Corrente da Empresa com Saldo Insuficiente'),
+ ('HG', u'HG - Lote de Serviço Fora de Seqüência'),
+ ('HH', u'HH - Lote de Serviço Inválido'),
+ ('HI', u'HI - Arquivo não aceito'),
+ ('HJ', u'HJ - Tipo de Registro Inválido'),
+ ('HK', u'HK - Código Remessa / Retorno Inválido'),
+ ('HL', u'HL - Versão de layout inválida'),
+ ('HM', u'HM - Mutuário não identificado'),
+ ('HN', u'HN - Tipo do beneficio não permite empréstimo'),
+ ('HO', u'HO - Beneficio cessado/suspenso'),
+ ('HP', u'HP - Beneficio possui representante legal'),
+ ('HQ', u'HQ - Beneficio é do tipo PA (Pensão alimentícia)'),
+ ('HR', u'HR - Quantidade de contratos permitida excedida'),
+ ('HS', u'HS - Beneficio não pertence ao Banco informado'),
+ ('HT', u'HT - Início do desconto informado já ultrapassado'),
+ ('HU', u'HU - Número da parcela inválida'),
+ ('HV', u'HV - Quantidade de parcela inválida'),
+ ('HW', u'HW - Margem consignável excedida para o mutuário dentro'
+ u' do prazo do contrato'),
+ ('HX', u'HX - Empréstimo já cadastrado'),
+ ('HY', u'HY - Empréstimo inexistente'),
+ ('HZ', u'HZ - Empréstimo já encerrado'),
+ ('H1', u'H1 - Arquivo sem trailer'),
+ ('H2', u'H2 - Mutuário sem crédito na competência'),
+ ('H3', u'H3 - Não descontado – outros motivos'),
+ ('H4', u'H4 - Retorno de Crédito não pago'),
+ ('H5', u'H5 - Cancelamento de empréstimo retroativo'),
+ ('H6', u'H6 - Outros Motivos de Glosa'),
+ ('H7', u'H7 - Margem consignável excedida para o mutuário acima'
+ u' do prazo do contrato'),
+ ('H8', u'H8 - Mutuário desligado do empregador'),
+ ('H9', u'H9 - Mutuário afastado por licença'),
+ ('IA', u'IA - Primeiro nome do mutuário diferente do primeiro nome'
+ u' do movimento do censo ou diferente da base de Titular'
+ u' do Benefício'),
+ ('IB', u'IB - Benefício suspenso/cessado pela APS ou Sisobi'),
+ ('IC', u'IC - Benefício suspenso por dependência de cálculo'),
+ ('ID', u'ID - Benefício suspenso/cessado pela inspetoria/auditoria'),
+ ('IE', u'IE - Benefício bloqueado para empréstimo pelo beneficiário'),
+ ('IF', u'IF - Benefício bloqueado para empréstimo por TBM'),
+ ('IG', u'IG - Benefício está em fase de concessão de PA ou desdobramento'),
+ ('IH', u'IH - Benefício cessado por óbito'),
+ ('II', u'II - Benefício cessado por fraude'),
+ ('IJ', u'IJ - Benefício cessado por concessão de outro benefício'),
+ ('IK', u'IK - Benefício cessado: estatutário transferido'
+ u' para órgão de origem'),
+ ('IL', u'IL - Empréstimo suspenso pela APS'),
+ ('IM', u'IM - Empréstimo cancelado pelo banco'),
+ ('IN', u'IN - Crédito transformado em PAB'),
+ ('IO', u'IO - Término da consignação foi alterado'),
+ ('IP', u'IP - Fim do empréstimo ocorreu durante período'
+ u' de suspensão ou concessão'),
+ ('IQ', u'IQ - Empréstimo suspenso pelo banco'),
+ ('IR', u'IR - Não averbação de contrato – quantidade de'
+ u' parcelas/competências informadas ultrapassou a data limite'
+ u' da extinção de cota do dependente titular de benefícios'),
+ ('TA', u'TA - Lote Não Aceito - Totais do Lote com Diferença'),
+ ('YA', u'YA - Título Não Encontrado'),
+ ('YB', u'YB - Identificador Registro Opcional Inválido'),
+ ('YC', u'YC - Código Padrão Inválido'),
+ ('YD', u'YD - Código de Ocorrência Inválido'),
+ ('YE', u'YE - Complemento de Ocorrência Inválido'),
+ ('YF', u'YF - Alegação já Informada'),
+ ('ZA', u'ZA - Agência / Conta do Favorecido Substituída'),
+ ('ZB', u'ZB - Divergência entre o primeiro e último nome do beneficiário'
+ u' versus primeiro e último nome na Receita Federal'),
+ ('ZC', u'ZC - Confirmação de Antecipação de Valor'),
+ ('ZD', u'ZD - Antecipação parcial de valor'),
+ ('ZE', u'ZE - Título bloqueado na base'),
+ ('ZF', u'ZF - Sistema em contingência'
+ u' – título valor maior que referência'),
+ ('ZG', u'ZG - Sistema em contingência – título vencido'),
+ ('ZH', u'ZH - Sistema em contingência – título indexado'),
+ ('ZI', u'ZI - Beneficiário divergente'),
+ ('ZJ', u'ZJ - Limite de pagamentos parciais excedido'),
+ ('ZK', u'ZK - Boleto já liquidado'),
+]
diff --git a/l10n_br_account_banking_payment_cnab/data/l10n_br_payment_export_type.xml b/l10n_br_account_banking_payment_cnab/data/l10n_br_payment_export_type.xml
index 98952df..edbc317 100644
--- a/l10n_br_account_banking_payment_cnab/data/l10n_br_payment_export_type.xml
+++ b/l10n_br_account_banking_payment_cnab/data/l10n_br_payment_export_type.xml
@@ -3,16 +3,16 @@
+
240
Cnab240
True
- cobranca
-
+ payment
+
-
+
@@ -24,7 +24,7 @@
ref="l10n_br_account_banking_payment_cnab.model_payment_cnab"/>
-
+
@@ -37,7 +37,7 @@
ref="l10n_br_account_banking_payment_cnab.model_payment_cnab"/>
-
+
diff --git a/l10n_br_account_banking_payment_cnab/data/l10n_br_payment_mode.xml b/l10n_br_account_banking_payment_cnab/demo/l10n_br_payment_mode.xml
similarity index 100%
rename from l10n_br_account_banking_payment_cnab/data/l10n_br_payment_mode.xml
rename to l10n_br_account_banking_payment_cnab/demo/l10n_br_payment_mode.xml
diff --git a/l10n_br_account_banking_payment_cnab/febraban/cnab.py b/l10n_br_account_banking_payment_cnab/febraban/cnab.py
index 9faec66..2a384e4 100644
--- a/l10n_br_account_banking_payment_cnab/febraban/cnab.py
+++ b/l10n_br_account_banking_payment_cnab/febraban/cnab.py
@@ -22,6 +22,8 @@
##############################################################################
# TODO: implement abc factory?
+from __future__ import division, print_function, unicode_literals
+
class Cnab(object):
diff --git a/l10n_br_account_banking_payment_cnab/febraban/cnab_240/bancos/bb.py b/l10n_br_account_banking_payment_cnab/febraban/cnab_240/bancos/bb.py
new file mode 100644
index 0000000..5580359
--- /dev/null
+++ b/l10n_br_account_banking_payment_cnab/febraban/cnab_240/bancos/bb.py
@@ -0,0 +1,60 @@
+# coding: utf-8
+
+from __future__ import division, print_function, unicode_literals
+
+import re
+import string
+
+from ..cnab_240 import Cnab240
+
+
+class BB240(Cnab240):
+
+ def __init__(self):
+ super(Cnab240, self).__init__()
+ from cnab240.bancos import bancodobrasil
+ self.bank = bancodobrasil
+
+ def _prepare_header(self):
+ """
+ Preparar header do arquivo.
+ Adicionar informações no header do arquivo do Banco do Brasil
+ """
+ vals = super(BB240, self)._prepare_header()
+ # vals['servico_servico'] = 1
+ return vals
+
+ def _prepare_cobranca(self, line):
+ """
+ Preparar o evento (segmentoA e segmentoB) apartir da payment.line
+ :param line - payment.line
+ :return: dict - Informações
+ """
+ vals = super(BB240, self)._prepare_cobranca(line)
+ # vals['prazo_baixa'] = unicode(str(
+ # vals['prazo_baixa']), "utf-8")
+ # vals['desconto1_percentual'] = Decimal('0.00')
+ # vals['valor_iof'] = Decimal('0.00')
+ # # vals['cobrancasimples_valor_titulos'] = Decimal('02.00')
+ # vals['identificacao_titulo_banco'] = int(
+ # vals['identificacao_titulo_banco'])
+ # vals['cedente_conta_dv'] = unicode(str(
+ # vals['cedente_conta_dv']), "utf-8")
+ # vals['cedente_agencia_dv'] = unicode(str(
+ # vals['cedente_agencia_dv']), "utf-8")
+ # vals['cedente_dv_ag_cc'] = unicode(str(
+ # vals['cedente_dv_ag_cc']), "utf-8")
+ return vals
+
+ # Override cnab_240.nosso_numero. Diferentes números de dígitos entre
+ # CEF e Itau
+ def nosso_numero(self, format):
+ digito = format[-1:]
+ carteira = format[:3]
+ nosso_numero = re.sub(
+ '[%s]' % re.escape(string.punctuation), '', format[3:-1] or '')
+ return carteira, nosso_numero, digito
+
+ def str_to_unicode(inp_str):
+ inp_str = unicode(inp_str, "utf-8")
+ return inp_str
diff --git a/l10n_br_account_banking_payment_cnab/febraban/cnab_240/bancos/bradesco.py b/l10n_br_account_banking_payment_cnab/febraban/cnab_240/bancos/bradesco.py
index b6b4422..3dea8ad 100644
--- a/l10n_br_account_banking_payment_cnab/febraban/cnab_240/bancos/bradesco.py
+++ b/l10n_br_account_banking_payment_cnab/febraban/cnab_240/bancos/bradesco.py
@@ -47,13 +47,13 @@ def _prepare_header(self):
vals['servico_servico'] = 1
return vals
- def _prepare_segmento(self, line):
+ def _prepare_cobranca(self, line):
"""
:param line:
:return:
"""
- vals = super(Bradesco240, self)._prepare_segmento(line)
+ vals = super(Bradesco240, self)._prepare_cobranca(line)
vals['prazo_baixa'] = unicode(str(
vals['prazo_baixa']), "utf-8")
vals['desconto1_percentual'] = Decimal('0.00')
diff --git a/l10n_br_account_banking_payment_cnab/febraban/cnab_240/bancos/cef.py b/l10n_br_account_banking_payment_cnab/febraban/cnab_240/bancos/cef.py
index a6a7c05..14193fe 100644
--- a/l10n_br_account_banking_payment_cnab/febraban/cnab_240/bancos/cef.py
+++ b/l10n_br_account_banking_payment_cnab/febraban/cnab_240/bancos/cef.py
@@ -57,13 +57,13 @@ def _prepare_header(self):
return vals
- def _prepare_segmento(self, line):
+ def _prepare_cobranca(self, line):
"""
:param line:
:return:
"""
- vals = super(Cef240, self)._prepare_segmento(line)
+ vals = super(Cef240, self)._prepare_cobranca(line)
carteira, nosso_numero, digito = self.nosso_numero(
line.move_line_id.transaction_ref)
diff --git a/l10n_br_account_banking_payment_cnab/febraban/cnab_240/bancos/itau.py b/l10n_br_account_banking_payment_cnab/febraban/cnab_240/bancos/itau.py
index 1fefd02..84c5706 100644
--- a/l10n_br_account_banking_payment_cnab/febraban/cnab_240/bancos/itau.py
+++ b/l10n_br_account_banking_payment_cnab/febraban/cnab_240/bancos/itau.py
@@ -54,13 +54,13 @@ def _prepare_header(self):
vals['cedente_agencia_dv']),
return vals
- def _prepare_segmento(self, line):
+ def _prepare_cobranca(self, line):
"""
:param line:
:return:
"""
- vals = super(Itau240, self)._prepare_segmento(line)
+ vals = super(Itau240, self)._prepare_cobranca(line)
carteira, nosso_numero, digito = self.nosso_numero(
line.move_line_id.transaction_ref)
diff --git a/l10n_br_account_banking_payment_cnab/febraban/cnab_240/bancos/santander.py b/l10n_br_account_banking_payment_cnab/febraban/cnab_240/bancos/santander.py
index bd4bbca..cd8a3a5 100644
--- a/l10n_br_account_banking_payment_cnab/febraban/cnab_240/bancos/santander.py
+++ b/l10n_br_account_banking_payment_cnab/febraban/cnab_240/bancos/santander.py
@@ -49,11 +49,11 @@ def _prepare_header(self):
del vals['arquivo_hora_de_geracao']
return vals
- def _prepare_segmento(self, line):
+ def _prepare_cobranca(self, line):
"""
:param line:
:return:
"""
- vals = super(Santander240, self)._prepare_segmento(line)
+ vals = super(Santander240, self)._prepare_cobranca(line)
return vals
diff --git a/l10n_br_account_banking_payment_cnab/febraban/cnab_240/cnab_240.py b/l10n_br_account_banking_payment_cnab/febraban/cnab_240/cnab_240.py
index 0ccc091..b67d6b8 100644
--- a/l10n_br_account_banking_payment_cnab/febraban/cnab_240/cnab_240.py
+++ b/l10n_br_account_banking_payment_cnab/febraban/cnab_240/cnab_240.py
@@ -21,6 +21,8 @@
#
##############################################################################
+from __future__ import division, print_function, unicode_literals
+
import datetime
import logging
import re
@@ -35,14 +37,14 @@
_logger = logging.getLogger(__name__)
try:
- from cnab240.tipos import Arquivo
+ from cnab240.tipos import Arquivo, Lote
except ImportError as err:
_logger.debug = err
class Cnab240(Cnab):
"""
-
+ CNAB240
"""
def __init__(self):
@@ -50,6 +52,12 @@ def __init__(self):
@staticmethod
def get_bank(bank):
+ '''
+ Função chamada na criação do CNAB que dado o código do banco,
+ instancia o objeto do banco e retorna o obj ao CNAB que sera criado.
+ :param bank: str - Código do banco
+ :return:
+ '''
if bank == '341':
from .bancos.itau import Itau240
return Itau240
@@ -62,80 +70,180 @@ def get_bank(bank):
elif bank == '033':
from .bancos.santander import Santander240
return Santander240
+ elif bank == '001':
+ from .bancos.bb import BB240
+ return BB240
else:
return Cnab240
- @property
- def inscricao_tipo(self):
+ def get_inscricao_tipo(self, partner_id):
# TODO: Implementar codigo para PIS/PASEP
- if self.order.company_id.partner_id.is_company:
+ if partner_id.is_company:
return 2
else:
return 1
def _prepare_header(self):
"""
-
- :param:
- :return:
+ Preparar o header do arquivo do CNAB
+ :return: dict - Header do arquivo
"""
- return {
+ header_arquivo = {
+ # CONTROLE
+ # 01.0
'controle_banco': int(self.order.mode.bank_id.bank_bic),
+ # 02.0 # Sequencia para o Arquivo
+ 'controle_lote': 1,
+ # 03.0 0- Header do Arquivo
+ 'controle_registro': 0,
+ # 04.0
+ # CNAB - Uso Exclusivo FEBRABAN / CNAB
+
+ # EMPRESA
+ # 05.0 - 1 - CPF / 2 - CNPJ
+ 'cedente_inscricao_tipo':
+ self.get_inscricao_tipo(self.order.company_id.partner_id),
+ # 06.0
+ 'cedente_inscricao_numero':
+ int(punctuation_rm(self.order.company_id.cnpj_cpf)),
+ # 07.0
+ 'cedente_convenio': '0001222130126',
+ # 08.0
+ 'cedente_agencia':
+ int(self.order.mode.bank_id.bra_number),
+ # 09.0
+ 'cedente_agencia_dv': self.order.mode.bank_id.bra_number_dig,
+ # 10.0
+ 'cedente_conta': int(self.order.mode.bank_id.acc_number),
+ # 11.0
+ 'cedente_conta_dv': self.order.mode.bank_id.acc_number_dig[0],
+ # 12.0
+ 'cedente_agencia_conta_dv':
+ self.order.mode.bank_id.acc_number_dig[1]
+ if len(self.order.mode.bank_id.acc_number_dig) > 1 else '',
+ # 13.0
+ 'cedente_nome':
+ self.order.mode.bank_id.partner_id.legal_name[:30],
+ # 14.0
+ 'nome_banco': self.order.mode.bank_id.bank_name,
+ # 15.0
+ # CNAB - Uso Exclusivo FEBRABAN / CNAB
+
+ # ARQUIVO
+ # 16.0 Código Remessa = 1 / Retorno = 2
+ 'arquivo_codigo': '1',
+ # 17.0
'arquivo_data_de_geracao': self.data_hoje(),
+ # 18.0
'arquivo_hora_de_geracao': self.hora_agora(),
- # TODO: Número sequencial de arquivo
+ # 19.0 TODO: Número sequencial de arquivo
'arquivo_sequencia': int(self.get_file_numeration()),
- 'cedente_inscricao_tipo': self.inscricao_tipo,
- 'cedente_inscricao_numero': int(punctuation_rm(
- self.order.company_id.cnpj_cpf)),
- 'cedente_agencia': int(
- self.order.mode.bank_id.bra_number),
- 'cedente_conta': int(self.order.mode.bank_id.acc_number),
- 'cedente_conta_dv': (self.order.mode.bank_id.acc_number_dig),
- 'cedente_agencia_dv': self.order.mode.bank_id.bra_number_dig,
- 'cedente_nome': self.order.company_id.legal_name,
- # DV ag e conta
- 'cedente_dv_ag_cc': (self.order.mode.bank_id.bra_acc_dig),
- 'arquivo_codigo': 1, # Remessa/Retorno
- 'servico_operacao': u'R',
- 'nome_banco': unicode(self.order.mode.bank_id.bank_name),
+ # 20.0
+ 'arquivo_layout': 103,
+ # 21.0
+ 'arquivo_densidade': 0,
+ # 22.0
+ 'reservado_banco': '',
+ # 23.0
+ 'reservado_empresa': 'EMPRESA 100',
+ # 24.0
+ # CNAB - Uso Exclusivo FEBRABAN / CNAB
}
- def get_file_numeration(self):
- numero = self.order.get_next_number()
- if not numero:
- numero = 1
- return numero
+ return header_arquivo
- def format_date(self, srt_date):
- return int(datetime.datetime.strptime(
- srt_date, '%Y-%m-%d').strftime('%d%m%Y'))
-
- def nosso_numero(self, format):
- pass
+ def _prepare_header_lote(self):
+ """
+ Preparar o header de LOTE para arquivo do CNAB
+ :return: dict - Header do arquivo
+ """
+ empresa = self.order.mode.bank_id.partner_id
- def cep(self, format):
- sulfixo = format[-3:]
- prefixo = format[:5]
- return prefixo, sulfixo
+ header_arquivo_lote = {
- def sacado_inscricao_tipo(self, partner_id):
- # TODO: Implementar codigo para PIS/PASEP
- if partner_id.is_company:
- return 2
- else:
- return 1
+ # CONTROLE
+ # 01.1
+ 'controle_banco': int(self.order.mode.bank_id.bank_bic),
+ # 02.1 Sequencia para o Arquivo
+ 'controle_lote': 1,
+ # 03.1 0- Header do Arquivo
+ 'controle_registro': 1,
+
+ # SERVICO
+ # 04.1 # Header do lote sempre 'C'
+ 'servico_operacao': 'C',
+ # 05.1
+ 'servico_servico': self.order.tipo_servico,
+ # 06.1
+ 'servico_forma_lancamento': 1,
+ # 07.1
+ 'servico_layout': 20,
+ # 08.1
+ # CNAB - Uso Exclusivo da FEBRABAN/CNAB
+
+ # EMPRESA CEDENTE
+ # 09.1
+ 'empresa_inscricao_tipo': 2,
+ # self.get_inscricao_tipo(self.order.company_id.partner_id),
+ # 10.1
+ 'empresa_inscricao_numero': punctuation_rm(empresa.cnpj_cpf),
+ # 11.1
+ 'cedente_convenio': self.order.codigo_convenio,
+ # 12.1
+ 'cedente_agencia':
+ int(self.order.mode.bank_id.bra_number),
+ # 13.1
+ 'cedente_agencia_dv': self.order.mode.bank_id.bra_number_dig,
+ # 14.1
+ 'cedente_conta': int(self.order.mode.bank_id.acc_number),
+ # 15.1
+ 'cedente_conta_dv': self.order.mode.bank_id.acc_number_dig[0],
+ # 16.1
+ 'cedente_agencia_conta_dv':
+ self.order.mode.bank_id.acc_number_dig[1]
+ if len(self.order.mode.bank_id.acc_number_dig) > 1 else '',
+ # 17.1
+ 'cedente_nome':
+ self.order.mode.bank_id.partner_id.legal_name[:30],
+ # 18.1
+ 'mensagem1': '',
+
+ # ENDERECO
+ # 19.1
+ 'empresa_logradouro': empresa.street,
+ # 20.1
+ 'empresa_endereco_numero': empresa.number,
+ # 21.1
+ 'empresa_endereco_complemento': empresa.street2,
+ # 22.1
+ 'empresa_endereco_cidade': empresa.l10n_br_city_id.name,
+ # 23.1
+ 'empresa_endereco_cep': self.get_cep('prefixo', empresa.zip),
+ # 24.1
+ 'empresa_endereco_cep_complemento':
+ self.get_cep('sufixo', empresa.zip),
+ # 25.1
+ 'empresa_endereco_estado': empresa.state_id.code,
+
+ # 26.1
+ 'indicativo_forma_pagamento': '',
+ # 27.1
+ # CNAB - Uso Exclusivo FEBRABAN / CNAB
+ # 28.1
+ 'ocorrencias': '',
+ }
+ return header_arquivo_lote
- def rmchar(self, format):
- return re.sub('[%s]' % re.escape(string.punctuation), '',
- format or '')
+ def get_file_numeration(self):
+ # Função para retornar a numeração sequencial do arquivo
+ return 1
- def _prepare_segmento(self, line):
+ def _prepare_cobranca(self, line):
"""
:param line:
:return:
"""
- prefixo, sulfixo = self.cep(line.partner_id.zip)
+ # prefixo, sufixo = self.cep(line.partner_id.zip)
aceite = u'N'
if not self.order.mode.boleto_aceite == 'S':
@@ -162,8 +270,6 @@ def _prepare_segmento(self, line):
'cedente_conta': int(self.order.mode.bank_id.acc_number),
'cedente_conta_dv': self.order.mode.bank_id.acc_number_dig,
'cedente_agencia_dv': self.order.mode.bank_id.bra_number_dig,
- # DV ag e cc
- 'cedente_dv_ag_cc': (self.order.mode.bank_id.bra_acc_dig),
'identificacao_titulo': u'0000000', # TODO
'identificacao_titulo_banco': u'0000000', # TODO
'identificacao_titulo_empresa': line.move_line_id.move_id.name,
@@ -172,6 +278,7 @@ def _prepare_segmento(self, line):
line.ml_maturity_date),
'valor_titulo': Decimal(str(line.amount_currency)).quantize(
Decimal('1.00')),
+ # TODO: fépefwfwe
# TODO: Código adotado para identificar o título de cobrança.
# 8 é Nota de cŕedito comercial
'especie_titulo': int(self.order.mode.boleto_especie),
@@ -185,15 +292,15 @@ def _prepare_segmento(self, line):
'juros_mora_taxa_dia': Decimal('0.00'),
'valor_abatimento': Decimal('0.00'),
'sacado_inscricao_tipo': int(
- self.sacado_inscricao_tipo(line.partner_id)),
+ self.get_inscricao_tipo(line.partner_id)),
'sacado_inscricao_numero': int(
self.rmchar(line.partner_id.cnpj_cpf)),
'sacado_nome': line.partner_id.legal_name,
'sacado_endereco': (
line.partner_id.street + ' ' + line.partner_id.number),
'sacado_bairro': line.partner_id.district,
- 'sacado_cep': int(prefixo),
- 'sacado_cep_sufixo': int(sulfixo),
+ 'sacado_cep': self.get_cep('prefixo', line.partner_id.zip),
+ 'sacado_cep_sufixo': self.get_cep('sufixo', line.partner_id.zip),
'sacado_cidade': line.partner_id.l10n_br_city_id.name,
'sacado_uf': line.partner_id.state_id.code,
'codigo_protesto': int(self.order.mode.boleto_protesto),
@@ -204,31 +311,254 @@ def _prepare_segmento(self, line):
'cobranca_carteira': int(self.order.mode.boleto_carteira),
}
- def remessa(self, order):
+ def _prepare_pagamento(self, line):
+ """
+ Prepara um dict para preencher os valores do segmento A e B apartir de
+ uma linha da payment.order e insere informações que irão compor o
+ header do lote
+ :param line: payment.line - linha que sera base para evento
+ :return: dict - Dict contendo todas informações dos segmentos
"""
+ vals = {
- :param order:
- :return:
+ # SEGMENTO A
+ # CONTROLE
+ # 01.3A
+ 'controle_banco': int(self.order.mode.bank_id.bank_bic),
+ # 02.3A
+ 'controle_lote': 1,
+ # 03.3A - 3-Registros Iniciais do Lote
+ 'controle_registro': 3,
+
+ # SERVICO
+ # 04.3A - Nº Seqüencial do Registro - Inicia em 1 em cada novo lote
+ # TODO: Contador para o sequencial do lote
+ 'servico_numero_registro': 1,
+ # 05.3A
+ # Segmento Código de Segmento do Reg.Detalhe
+ # 06.3A
+ 'servico_tipo_movimento': self.order.tipo_movimento,
+ # 07.3A
+ 'servico_codigo_movimento': self.order.codigo_instrucao_movimento,
+
+ # FAVORECIDO
+ # 08.3A - 018-TED 700-DOC
+ 'favorecido_camara': 0,
+ # 09.3A
+ 'favorecido_banco': int(line.bank_id.bank_bic),
+ # 10.3A
+ 'favorecido_agencia': int(line.bank_id.bra_number),
+ # 11.3A
+ 'favorecido_agencia_dv': line.bank_id.bra_number_dig,
+ # 12.3A
+ 'favorecido_conta': punctuation_rm(line.bank_id.acc_number),
+ # 13.3A
+ 'favorecido_conta_dv': line.bank_id.acc_number_dig[0]
+ if line.bank_id.acc_number_dig else '',
+ # 14.3A
+ 'favorecido_dv': line.bank_id.acc_number_dig[1]
+ if len(line.bank_id.bra_number_dig or '') > 1 else '',
+ # 15.3A
+ 'favorecido_nome': line.partner_id.name,
+
+ # CREDITO
+ # 16.3A -
+ 'credito_seu_numero': line.name,
+ # 17.3A
+ 'credito_data_pagamento': self.format_date(line.date),
+ # 18.3A
+ 'credito_moeda_tipo': line.currency.name,
+ # 19.3A
+ 'credito_moeda_quantidade': Decimal('0.00000'),
+ # 20.3A
+ 'credito_valor_pagamento':
+ Decimal(str(line.amount_currency)).quantize(Decimal('1.00')),
+ # 21.3A
+ # 'credito_nosLoteso_numero': '',
+ # 22.3A
+ # 'credito_data_real': '',
+ # 23.3A
+ # 'credito_valor_real': '',
+
+ # INFORMAÇÔES
+ # 24.3A
+ # 'outras_informacoes': '',
+ # 25.3A
+ # 'codigo_finalidade_doc': line.codigo_finalidade_doc,
+ # 26.3A
+ 'codigo_finalidade_ted': line.codigo_finalidade_ted or '',
+ # 27.3A
+ 'codigo_finalidade_complementar':
+ line.codigo_finalidade_complementar or '',
+ # 28.3A
+ # CNAB - Uso Exclusivo FEBRABAN/CNAB
+ # 29.3A
+ # 'aviso_ao_favorecido': line.aviso_ao_favorecido,
+ 'aviso_ao_favorecido': 0,
+ # 'ocorrencias': '',
+
+ # SEGMENTO B
+ # Preenchido no segmento A
+ # 01.3B
+ # 02.3B
+ # 03.3B
+
+ # 04.3B
+ # 05.3B
+ # 06.3B
+
+ # DADOS COMPLEMENTARES - FAVORECIDOS
+ # 07.3B
+ 'favorecido_tipo_inscricao':
+ self.get_inscricao_tipo(line.partner_id),
+ # 08.3B
+ 'favorecido_num_inscricao':
+ int(punctuation_rm(line.partner_id.cnpj_cpf)),
+ # 09.3B
+ 'favorecido_endereco_rua': line.partner_id.street or '',
+ # 10.3B
+ 'favorecido_endereco_num': int(line.partner_id.number) or 0,
+ # 11.3B
+ 'favorecido_endereco_complemento': line.partner_id.street2 or '',
+ # 12.3B
+ 'favorecido_endereco_bairro': line.partner_id.district or '',
+ # 13.3B
+ 'favorecido_endereco_cidade':
+ line.partner_id.l10n_br_city_id.name or '',
+ # 14.3B
+ # 'favorecido_cep': int(line.partner_id.zip[:5]) or 0,
+ 'favorecido_cep': self.get_cep('prefixo', line.partner_id.zip),
+ # 15.3B
+ 'favorecido_cep_complemento':
+ self.get_cep('sufixo', line.partner_id.zip),
+ # 16.3B
+ 'favorecido_estado': line.partner_id.state_id.code or '',
+
+ # DADOS COMPLEMENTARES - PAGAMENTO
+ # 17.3B
+ 'pagamento_vencimento': 0,
+ # 18.3B
+ 'pagamento_valor_documento': Decimal('0.00'),
+ # 19.3B
+ 'pagamento_abatimento': Decimal('0.00'),
+ # 20.3B
+ 'pagamento_desconto': Decimal('0.00'),
+ # 21.3B
+ 'pagamento_mora': Decimal('0.00'),
+ # 22.3B
+ 'pagamento_multa': Decimal('0.00'),
+ # 23.3B
+ # TODO: Verificar se este campo é retornado no retorno
+ # 'cod_documento_favorecido': '',
+ # 24.3B - Informado No SegmentoA
+ # 'aviso_ao_favorecido': '0',
+ # 25.3B
+ # 'codigo_ug_centralizadora': '0',
+ # 26.3B
+ # 'codigo_ispb': '0',
+ }
+ return vals
+
+ def _adicionar_evento(self, line):
+ """
+ Adicionar o evento no arquivo de acordo com seu tipo
"""
- cobrancasimples_valor_titulos = 0
+ # if self.order.payment_order_type == 'payment':
+ # incluir = self.arquivo.incluir_debito_pagamento
+ # prepare = self._prepare_pagamento
+ # else:
+ # incluir = self.arquivo.incluir_cobranca
+ # prepare = self._prepare_cobranca
+ pass
+
+ def remessa(self, order):
+ """
+ Cria a remessa de eventos que sera anexada ao arquivo
+ :param order: payment.order
+ :return: Arquivo Cnab pronto para download
+ """
+ # cobrancasimples_valor_titulos = 0
self.order = order
+
+ # Preparar Header do Arquivo
self.arquivo = Arquivo(self.bank, **self._prepare_header())
- for line in order.line_ids:
- self.arquivo.incluir_cobranca(**self._prepare_segmento(line))
- self.arquivo.lotes[0].header.servico_servico = 1
+
+ if order.payment_order_type == 'payment':
+ incluir = self.arquivo.incluir_debito_pagamento
+ prepare = self._prepare_pagamento
+
+ header = self.bank.registros.HeaderLotePagamento(
+ **self._prepare_header_lote())
+
+ trailer = self.bank.registros.TrailerLotePagamento()
+ trailer.somatoria_valores = Decimal('0.00')
+ trailer.somatoria_quantidade_moedas = Decimal('0.00000')
+
+ lote_pagamento = Lote(self.bank, header, trailer)
+ self.arquivo.adicionar_lote(lote_pagamento)
+
+ else:
+ incluir = self.arquivo.incluir_cobranca
+ prepare = self._prepare_cobranca
+
+ for line in order.bank_line_ids:
+ # para cada linha da payment order adicoinar como um novo evento
+ # self._adicionar_evento(line)
+ # try:
+ incluir(tipo_lote=30, **prepare(line))
+ # except:
+ # from openerp import exceptions
+ # raise exceptions.ValidationError("Erro")
+ # self.arquivo.lotes[0].header.servico_servico = 30
# TODO: tratar soma de tipos de cobranca
- cobrancasimples_valor_titulos += line.amount_currency
- self.arquivo.lotes[0].trailer.cobrancasimples_valor_titulos = \
- Decimal(cobrancasimples_valor_titulos).quantize(
- Decimal('1.00'))
+ # cobrancasimples_valor_titulos += line.amount_currency
+ # self.arquivo.lotes[0].trailer.cobrancasimples_valor_titulos = \
+ # Decimal(cobrancasimples_valor_titulos).quantize(
+ # Decimal('1.00'))
remessa = unicode(self.arquivo)
- return unicodedata.normalize(
- 'NFKD', remessa).encode('ascii', 'ignore')
+ return unicodedata.normalize('NFKD', remessa).encode('ascii', 'ignore')
+
+ def get_cep(self, tipo, value):
+ '''
+ :param tipo:
+ :param value:
+ :return:
+ '''
+ if not value:
+ if tipo == 'prefixo':
+ return 0
+ else:
+ return ''
+ value = punctuation_rm(value)
+ sufixo = value[-3:]
+ prefixo = value[:5]
+ if tipo == 'sufixo':
+ return sufixo
+ else:
+ return prefixo
+
+ def format_date(self, srt_date):
+ if not srt_date:
+ return 0
+ return int(datetime.datetime.strptime(
+ srt_date, '%Y-%m-%d').strftime('%d%m%Y'))
def data_hoje(self):
return (int(time.strftime("%d%m%Y")))
def hora_agora(self):
return (int(time.strftime("%H%M%S")))
+
+ def rmchar(self, format):
+ return re.sub('[%s]' % re.escape(string.punctuation), '',
+ format or '')
+
+ def nosso_numero(self, format):
+ """
+ Hook para ser sobrescrito e adicionar informação
+ :param format:
+ :return:
+ """
+ pass
diff --git a/l10n_br_account_banking_payment_cnab/febraban/cnab_400/bancos/bradesco.py b/l10n_br_account_banking_payment_cnab/febraban/cnab_400/bancos/bradesco.py
index 6317ed9..fa3cf04 100644
--- a/l10n_br_account_banking_payment_cnab/febraban/cnab_400/bancos/bradesco.py
+++ b/l10n_br_account_banking_payment_cnab/febraban/cnab_400/bancos/bradesco.py
@@ -48,13 +48,13 @@ def _prepare_header(self):
vals['servico_servico'] = 1
return vals
- def _prepare_segmento(self, line):
+ def _prepare_cobranca(self, line):
"""
:param line:
:return:
"""
- vals = super(Bradesco400, self)._prepare_segmento(line)
+ vals = super(Bradesco400, self)._prepare_cobranca(line)
vals['prazo_baixa'] = unicode(str(
vals['prazo_baixa']), "utf-8")
vals['desconto1_percentual'] = Decimal('0.00')
diff --git a/l10n_br_account_banking_payment_cnab/febraban/cnab_400/cnab_400.py b/l10n_br_account_banking_payment_cnab/febraban/cnab_400/cnab_400.py
index 09c49c6..cb1e3d8 100644
--- a/l10n_br_account_banking_payment_cnab/febraban/cnab_400/cnab_400.py
+++ b/l10n_br_account_banking_payment_cnab/febraban/cnab_400/cnab_400.py
@@ -136,8 +136,6 @@ def _prepare_header(self):
'cedente_conta_dv': (self.order.mode.bank_id.acc_number_dig),
'cedente_agencia_dv': self.order.mode.bank_id.bra_number_dig,
'cedente_nome': self.order.company_id.legal_name,
- # DV ag e conta
- 'cedente_dv_ag_cc': (self.order.mode.bank_id.bra_acc_dig),
'arquivo_codigo': 1, # Remessa/Retorno
'servico_operacao': u'R',
'nome_banco': unicode(self.order.mode.bank_id.bank_name),
@@ -176,7 +174,7 @@ def rmchar(self, format):
def codificar(self, texto):
return texto.encode('utf-8')
- def _prepare_segmento(self, line):
+ def _prepare_cobranca(self, line):
"""
:param line:
:return:
@@ -236,8 +234,6 @@ def _prepare_segmento(self, line):
'cedente_conta': int(self.order.mode.bank_id.acc_number),
'cedente_conta_dv': self.order.mode.bank_id.acc_number_dig,
'cedente_agencia_dv': self.order.mode.bank_id.bra_number_dig,
- # DV ag e cc
- 'cedente_dv_ag_cc': (self.order.mode.bank_id.bra_acc_dig),
'identificacao_titulo': u'0000000', # TODO
'identificacao_titulo_banco': u'0000000', # TODO
'identificacao_titulo_empresa': line.move_line_id.move_id.name,
@@ -303,7 +299,7 @@ def remessa(self, order):
self.order = order
self.arquivo = ArquivoCobranca400(self.bank, **self._prepare_header())
for line in order.line_ids:
- self.arquivo.incluir_cobranca(**self._prepare_segmento(line))
+ self.arquivo.incluir_cobranca(**self._prepare_cobranca(line))
self.arquivo.trailer.num_seq_registro = self.controle_linha
remessa = unicode(self.arquivo)
diff --git a/l10n_br_account_banking_payment_cnab/febraban/pag_for/bancos/bradesco.py b/l10n_br_account_banking_payment_cnab/febraban/pag_for/bancos/bradesco.py
index 9b4cb40..1edd242 100644
--- a/l10n_br_account_banking_payment_cnab/febraban/pag_for/bancos/bradesco.py
+++ b/l10n_br_account_banking_payment_cnab/febraban/pag_for/bancos/bradesco.py
@@ -45,13 +45,13 @@ def _prepare_header(self):
vals['codigo_comunicacao'] = int(self.order.mode.boleto_convenio)
return vals
- def _prepare_segmento(self, line, vals):
+ def _prepare_cobranca(self, line, vals):
"""
:param line:
:return:
"""
- vals = super(BradescoPagFor, self)._prepare_segmento(line, vals)
+ vals = super(BradescoPagFor, self)._prepare_cobranca(line, vals)
# TODO campo para informar a data do pagamento.
vals['data_para_efetivacao_pag'] = self.muda_campos_data(
diff --git a/l10n_br_account_banking_payment_cnab/febraban/pag_for/pag_for500.py b/l10n_br_account_banking_payment_cnab/febraban/pag_for/pag_for500.py
index 472fca8..3666832 100644
--- a/l10n_br_account_banking_payment_cnab/febraban/pag_for/pag_for500.py
+++ b/l10n_br_account_banking_payment_cnab/febraban/pag_for/pag_for500.py
@@ -249,7 +249,7 @@ def sacado_inscricao_tipo(self, partner_id):
def rmchar(self, format):
return re.sub('[%s]' % re.escape(string.punctuation), '', format or '')
- def _prepare_segmento(self, line, vals):
+ def _prepare_cobranca(self, line, vals):
"""
:param line:
@@ -436,7 +436,7 @@ def lancamento_credito_bradesco(self, line):
'informacoes_complementares': u'',
}
- return self._prepare_segmento(line, vals)
+ return self._prepare_cobranca(line, vals)
def lancamento_ted(self, line):
# TODO:
@@ -488,14 +488,14 @@ def lancamento_ted(self, line):
}
- return self._prepare_segmento(line, vals)
+ return self._prepare_cobranca(line, vals)
def lancamento_doc(self):
# TODO:
vals = {}
- return self._prepare_segmento(vals)
+ return self._prepare_cobranca(vals)
def lancamento_titulos_terceiros(self, line):
# TODO:
@@ -520,7 +520,7 @@ def lancamento_titulos_terceiros(self, line):
}
- return self._prepare_segmento(vals)
+ return self._prepare_cobranca(vals)
def adiciona_digitos_num_pag(self, campo):
num_digitos = 16
diff --git a/l10n_br_account_banking_payment_cnab/model/__init__.py b/l10n_br_account_banking_payment_cnab/model/__init__.py
index 28ef5a5..c630028 100644
--- a/l10n_br_account_banking_payment_cnab/model/__init__.py
+++ b/l10n_br_account_banking_payment_cnab/model/__init__.py
@@ -7,3 +7,7 @@
from . import payment_mode
from . import res_partner_bank
from . import res_partner
+from .. import constantes
+from . import payment_line
+from . import bank_payment_line
+from . import l10n_br_cnab
diff --git a/l10n_br_account_banking_payment_cnab/model/bank_payment_line.py b/l10n_br_account_banking_payment_cnab/model/bank_payment_line.py
new file mode 100644
index 0000000..ddd64c9
--- /dev/null
+++ b/l10n_br_account_banking_payment_cnab/model/bank_payment_line.py
@@ -0,0 +1,100 @@
+# -*- coding: utf-8 -*-
+from openerp import models, fields, api
+from ..constantes import COMPLEMENTO_TIPO_SERVICO, CODIGO_FINALIDADE_TED, \
+ AVISO_FAVORECIDO
+
+STATE = [
+ ('draft', 'Draft'),
+ ('wait', 'Waiting Paiment'),
+ ('exception', 'Exception'),
+ ('paid', 'Paid'),
+]
+
+
+class BankPaymentLine(models.Model):
+ _inherit = 'bank.payment.line'
+
+ @api.model
+ def default_get(self, fields_list):
+ res = super(BankPaymentLine, self).default_get(fields_list)
+ mode = self.env['payment.order'].browse(
+ self.env.context.get('order_id')).mode
+ if mode.codigo_finalidade_doc:
+ res.update({
+ 'codigo_finalidade_doc': mode.codigo_finalidade_doc})
+ if mode.codigo_finalidade_ted:
+ res.update({
+ 'codigo_finalidade_ted': mode.codigo_finalidade_ted
+ })
+ if mode.codigo_finalidade_complementar:
+ res.update({
+ 'codigo_finalidade_complementar':
+ mode.codigo_finalidade_complementar
+ })
+ if mode.aviso_ao_favorecido:
+ res.update({
+ 'aviso_ao_favorecido': mode.aviso_ao_favorecido
+ })
+ return res
+
+ codigo_finalidade_doc = fields.Selection(
+ selection=COMPLEMENTO_TIPO_SERVICO,
+ string=u'Complemento do Tipo de Serviço',
+ help=u'Campo P005 do CNAB'
+ )
+ codigo_finalidade_ted = fields.Selection(
+ selection=CODIGO_FINALIDADE_TED,
+ string=u'Código Finalidade da TED',
+ help=u'Campo P011 do CNAB'
+ )
+ codigo_finalidade_complementar = fields.Char(
+ size=2,
+ string=u'Código de finalidade complementar',
+ help=u'Campo P013 do CNAB'
+ )
+ aviso_ao_favorecido = fields.Selection(
+ selection=AVISO_FAVORECIDO,
+ string=u'Aviso ao Favorecido',
+ help=u'Campo P006 do CNAB',
+ default='0',
+ )
+ abatimento = fields.Float(
+ digits=(13, 2),
+ string=u'Valor do Abatimento',
+ help=u'Campo G045 do CNAB',
+ default=0.00
+ )
+ desconto = fields.Float(
+ digits=(13, 2),
+ string=u'Valor do Desconto',
+ help=u'Campo G046 do CNAB',
+ default=0.00
+ )
+ mora = fields.Float(
+ digits=(13, 2),
+ string=u'Valor da Mora',
+ help=u'Campo G047 do CNAB',
+ default=0.00
+ )
+ multa = fields.Float(
+ digits=(13, 2),
+ string=u'Valor da Multa',
+ help=u'Campo G048 do CNAB',
+ default=0.00
+ )
+ state2 = fields.Selection(
+ string="State",
+ selection=STATE,
+ default="draft",
+ )
+ evento_id = fields.One2many(
+ string="Eventos CNAB",
+ comodel_name="l10n.br.cnab.evento",
+ inverse_name="bank_payment_line_id",
+ readonly=True
+ )
+ codigo_finalidade_complementar = fields.Char(
+ size=2,
+ string=u'Código de finalidade complementar',
+ help=u'Campo P013 do CNAB',
+ )
diff --git a/l10n_br_account_banking_payment_cnab/model/l10n_br_cnab.py b/l10n_br_account_banking_payment_cnab/model/l10n_br_cnab.py
new file mode 100644
index 0000000..d16929d
--- /dev/null
+++ b/l10n_br_account_banking_payment_cnab/model/l10n_br_cnab.py
@@ -0,0 +1,304 @@
+# -*- coding: utf-8 -*-
+# Copyright 2017 KMEE - Luiz Felipe do Divino Costa
+# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
+
+import base64
+import codecs
+import logging
+from datetime import datetime
+from ..constantes import CODIGO_OCORRENCIAS
+
+from openerp import api, models, fields, exceptions
+
+_logger = logging.getLogger(__name__)
+try:
+ from cnab240.bancos import bancodobrasil
+ from cnab240.tipos import Arquivo
+except ImportError as err:
+ _logger.debug = (err)
+
+STATE = [
+ ('draft', 'Novo'),
+ ('done', 'Processado'),
+]
+
+TIPO_OPERACAO = {
+ 'C': u'Lançamento a Crédito',
+ 'D': u'Lançamento a Débito',
+ 'E': u'Extrato para Conciliação',
+ 'G': u'Extrato para Gestão de Caixa',
+ 'I': u'Informações de Títulos Capturados do Próprio Banco',
+ 'R': u'Arquivo Remessa',
+ 'T': u'Arquivo Retorno',
+}
+
+TIPO_SERVICO = {
+ '01': 'Cobrança',
+ '03': 'Boleto de Pagamento Eletrônico',
+ '04': 'Conciliação Bancária',
+ '05': 'Débitos',
+ '06': 'Custódia de Cheques',
+ '07': 'Gestão de Caixa',
+ '08': 'Consulta/Informação Margem',
+ '09': 'Averbação da Consignação/Retenção',
+ '10': 'Pagamento Dividendos',
+ '11': 'Manutenção da Consignação',
+ '12': 'Consignação de Parcelas',
+ '13': 'Glosa da Consignação (INSS)',
+ '14': 'Consulta de Tributos a pagar',
+ '20': 'Pagamento Fornecedor',
+ '22': 'Pagamento de Contas, Tributos e Impostos',
+ '23': 'Interoperabilidade entre Contas de Instituições de Pagamentos',
+ '25': 'Compror',
+ '26': 'Compror Rotativo',
+ '29': 'Alegação do Pagador',
+ '30': 'Pagamento Salários',
+ '32': 'Pagamento de honorários',
+ '33': 'Pagamento de bolsa auxílio',
+ '34': 'Pagamento de prebenda (remuneração a padres e sacerdotes)',
+ '40': 'Vendor',
+ '41': 'Vendor a Termo',
+ '50': 'Pagamento Sinistros Segurados',
+ '60': 'Pagamento Despesas Viajante em Trânsito',
+ '70': 'Pagamento Autorizado',
+ '75': 'Pagamento Credenciados',
+ '77': 'Pagamento de Remuneração',
+ '80': 'Pagamento Representantes / Vendedores Autorizados',
+ '90': 'Pagamento Benefícios',
+ '98': 'Pagamentos Diversos',
+}
+
+TIPO_INSCRICAO_EMPRESA = {
+ 0: 'Isento / Não informado',
+ 1: 'CPF',
+ 2: 'CGC / CNPJ',
+ 3: 'PIS / PASEP',
+ 9: 'Outros',
+}
+
+
+class L10nBrHrCnab(models.Model):
+ _name = "l10n.br.cnab"
+ _rec_name = "display_name"
+
+ @api.multi
+ def processar_arquivo_retorno(self):
+ arquivo_retono = base64.b64decode(self.arquivo_retorno)
+ f = open('/tmp/cnab_retorno.ret', 'wb')
+ f.write(arquivo_retono)
+ f.close()
+ arquivo_retono = codecs.open('/tmp/cnab_retorno.ret', encoding='ascii')
+ arquivo_parser = Arquivo(bancodobrasil, arquivo=arquivo_retono)
+ if not arquivo_parser.header.arquivo_codigo == u'2':
+ raise exceptions.Warning(
+ u"Este não é um arquivo de retorno!"
+ )
+ data_arquivo = str(arquivo_parser.header.arquivo_data_de_geracao)
+ self.data_arquivo = fields.Date.from_string(
+ data_arquivo[4:] + "-" + data_arquivo[2:4] + "-" +
+ data_arquivo[0:2]
+ )
+ self.bank_account_id = self.env['res.partner.bank'].search(
+ [('acc_number', '=', arquivo_parser.header.cedente_conta)]).id
+ self.num_lotes = arquivo_parser.trailer.totais_quantidade_lotes
+ self.num_eventos = arquivo_parser.trailer.totais_quantidade_registros
+ for lote in arquivo_parser.lotes:
+ account_bank_id_lote = self.env['res.partner.bank'].search(
+ [('acc_number', '=', lote.header.cedente_conta)]
+ ).id
+ vals = {
+ 'account_bank_id': account_bank_id_lote,
+ 'empresa_inscricao_numero':
+ str(lote.header.empresa_inscricao_numero),
+ 'empresa_inscricao_tipo':
+ TIPO_INSCRICAO_EMPRESA[lote.header.empresa_inscricao_tipo],
+ 'servico_operacao':
+ TIPO_OPERACAO[lote.header.servico_operacao],
+ 'tipo_servico': TIPO_SERVICO[str(lote.header.servico_servico)],
+ 'mensagem': lote.header.mensagem1,
+ 'qtd_registros': lote.trailer.quantidade_registros,
+ 'total_valores': float(lote.trailer.somatoria_valores),
+ 'cnab_id': self.id,
+ }
+ lote_id = self.env['l10n.br.cnab.lote'].create(vals)
+ for evento in lote.eventos:
+ data_evento = str(
+ evento.credito_data_real)
+ data_evento = fields.Date.from_string(
+ data_evento[4:] + "-" + data_evento[2:4] + "-" +
+ data_evento[0:2]
+ )
+ account_bank_id_lote = self.env['res.partner.bank'].search(
+ [
+ ('bra_number', '=', evento.favorecido_agencia),
+ ('bra_number_dig', '=', evento.favorecido_agencia_dv),
+ ('acc_number', '=', evento.favorecido_conta),
+ ('acc_number_dig', '=', evento.favorecido_conta_dv)
+ ])
+ account_bank_id_lote = account_bank_id_lote.ids[0] \
+ if account_bank_id_lote else False
+ favorecido_partner = self.env['res.partner.bank'].search(
+ [('owner_name', 'ilike', evento.favorecido_nome)]
+ )
+ favorecido_partner = favorecido_partner[0].partner_id.id \
+ if favorecido_partner else False
+ bank_payment_line_id = self.env['bank.payment.line'].search(
+ [
+ ('name', '=', evento.credito_seu_numero)
+ ]
+ )
+ ocorrencias_dic = dict(CODIGO_OCORRENCIAS)
+ ocorrencias = [
+ evento.ocorrencias[0:2],
+ evento.ocorrencias[2:4],
+ evento.ocorrencias[4:6],
+ evento.ocorrencias[6:8],
+ evento.ocorrencias[8:10]
+ ]
+ vals_evento = {
+ 'data_real_pagamento': data_evento,
+ 'segmento': evento.servico_segmento,
+ 'favorecido_nome': favorecido_partner,
+ 'favorecido_conta_bancaria': account_bank_id_lote,
+ 'nosso_numero': str(evento.credito_nosso_numero),
+ 'seu_numero': evento.credito_seu_numero,
+ 'tipo_moeda': evento.credito_moeda_tipo,
+ 'valor_pagamento': evento.credito_valor_pagamento,
+ 'ocorrencias': evento.ocorrencias,
+ 'str_motiv_a': ocorrencias_dic[ocorrencias[0]] if
+ ocorrencias[0] else '',
+ 'str_motiv_b': ocorrencias_dic[ocorrencias[1]] if
+ ocorrencias[1] else '',
+ 'str_motiv_c': ocorrencias_dic[ocorrencias[2]] if
+ ocorrencias[2] else '',
+ 'str_motiv_d': ocorrencias_dic[ocorrencias[3]] if
+ ocorrencias[3] else '',
+ 'str_motiv_e': ocorrencias_dic[ocorrencias[4]] if
+ ocorrencias[4] else '',
+ 'lote_id': lote_id.id,
+ 'bank_payment_line_id': bank_payment_line_id.id,
+ }
+ self.env['l10n.br.cnab.evento'].create(vals_evento)
+ if evento.ocorrencias and bank_payment_line_id:
+ if '00' in ocorrencias:
+ bank_payment_line_id.write({'state2': 'paid'})
+ else:
+ bank_payment_line_id.write({'state2': 'exception'})
+
+ return self.write({'state': 'done'})
+
+ @api.multi
+ def _get_name(self, data):
+ cnab_ids = self.search([('data', '=', data)])
+ return data + " - " + (
+ str(len(cnab_ids) + 1) if cnab_ids else '1'
+ )
+
+ @api.model
+ def create(self, vals):
+ name = self._get_name(vals['data'])
+ vals.update({'name': name})
+ return super(L10nBrHrCnab, self).create(vals)
+
+ arquivo_retorno = fields.Binary(string='Arquivo Retorno')
+ data = fields.Date(
+ string="Data CNAB",
+ required=True,
+ default=datetime.now()
+ )
+ name = fields.Char(
+ string="Name",
+ )
+ lote_id = fields.One2many(
+ string="Lotes",
+ comodel_name="l10n.br.cnab.lote",
+ inverse_name="cnab_id"
+ )
+ state = fields.Selection(
+ string=u"Estágio",
+ selection=STATE,
+ default="draft",
+ )
+ data_arquivo = fields.Datetime(
+ string="Data Criação no Banco",
+ )
+ bank_account_id = fields.Many2one(
+ string="Conta cedente",
+ comodel_name="res.partner.bank",
+ )
+ num_lotes = fields.Integer(
+ string=u"Número de Lotes",
+ )
+ num_eventos = fields.Integer(
+ string=u"Número de Eventos",
+ )
+
+
+class L10nBrHrCnabLote(models.Model):
+ _name = "l10n.br.cnab.lote"
+
+ account_bank_id = fields.Many2one(
+ string=u"Conta Bancária",
+ comodel_name="res.partner.bank",
+ )
+ empresa_inscricao_numero = fields.Char(string=u"Número de Inscrição")
+ empresa_inscricao_tipo = fields.Char(string=u"Tipo de Inscrição")
+ servico_operacao = fields.Char(string=u"Tipo de Operação")
+ tipo_servico = fields.Char(strin=u"Tipo do Serviço")
+ mensagem = fields.Char(string="Mensagem")
+ qtd_registros = fields.Integer(string="Quantidade de Registros")
+ total_valores = fields.Float(string="Valor Total")
+ evento_id = fields.One2many(
+ string="Eventos",
+ comodel_name="l10n.br.cnab.evento",
+ inverse_name="lote_id",
+ )
+ cnab_id = fields.Many2one(
+ string="CNAB",
+ comodel_name="l10n.br.cnab"
+ )
+ state = fields.Selection(
+ string="State",
+ related="cnab_id.state",
+ selection=STATE,
+ default="draft",
+ )
+
+
+class L10nBrHrCnabEvento(models.Model):
+ _name = "l10n.br.cnab.evento"
+
+ data_real_pagamento = fields.Datetime(string="Data Real do Pagamento")
+ segmento = fields.Char(string="Segmento")
+ favorecido_nome = fields.Many2one(
+ string="Favorecido",
+ comodel_name="res.partner"
+ )
+ favorecido_conta_bancaria = fields.Many2one(
+ string=u"Conta Bancária",
+ comodel_name="res.partner.bank",
+ )
+ nosso_numero = fields.Char(string=u"Nosso Número")
+ seu_numero = fields.Char(string=u"Seu Número")
+ tipo_moeda = fields.Char(string=u"Tipo de Moeda")
+ valor_pagamento = fields.Float(string="Valor do Pagamento")
+ ocorrencias = fields.Char(string=u"Ocorrências")
+ str_motiv_a = fields.Char(u'Motivo da ocorrência 01')
+ str_motiv_b = fields.Char(u'Motivo de ocorrência 02')
+ str_motiv_c = fields.Char(u'Motivo de ocorrência 03')
+ str_motiv_d = fields.Char(u'Motivo de ocorrência 04')
+ str_motiv_e = fields.Char(u'Motivo de ocorrência 05')
+ bank_payment_line_id = fields.Many2one(
+ string="Bank Payment Line",
+ comodel_name="bank.payment.line",
+ )
+ lote_id = fields.Many2one(
+ string="Lote",
+ comodel_name="l10n.br.cnab.lote",
+ )
+ state = fields.Selection(
+ string="State",
+ related="lote_id.state",
+ selection=STATE,
+ default="draft",
+ )
diff --git a/l10n_br_account_banking_payment_cnab/model/payment_line.py b/l10n_br_account_banking_payment_cnab/model/payment_line.py
new file mode 100644
index 0000000..0c66474
--- /dev/null
+++ b/l10n_br_account_banking_payment_cnab/model/payment_line.py
@@ -0,0 +1,94 @@
+# -*- coding: utf-8 -*-
+from openerp import models, fields, api
+from ..constantes import COMPLEMENTO_TIPO_SERVICO, CODIGO_FINALIDADE_TED, \
+ AVISO_FAVORECIDO
+
+STATE = [
+ ('draft', 'Draft'),
+ ('wait', 'Waiting Paiment'),
+ ('exception', 'Exception'),
+ ('paid', 'Paid'),
+]
+
+
+class PaymentLine(models.Model):
+ _inherit = 'payment.line'
+
+ @api.model
+ def default_get(self, fields_list):
+ res = super(PaymentLine, self).default_get(fields_list)
+ mode = self.env['payment.order'].browse(
+ self.env.context.get('order_id')).mode
+ if mode.codigo_finalidade_doc:
+ res.update({
+ 'codigo_finalidade_doc': mode.codigo_finalidade_doc})
+ if mode.codigo_finalidade_ted:
+ res.update({
+ 'codigo_finalidade_ted': mode.codigo_finalidade_ted
+ })
+ if mode.codigo_finalidade_complementar:
+ res.update({
+ 'codigo_finalidade_complementar':
+ mode.codigo_finalidade_complementar
+ })
+ if mode.aviso_ao_favorecido:
+ res.update({
+ 'aviso_ao_favorecido': mode.aviso_ao_favorecido
+ })
+ return res
+
+ seu_numero = fields.Char(
+ string=u'Seu Número',
+ size=20,
+ help=u'Campo G064'
+ )
+ codigo_finalidade_doc = fields.Selection(
+ selection=COMPLEMENTO_TIPO_SERVICO,
+ string=u'Complemento do Tipo de Serviço',
+ help=u'Campo P005 do CNAB',
+ )
+ codigo_finalidade_ted = fields.Selection(
+ selection=CODIGO_FINALIDADE_TED,
+ string=u'Código Finalidade da TED',
+ help=u'Campo P011 do CNAB',
+ )
+ codigo_finalidade_complementar = fields.Char(
+ size=2,
+ string=u'Código de finalidade complementar',
+ help=u'Campo P013 do CNAB',
+ )
+ aviso_ao_favorecido = fields.Selection(
+ selection=AVISO_FAVORECIDO,
+ string=u'Aviso ao Favorecido',
+ help=u'Campo P006 do CNAB',
+ default='0',
+ )
+ abatimento = fields.Float(
+ digits=(13, 2),
+ string=u'Valor do Abatimento',
+ help=u'Campo G045 do CNAB',
+ default=0.00
+ )
+ desconto = fields.Float(
+ digits=(13, 2),
+ string=u'Valor do Desconto',
+ help=u'Campo G046 do CNAB',
+ default=0.00
+ )
+ mora = fields.Float(
+ digits=(13, 2),
+ string=u'Valor da Mora',
+ help=u'Campo G047 do CNAB',
+ default=0.00
+ )
+ multa = fields.Float(
+ digits=(13, 2),
+ string=u'Valor da Multa',
+ help=u'Campo G048 do CNAB',
+ default=0.00
+ )
+ state2 = fields.Selection(
+ related="bank_line_id.state2",
+ selection=STATE,
+ default="draft",
+ )
diff --git a/l10n_br_account_banking_payment_cnab/model/payment_mode.py b/l10n_br_account_banking_payment_cnab/model/payment_mode.py
index b6eec56..18de555 100644
--- a/l10n_br_account_banking_payment_cnab/model/payment_mode.py
+++ b/l10n_br_account_banking_payment_cnab/model/payment_mode.py
@@ -22,6 +22,8 @@
from openerp import models, fields
from openerp.addons import decimal_precision as dp
+from ..constantes import TIPO_SERVICO, FORMA_LANCAMENTO, \
+ COMPLEMENTO_TIPO_SERVICO, CODIGO_FINALIDADE_TED, AVISO_FAVORECIDO
class PaymentMode(models.Model):
@@ -34,5 +36,42 @@ class PaymentMode(models.Model):
cnab_percent_interest = fields.Float(string=u"Percentual de Juros",
digits=dp.get_precision('Account'))
comunicacao_2 = fields.Char("Comunicação para o sacador avalista")
+ tipo_servico = fields.Selection(
+ selection=TIPO_SERVICO,
+ string=u'Tipo de Serviço',
+ help=u'Campo G025 do CNAB'
+ )
+ forma_lancamento = fields.Selection(
+ selection=FORMA_LANCAMENTO,
+ string=u'Forma Lançamento',
+ help=u'Campo G029 do CNAB'
+ )
+ codigo_convenio = fields.Char(
+ size=20,
+ string=u'Código do Convênio no Banco',
+ help=u'Campo G007 do CNAB',
+ default=u'0001222130126',
+ )
+ codigo_finalidade_doc = fields.Selection(
+ selection=COMPLEMENTO_TIPO_SERVICO,
+ string=u'Complemento do Tipo de Serviço',
+ help=u'Campo P005 do CNAB'
+ )
+ codigo_finalidade_ted = fields.Selection(
+ selection=CODIGO_FINALIDADE_TED,
+ string=u'Código Finalidade da TED',
+ help=u'Campo P011 do CNAB'
+ )
+ codigo_finalidade_complementar = fields.Char(
+ size=2,
+ string=u'Código de finalidade complementar',
+ help=u'Campo P013 do CNAB',
+ )
+ aviso_ao_favorecido = fields.Selection(
+ selection=AVISO_FAVORECIDO,
+ string=u'Aviso ao Favorecido',
+ help=u'Campo P006 do CNAB',
+ default=0,
+ )
# A exportação CNAB não se encaixa somente nos parâmetros de
# débito e crédito.
diff --git a/l10n_br_account_banking_payment_cnab/model/payment_order.py b/l10n_br_account_banking_payment_cnab/model/payment_order.py
index d1c7d01..6a191ea 100644
--- a/l10n_br_account_banking_payment_cnab/model/payment_order.py
+++ b/l10n_br_account_banking_payment_cnab/model/payment_order.py
@@ -1,65 +1,65 @@
# -*- coding: utf-8 -*-
-# #############################################################################
-#
-#
-# Copyright (C) 2012 KMEE (http://www.kmee.com.br)
-# @author Fernando Marcato Rodrigues
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as
-# published by the Free Software Foundation, either version 3 of the
-# License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with this program. If not, see .
-#
-##############################################################################
+# Copyright 2012 KMEE - Fernando Marcato Rodrigues
+# Copyright 2017 KMEE - Hendrix Costa
+# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
-from openerp import api, models, fields
+from __future__ import division, print_function, unicode_literals
-# TODO: funcao a ser chamada por ação automatizada para resetar o sufixo
-# diariamente
+from openerp import models, fields
+
+from ..constantes import TIPO_SERVICO, FORMA_LANCAMENTO, \
+ INDICATIVO_FORMA_PAGAMENTO, TIPO_MOVIMENTO, CODIGO_INSTRUCAO_MOVIMENTO
class PaymentOrder(models.Model):
- _inherit = 'payment.order'
+ _inherit = b'payment.order'
+
+ file_number = fields.Integer(
+ string=u'Número sequencial do arquivo',
+ )
- file_number = fields.Integer(u'Número sequencial do arquivo')
- # TODO adicionar domain para permitir o modo de pagamento correspondente
- # ao mode
- serie_id = fields.Many2one(
- 'l10n_br_cnab.sequence', u'Sequencia interna')
- sufixo_arquivo = fields.Integer(u'Sufixo do arquivo')
- serie_sufixo_arquivo = fields.Many2one(
- 'l10n_br_cnab_file_sufix.sequence', u'Série do Sufixo do arquivo')
+ cnab_file = fields.Binary(
+ string='CNAB File',
+ readonly=True,
+ )
- @api.multi
- def get_next_number(self):
- for ord in self:
- sequence = self.env['ir.sequence']
- # sequence_read = sequence.read(
- # cr, uid, ord.serie_id.internal_sequence_id.id,
- # ['number_next'])
- seq_no = sequence.get_id(ord.serie_id.internal_sequence_id.id)
- ord.write({'file_number': seq_no})
- return seq_no
+ cnab_filename = fields.Char("CNAB Filename")
- @api.multi
- def get_next_sufixo(self):
- for ord in self:
- sequence = self.env['ir.sequence']
- # sequence_read = sequence.read(
- # cr, uid, ord.serie_id.internal_sequence_id.id,
- # ['number_next'])
- seq_no = sequence.get_id(
- ord.serie_sufixo_arquivo.internal_sequence_id.id)
- ord.write({'sufixo_arquivo': seq_no})
- return seq_no
+ tipo_servico = fields.Selection(
+ selection=TIPO_SERVICO,
+ string=u'Tipo de Serviço',
+ help=u'Campo G025 do CNAB',
+ default='30',
+ )
+ forma_lancamento = fields.Selection(
+ selection=FORMA_LANCAMENTO,
+ string=u'Forma Lançamento',
+ help=u'Campo G029 do CNAB'
+ )
+ codigo_convenio = fields.Char(
+ size=20,
+ string=u'Código do Convênio no Banco',
+ help=u'Campo G007 do CNAB',
+ default=u'0001222130126',
+ )
+ indicativo_forma_pagamento = fields.Selection(
+ selection=INDICATIVO_FORMA_PAGAMENTO,
+ string=u'Indicativo de Forma de Pagamento',
+ help='Campo P014 do CNAB',
+ default='01'
+ )
+ tipo_movimento = fields.Selection(
+ selection=TIPO_MOVIMENTO,
+ string='Tipo de Movimento',
+ help='Campo G060 do CNAB',
+ default='0',
+ )
+ codigo_instrucao_movimento = fields.Selection(
+ selection=CODIGO_INSTRUCAO_MOVIMENTO,
+ string='Código da Instrução para Movimento',
+ help='Campo G061 do CNAB',
+ default='0',
+ )
# @api.multi
# def set_to_draft(self, *args):
diff --git a/l10n_br_account_banking_payment_cnab/model/res_partner_bank.py b/l10n_br_account_banking_payment_cnab/model/res_partner_bank.py
index e21c9ce..0892a46 100644
--- a/l10n_br_account_banking_payment_cnab/model/res_partner_bank.py
+++ b/l10n_br_account_banking_payment_cnab/model/res_partner_bank.py
@@ -1,24 +1,7 @@
# -*- coding: utf-8 -*-
-# #############################################################################
-#
-#
-# Copyright (C) 2012 KMEE (http://www.kmee.com.br)
-# @author Fernando Marcato Rodrigues
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as
-# published by the Free Software Foundation, either version 3 of the
-# License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with this program. If not, see .
-#
-##############################################################################
+# Copyright 2012 KMEE - Fernando Marcato Rodrigues
+# Copyright 2017 KMEE - Hendrix Costa
+# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from openerp import models, fields
@@ -28,18 +11,27 @@ class ResPartnerBank(models.Model):
bancárias no Brasil."""
_inherit = 'res.partner.bank'
- bra_acc_dig = fields.Char(u'Digito Verificador Agência/Conta', size=1)
codigo_da_empresa = fields.Integer(
- u'Código da empresa', size=20,
+ u'Código da empresa',
+ size=20,
help=u"Será informado pelo banco depois do cadastro do beneficiário "
- u"na agência")
+ u"na agência"
+ )
+
tipo_de_conta = fields.Selection(
- [('01', u'Conta corrente individual'),
- ('02', u'Conta poupança individual'),
- ('03', u'Conta depósito judicial/Depósito em consignação individual'),
- ('11', u'Conta corrente conjunta'),
- ('12', u'Conta poupança conjunta'),
- ('13', u'Conta depósito judicial/Depósito em consignação conjunta')
- ],
- u'Tipo de Conta', default='01'
+ selection=[
+ ('01', u'Conta corrente individual'),
+ ('02', u'Conta poupança individual'),
+ ('03', u'Conta depósito judicial/Depósito em consignação '
+ u'individual'),
+ ('11', u'Conta corrente conjunta'),
+ ('12', u'Conta poupança conjunta'),
+ ('13', u'Conta depósito judicial/Depósito em consignação '
+ u'conjunta')],
+ string=u'Tipo de Conta',
+ default='01'
+ )
+
+ bra_number = fields.Char(
+ size=5,
)
diff --git a/l10n_br_account_banking_payment_cnab/security/cnab_cobranca_security.xml b/l10n_br_account_banking_payment_cnab/security/cnab_cobranca_security.xml
new file mode 100644
index 0000000..42a6a0c
--- /dev/null
+++ b/l10n_br_account_banking_payment_cnab/security/cnab_cobranca_security.xml
@@ -0,0 +1,11 @@
+
+
+
+
+
+ CNAB Cobranca
+
+
+
+
+
\ No newline at end of file
diff --git a/l10n_br_account_banking_payment_cnab/security/ir.model.access.csv b/l10n_br_account_banking_payment_cnab/security/ir.model.access.csv
new file mode 100644
index 0000000..8ed4b5e
--- /dev/null
+++ b/l10n_br_account_banking_payment_cnab/security/ir.model.access.csv
@@ -0,0 +1,6 @@
+"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
+access_l10n_br_cnab,access_l10n_br_cnab,model_l10n_br_cnab,,1,0,0,0
+access_l10n_br_cnab_lote,access_l10n_br_cnab_lote,model_l10n_br_cnab_lote,,1,0
+access_l10n_br_cnab_evento,access_l10n_br_cnab_evento,model_l10n_br_cnab_evento,,1,0,0,0
+access_l10n_br_cnab_sequence,access_l10n_br_cnab_sequence,model_l10n_br_cnab_sequence,,1,0,0,0
+access_l10n_br_cnab_file_sufix_sequence,access_l10n_br_cnab_file_sufix_sequence,model_l10n_br_cnab_file_sufix_sequence,,1,0,0,0
diff --git a/l10n_br_account_banking_payment_cnab/tests/invoice_create.yml b/l10n_br_account_banking_payment_cnab/tests/invoice_create.yml
deleted file mode 100644
index aeffa3d..0000000
--- a/l10n_br_account_banking_payment_cnab/tests/invoice_create.yml
+++ /dev/null
@@ -1,207 +0,0 @@
--
- Create a sale customer invoice from SP to SP fiscal contributor
--
- !record {model: account.invoice, id: account_invoice_customer_sp_sp_banking, view: l10n_br_account_product.l10n_br_account_product_invoice_form}:
- partner_id: l10n_br_base.res_partner_cliente1_sp
- fiscal_category_id: l10n_br_account_product.fc_78df616ab31e95ee46c6a519a2ce9e12
- reference_type: none
- payment_mode_id: l10n_br_account_banking_payment_cnab.payment_mode_cobranca_bradesco240
- name: 'NFe Invoice Test'
- date_due: 2017-03-05
- invoice_line:
- - product_id: product.product_product_18
- fiscal_category_id: l10n_br_account_product.fc_78df616ab31e95ee46c6a519a2ce9e12
- quantity: 1.0
- price_unit: 1000.00
--
- I check if found fisal position and CFOP, document type and document serie
--
- !assert {model: account.invoice, id: account_invoice_customer_sp_sp_banking}:
- - fiscal_position != False
- - fiscal_document_id.id == company_id.product_invoice_id.id
- - document_serie_id.fiscal_document_id.id == fiscal_document_id.id
- - invoice_line[0].fiscal_position.id == ref('l10n_br_account_product.fp_78df616ab31e95ee46c6a519a2ce9e12_internal_demo')
- - invoice_line[0].cfop_id.code == '5101'
-
--
- I check that Initially customer invoice is in the "Draft" state
--
- !assert {model: account.invoice, id: account_invoice_customer_sp_sp_banking}:
- - state == 'draft'
--
- I create invoice by clicking on Create button
--
- !workflow {model: account.invoice, action: invoice_validate, ref: account_invoice_customer_sp_sp_banking}
--
- I check that the invoice state is "sefaz_export"
--
- !assert {model: account.invoice, id: account_invoice_customer_sp_sp_banking}:
- - state == 'sefaz_export'
--
- I set the state of invoice to "open" state
--
- !workflow {model: account.invoice, action: invoice_open, ref: account_invoice_customer_sp_sp_banking}
--
- I check that the invoice state is "open"
--
- !assert {model: account.invoice, id: account_invoice_customer_sp_sp_banking}:
- - state == 'open'
--
- I check if the invoice has a related move that is receivable
--
- !assert {model: account.invoice, id: account_invoice_customer_sp_sp_banking}:
- - move_id.line_id[0].date_maturity != False
- - move_id.line_id[0].account_id.type == 'receivable'
--
- I update the main company bank bradesco account digit
--
- !record {model: res.partner.bank, id: l10n_br_account_payment_mode.main_company_bank_bradesco}:
- bra_acc_dig: '0'
--
- I create the payment mode for pagamento
--
- !record {model: payment.mode, id: payment_mode_pagamento}:
- name: u'Pagamento'
- bank_id: l10n_br_account_payment_mode.main_company_bank_bradesco
- active: True
- payment_order_type: 'payment'
- sale_ok: True
- journal: account.bank_journal
- company_id: base.main_company
- type: account_banking_payment_export.manual_bank_tranfer
- purchase_ok: False,
- type_sale_payment: '99'
--
- I create the cnab internal sequence
--
- !record {model: ir.sequence, id: cnab_internal_sequence}:
- name: u'Sequência interna de cobrança'
- number_next: 1
- number_next_actual: 1
--
- I create the cnab sufix internal sequence
--
- !record {model: ir.sequence, id: cnab_sufix_internal_sequence}:
- name: u'Sequência interna do sufixo da cobrança'
- number_next: 1
- number_next_actual: 1
--
- I create the cnab sequence
--
- !record {model: l10n_br_cnab.sequence, id: cnab_sequence}:
- code: 'Cob'
- name: u'Sequência da Cobrança'
- internal_sequence_id: cnab_internal_sequence
- parent_payment_mode: payment_mode_pagamento
--
- I create the cnab sufix sequence
--
- !record {model: l10n_br_cnab_file_sufix.sequence, id: cnab_sufix_sequence}:
- code: 'CobSuf'
- name: u'Sequência do sufixo da Cobrança'
- internal_sequence_id: cnab_sufix_internal_sequence
- parent_payment_mode_suf: payment_mode_pagamento
--
- I create the cobrança (payment.order)
--
- !record {model: payment.order, id: cobranca}:
- user_id: 1
- mode: l10n_br_account_banking_payment_cnab.payment_mode_cobranca_bradesco240
- date_prefered: 'due'
- serie_id: cnab_sequence
- serie_sufixo_arquivo: cnab_sufix_sequence
--
- I confirm the cobrança (payment order)
--
- !workflow {model: payment.order, action: open, ref: cobranca}
--
- I check that cobranca(payment order) is now "Confirmed".
--
- !assert {model: payment.order, id: cobranca, severity: error, string: Payment Order should be 'Confirmed'.}:
- - state == 'open'
--
- !record {model: payment.order.create, id: wizard_cobranca}:
- duedate: 2017-03-05
--
- I search for the invoice entries to make the payment.
--
- !python {model: payment.order.create}: |
- self.search_entries(cr, uid, [ref("wizard_cobranca")], {
- "active_model": "payment.order", "active_ids": [ref("cobranca")],
- "active_id": ref("cobranca"), })
--
- I create payment lines entries.
--
- !python {model: payment.order.create}: |
- invoice = self.pool.get('account.invoice').browse(cr, uid, ref("account_invoice_customer_sp_sp_banking"))
- move_line = invoice.move_id.line_id[0]
- self.write(cr, uid, [ref("wizard_cobranca")], {'entries': [(6,0,[move_line.id])]})
- self.create_payment(cr, uid, [ref("wizard_cobranca")], {
- "active_model": "payment.order", "active_ids": [ref("cobranca")],
- "active_id": ref("cobranca")})
--
- I check that payment line is created with proper data.
--
- !python {model: payment.order}: |
- invoice = self.pool.get('account.invoice').browse(cr, uid, ref("account_invoice_customer_sp_sp_banking"))
- payment = self.browse(cr, uid, ref("cobranca"))
- payment_line = payment.line_ids[0]
- # rename the payment line because we can't test if the generated file get dinamic information (payment line get the by ir.sequence)
- payment_line.name = '001'
- payment_line.move_line_id.move_id.name = 1
-
- assert payment_line.move_line_id, "move line is not created in payment line."
- assert invoice.move_id.name == payment_line.ml_inv_ref.number, "invoice reference number is not same created."
- assert invoice.partner_id == payment_line.partner_id, "Partner is not correct."
- assert invoice.date_due == payment_line.ml_maturity_date, "Due date is not correct."
- assert invoice.amount_total == payment_line.amount, "Payment amount is not correct."
- assert payment_line.move_line_id.amount_to_pay > 0, "Move line paid"
- assert len(self.pool("account.move.line").search(cr, uid,
- [('amount_to_pay', '>', 0), ('id', '=', payment_line.move_line_id.id)])) == 0, \
- "No payment order found for this move line"
--
- I generate the .REM file and compare it with a test file
--
- !python {model: payment.order, id: cobranca}: |
- import base64
- import time
- assert self.mode.type.ir_model_id.model == 'payment.cnab', "Modelo de wizard errado, deveria ser payment.cnab porem o selecionado foi: %s" %self.mode.type.ir_model_id.model
- wizard = self.env['payment.cnab'].create({})
- wizard.with_context(active_ids=[self.env.ref("l10n_br_account_banking_payment_cnab.cobranca").id]).export()
- generated_file = base64.b64decode(str(wizard.cnab_file))
-
- # fixing dates to have the same date as the test_file
- def change(string, interval, what):
- start = interval[0]
- end = interval[1]
- length = end - start
- if len(what)
+
+
+
+ bank.payment.line.form
+ bank.payment.line
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/l10n_br_account_banking_payment_cnab/view/l10n_br_cnab_retorno_view.xml b/l10n_br_account_banking_payment_cnab/view/l10n_br_cnab_retorno_view.xml
new file mode 100644
index 0000000..7604f01
--- /dev/null
+++ b/l10n_br_account_banking_payment_cnab/view/l10n_br_cnab_retorno_view.xml
@@ -0,0 +1,173 @@
+
+
+
+
+
+
+
+ cnab.retorno.tree
+ l10n.br.cnab
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ cnab.lote.tree
+ l10n.br.cnab.lote
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ cnab.evento.tree
+ l10n.br.cnab.evento
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ cnab.retorno.evento.form.view
+ l10n.br.cnab.evento
+
+
+
+
+
+
+ cnab.retorno.lote.form.view
+ l10n.br.cnab.lote
+
+
+
+
+
+
+ cnab.retorno.form.view
+ l10n.br.cnab
+
+
+
+
+
+
+ CNAB Retorno
+ ir.actions.act_window
+ l10n.br.cnab
+ form
+ tree,form
+
+
+
+
+
+
\ No newline at end of file
diff --git a/l10n_br_account_banking_payment_cnab/view/l10n_br_cobranca_cnab.xml b/l10n_br_account_banking_payment_cnab/view/l10n_br_cobranca_cnab.xml
index 2e314d1..981c640 100644
--- a/l10n_br_account_banking_payment_cnab/view/l10n_br_cobranca_cnab.xml
+++ b/l10n_br_account_banking_payment_cnab/view/l10n_br_cobranca_cnab.xml
@@ -20,7 +20,7 @@
Crie ordens de cobrança CNAB 240.
-
+
payment.order.form
diff --git a/l10n_br_account_banking_payment_cnab/view/l10n_br_cobranca_cnab_lines.xml b/l10n_br_account_banking_payment_cnab/view/l10n_br_cobranca_cnab_lines.xml
index e5890de..c809942 100644
--- a/l10n_br_account_banking_payment_cnab/view/l10n_br_cobranca_cnab_lines.xml
+++ b/l10n_br_account_banking_payment_cnab/view/l10n_br_cobranca_cnab_lines.xml
@@ -87,7 +87,7 @@
Lista das linhas cnab 400.
-
+
diff --git a/l10n_br_account_banking_payment_cnab/view/payment_line.xml b/l10n_br_account_banking_payment_cnab/view/payment_line.xml
new file mode 100644
index 0000000..bf79e1d
--- /dev/null
+++ b/l10n_br_account_banking_payment_cnab/view/payment_line.xml
@@ -0,0 +1,37 @@
+
+
+
+ payment.order.form
+
+ payment.order
+
+
+ {'order_id': active_id or False,
+ 'default_mode': mode}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ payment.line.form
+ payment.line
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/l10n_br_account_banking_payment_cnab/view/payment_mode.xml b/l10n_br_account_banking_payment_cnab/view/payment_mode.xml
index e0c7cb8..abec16c 100644
--- a/l10n_br_account_banking_payment_cnab/view/payment_mode.xml
+++ b/l10n_br_account_banking_payment_cnab/view/payment_mode.xml
@@ -15,6 +15,17 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/l10n_br_account_banking_payment_cnab/view/payment_order.xml b/l10n_br_account_banking_payment_cnab/view/payment_order.xml
index c601651..d71dc0b 100644
--- a/l10n_br_account_banking_payment_cnab/view/payment_order.xml
+++ b/l10n_br_account_banking_payment_cnab/view/payment_order.xml
@@ -6,22 +6,23 @@
payment.order.form.sequence
payment.order
+ ref="account_banking_payment_export.view_payment_order_form"/>
-
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
-
diff --git a/l10n_br_account_banking_payment_cnab/view/res_partner_bank.xml b/l10n_br_account_banking_payment_cnab/view/res_partner_bank.xml
index 3e47645..88e7551 100644
--- a/l10n_br_account_banking_payment_cnab/view/res_partner_bank.xml
+++ b/l10n_br_account_banking_payment_cnab/view/res_partner_bank.xml
@@ -10,14 +10,22 @@
+
+
+
+
+
+ {'required': True}
+
+
+
+ {'required': True}
+
+
-
-
-
-
diff --git a/l10n_br_account_banking_payment_cnab/wizard/l10n_bank_payment_cnab_export.py b/l10n_br_account_banking_payment_cnab/wizard/l10n_bank_payment_cnab_export.py
index 6e21f5b..b951042 100644
--- a/l10n_br_account_banking_payment_cnab/wizard/l10n_bank_payment_cnab_export.py
+++ b/l10n_br_account_banking_payment_cnab/wizard/l10n_bank_payment_cnab_export.py
@@ -24,50 +24,72 @@
import base64
import time
-from openerp import models, api, workflow, fields
-
+from openerp import models, api, workflow, fields, _
+from openerp.exceptions import Warning as UserError
from ..febraban.cnab import Cnab
+import logging
-# TODO Server action para a cada dia retornar o sufixo do arquivo para zero
+_logger = logging.getLogger(__name__)
+try:
+ from cnab240.errors import (Cnab240Error)
+except ImportError as err:
+ _logger.debug = err
class L10nPaymentCnab(models.TransientModel):
_name = 'payment.cnab'
_description = 'Export payment order(s) in cnab layout'
- name = fields.Char(u'Nome', size=255)
- cnab_file = fields.Binary('CNAB File', readonly=True)
+ name = fields.Char(string=u'Nome', size=255)
+
+ cnab_file = fields.Binary(string='CNAB File', readonly=True)
+
state = fields.Selection(
- [('init', 'init'),
- ('done', 'done')],
- 'state',
+ string='state',
+ selection=[('init', 'init'), ('done', 'done')],
default='init',
- readonly=True)
+ readonly=True
+ )
@api.multi
def export(self):
for order_id in self.env.context.get('active_ids', []):
order = self.env['payment.order'].browse(order_id)
- cnab = Cnab.get_cnab(order.mode.bank_id.bank_bic,
- order.mode.type.code)()
- remessa = cnab.remessa(order)
- suf_arquivo = order.get_next_sufixo()
+ if not order.line_ids:
+ raise UserError(
+ _('Error'),
+ _('Adicione pelo menos uma linha na ordem de pagamento.'))
+
+ # Criando instancia do CNAB a partir do código do banco
+ cnab = Cnab.get_cnab(
+ order.mode.bank_id.bank_bic, order.mode.type.code)()
+
+ # Criando remessa de eventos
+ try:
+ remessa = cnab.remessa(order)
+ except Cnab240Error as e:
+ from openerp import exceptions
+ raise exceptions.ValidationError(
+ "Campo preenchido incorretamente \n\n{0}".format(e))
if order.mode.type.code == '240':
self.name = 'CB%s%s.REM' % (
time.strftime('%d%m'), str(order.file_number))
- elif order.mode.type.code == '400':
- self.name = 'CB%s%s.REM' % (
- time.strftime('%d%m'), str(suf_arquivo))
+ # elif order.mode.type.code == '400':
+ # self.name = 'CB%s%s.REM' % (
+ # time.strftime('%d%m'), str(suf_arquivo))
elif order.mode.type.code == '500':
self.name = 'PG%s%s.REM' % (
time.strftime('%d%m'), str(order.file_number))
self.state = 'done'
self.cnab_file = base64.b64encode(remessa)
- workflow.trg_validate(self.env.uid, 'payment.order', order_id,
- 'done', self.env.cr)
+ order.cnab_file = base64.b64encode(remessa)
+ order.cnab_filename = self.name
+
+ workflow.trg_validate(
+ self.env.uid, 'payment.order', order_id, 'done', self.env.cr)
return {
'type': 'ir.actions.act_window',
diff --git a/l10n_br_account_payment_boleto/demo/payment_demo.xml b/l10n_br_account_payment_boleto/demo/payment_demo.xml
index 94e0f0c..26d9d2c 100644
--- a/l10n_br_account_payment_boleto/demo/payment_demo.xml
+++ b/l10n_br_account_payment_boleto/demo/payment_demo.xml
@@ -20,7 +20,7 @@
18
DM
29
- S
+
03
DM
19
- N
+
@@ -65,7 +65,7 @@
CNR
PD
- N
+
@@ -87,7 +87,7 @@
109
DM
- N
+
102
DM
- N
+
@@ -132,7 +132,7 @@
SR
- N
+
SR
- N
+
diff --git a/l10n_br_account_payment_mode/__openerp__.py b/l10n_br_account_payment_mode/__openerp__.py
index 24c78be..1d58a49 100644
--- a/l10n_br_account_payment_mode/__openerp__.py
+++ b/l10n_br_account_payment_mode/__openerp__.py
@@ -8,14 +8,13 @@
'version': '8.0.1.0.0',
'category': 'Banking addons',
'license': 'AGPL-3',
- 'summary': '',
'author': "KMEE, Odoo Community Association (OCA)",
"website": "https://odoo-community.org/",
'depends': [
- 'l10n_br_account',
'l10n_br_data_base',
'account_due_list_payment_mode',
- 'account_banking_payment_export'
+ 'account_banking_payment_export',
+ 'l10n_br_account_banking_payment',
],
'data': [
'views/payment_mode_view.xml',
diff --git a/l10n_br_account_payment_mode/models/payment_mode.py b/l10n_br_account_payment_mode/models/payment_mode.py
index 16e1946..a27a4fd 100644
--- a/l10n_br_account_payment_mode/models/payment_mode.py
+++ b/l10n_br_account_payment_mode/models/payment_mode.py
@@ -39,16 +39,6 @@ class PaymentMode(models.Model):
('99', u'99 - Outros')],
string='Tipo SPED', required=True, default='99')
- type_purchase_payment = fields.Selection(
- [('01', u'01 - Crédito em conta-corrente ou poupança Bradesco'),
- ('02', u'02 - Cheque OP ( Ordem de Pagamento'),
- ('03', u'03 - DOC COMPE'),
- ('05', u'05 - Crédito em conta real time'),
- ('08', u'08 - TED'),
- ('30', u'30 - Rastreamento de Títulos'),
- ('31', u'31 - Títulos de terceiros'),
- ]
- )
internal_sequence_id = fields.Many2one('ir.sequence', u'Sequência')
instrucoes = fields.Text(u'Instruções de cobrança')
invoice_print = fields.Boolean(
diff --git a/l10n_br_account_payment_mode/views/payment_mode_view.xml b/l10n_br_account_payment_mode/views/payment_mode_view.xml
index 8ace235..da9cc2b 100644
--- a/l10n_br_account_payment_mode/views/payment_mode_view.xml
+++ b/l10n_br_account_payment_mode/views/payment_mode_view.xml
@@ -16,7 +16,8 @@
-
+
-
-
-
+
+
diff --git a/l10n_br_cnab400_import/__openerp__.py b/l10n_br_cnab400_import/__openerp__.py
index bfc0c1a..d0e1974 100644
--- a/l10n_br_cnab400_import/__openerp__.py
+++ b/l10n_br_cnab400_import/__openerp__.py
@@ -40,7 +40,7 @@
'data/l10n_br_res_partner_bank_type.xml',
],
'active': False,
- "installable": True,
+ "installable": False,
"auto_install": False,
'description': """
Allows to import CNAB 400 (Centro Nacional de Automação Bancária)
diff --git a/l10n_br_cnab400_import/models/__init__.py b/l10n_br_cnab400_import/models/__init__.py
index d0a4b42..3c3f5f6 100644
--- a/l10n_br_cnab400_import/models/__init__.py
+++ b/l10n_br_cnab400_import/models/__init__.py
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
-#from . import account_bank_statement_line
+# from . import account_bank_statement_line
from . import account_move_line
from . import account_bank_statement_import
from . import l10n_br_cnab_move
diff --git a/l10n_br_cnab400_import/models/account_bank_statement.py b/l10n_br_cnab400_import/models/account_bank_statement.py
index 309e471..fc38fe8 100644
--- a/l10n_br_cnab400_import/models/account_bank_statement.py
+++ b/l10n_br_cnab400_import/models/account_bank_statement.py
@@ -28,11 +28,11 @@ class AccountBankStatementLine(models.Model):
@api.model
def get_reconcile_lines_from_cnab_move(self, this, excluded_ids=None):
"""return move.line to reconcile with statement line"""
- move_lines = self.env['account.move.line'].search(
- [('transaction_ref', '=', this.name),
- ('name', '=', this.ref),
- ('company_id', '=', self.env.user.company_id.id)
- ])
+ move_lines = self.env['account.move.line'].search([
+ ('transaction_ref', '=', this.name),
+ ('name', '=', this.ref),
+ ('company_id', '=', self.env.user.company_id.id)
+ ])
try:
assert len(move_lines) <= 1
except Exception, e: