diff --git a/__unported__/account_statement_l10n_br_cnab240_import/__openerp__.py b/__unported__/account_statement_l10n_br_cnab240_import/__openerp__.py index 8a983dc..4b98065 100644 --- a/__unported__/account_statement_l10n_br_cnab240_import/__openerp__.py +++ b/__unported__/account_statement_l10n_br_cnab240_import/__openerp__.py @@ -20,30 +20,30 @@ ############################################################################## {'name': "Bank statement CNAB 240 import", - 'version': '1.0.0', - 'author': 'KMEE', - 'maintainer': 'Luis Felipe Mileo', - 'category': 'Finance', - 'complexity': 'normal', - 'depends': [ - 'account_statement_commission', - 'account_statement_transactionid_import' - ], - 'external_dependencies': { - 'python': ['cnab240'], - }, - 'description': """ - Allows to import CNAB 240 (Centro Nacional de Automação Bancária) statement files, using - *account_statement_base_import* generic inheritance mechanism to import - statements. + 'version': '1.0.0', + 'author': 'KMEE', + 'maintainer': 'Luis Felipe Mileo', + 'category': 'Finance', + 'complexity': 'normal', + 'depends': [ + 'account_statement_commission', + 'account_statement_transactionid_import' + ], + 'external_dependencies': { + 'python': ['cnab240'], + }, + 'description': """ + Allows to import CNAB 240 (Centro Nacional de Automação Bancária) statement + files, using *account_statement_base_import* generic inheritance + mechanism to import statements. It requires python cnab240 library to work. """, - 'website': 'http://www.kmee.com.br', - 'data': [], - 'test': [], - 'installable': True, - 'images': [], - 'auto_install': False, - 'license': 'AGPL-3', + 'website': 'http://www.kmee.com.br', + 'data': [], + 'test': [], + 'installable': True, + 'images': [], + 'auto_install': False, + 'license': 'AGPL-3', } diff --git a/__unported__/account_statement_l10n_br_cnab240_import/parser/__init__.py b/__unported__/account_statement_l10n_br_cnab240_import/parser/__init__.py index bf8f8cc..b8818f3 100644 --- a/__unported__/account_statement_l10n_br_cnab240_import/parser/__init__.py +++ b/__unported__/account_statement_l10n_br_cnab240_import/parser/__init__.py @@ -18,4 +18,5 @@ # along with this program. If not, see . # ############################################################################## + from . import cnab240_parser diff --git a/__unported__/account_statement_l10n_br_cnab240_import/parser/cnab240_parser.py b/__unported__/account_statement_l10n_br_cnab240_import/parser/cnab240_parser.py index 981dc87..43fb3bb 100644 --- a/__unported__/account_statement_l10n_br_cnab240_import/parser/cnab240_parser.py +++ b/__unported__/account_statement_l10n_br_cnab240_import/parser/cnab240_parser.py @@ -24,6 +24,7 @@ from openerp.tools.translate import _ from openerp.addons.account_statement_base_import.parser import \ BankStatementImportParser + try: import cnab240 from cnab240.bancos import cef @@ -57,26 +58,27 @@ def _parse(self, *args, **kwargs): cnab240_file.seek(0) cnab240_file.write(self.filebuffer) cnab240_file.flush() - + ret_file = codecs.open(cnab240_file.name, encoding='ascii') arquivo = Arquivo(cef, arquivo=ret_file) cnab240_file.close() - + res = [] for lote in arquivo.lotes: for evento in lote.eventos: - - res.append({ + res.append({ 'name': evento.sacado_nome, - 'date': datetime.datetime.strptime(str(evento.vencimento_titulo), '%d%m%Y'), + 'date': datetime.datetime.strptime( + str(evento.vencimento_titulo), '%d%m%Y'), 'amount': evento.valor_titulo, 'ref': evento.numero_documento, - 'label': evento.sacado_inscricao_numero, #cnpj - 'transaction_id': evento.nosso_numero_identificacao, #nosso numero - 'commission_amount':evento.valor_tarifas, + 'label': evento.sacado_inscricao_numero, # cnpj + 'transaction_id': evento.nosso_numero_identificacao, + # nosso numero + 'commission_amount': evento.valor_tarifas, }) - + self.result_row_list = res return True diff --git a/__unported__/account_statement_l10n_br_cnab240_import/statement.py b/__unported__/account_statement_l10n_br_cnab240_import/statement.py index e0357e4..ad9d5f7 100644 --- a/__unported__/account_statement_l10n_br_cnab240_import/statement.py +++ b/__unported__/account_statement_l10n_br_cnab240_import/statement.py @@ -30,5 +30,6 @@ def _get_import_type_selection(self, cr, uid, context=None): selection = super(AccountStatementProfil, self )._get_import_type_selection(cr, uid, context=context) - selection.append(('cnab240_so', _(u'CNAB 240 - Centro Nacional de Automação Bancária'))) + selection.append(('cnab240_so', _( + u'CNAB 240 - Centro Nacional de Automação Bancária'))) return selection diff --git a/l10n_br_account_banking_payment_cnab/README.rst b/l10n_br_account_banking_payment_cnab/README.rst index 4f21ec5..c867055 100644 --- a/l10n_br_account_banking_payment_cnab/README.rst +++ b/l10n_br_account_banking_payment_cnab/README.rst @@ -1,5 +1,5 @@ .. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg - :alt: License: AGPL-3 +:alt: License: AGPL-3 Account Banking Brazillian - Payments Export Infrastructure ============================================================= @@ -60,7 +60,7 @@ Maintainer ---------- .. image:: https://brasil.odoo.com/logo.png - :alt: Odoo Brazil +:alt: Odoo Brazil :target: http://brazil.odoo.com This module is maintained by the Odoo Brazil. diff --git a/l10n_br_account_banking_payment_cnab/__init__.py b/l10n_br_account_banking_payment_cnab/__init__.py index 2a266f1..a74946f 100644 --- a/l10n_br_account_banking_payment_cnab/__init__.py +++ b/l10n_br_account_banking_payment_cnab/__init__.py @@ -21,4 +21,4 @@ # ############################################################################## -import wizard \ No newline at end of file +import wizard diff --git a/l10n_br_account_banking_payment_cnab/__openerp__.py b/l10n_br_account_banking_payment_cnab/__openerp__.py old mode 100644 new mode 100755 index d52f907..7ef1955 --- a/l10n_br_account_banking_payment_cnab/__openerp__.py +++ b/l10n_br_account_banking_payment_cnab/__openerp__.py @@ -35,6 +35,7 @@ 'depends': [ 'l10n_br_account_payment_boleto', 'l10n_br_account_payment_mode', + 'account_direct_debit', ], 'data': [ 'view/l10n_br_payment_cnab.xml', diff --git a/l10n_br_account_banking_payment_cnab/febraban/cnab.py b/l10n_br_account_banking_payment_cnab/febraban/cnab.py index bd45468..3dd72cb 100644 --- a/l10n_br_account_banking_payment_cnab/febraban/cnab.py +++ b/l10n_br_account_banking_payment_cnab/febraban/cnab.py @@ -24,7 +24,6 @@ class Cnab(object): - def __init__(self): pass 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 7117769..f86176e 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 @@ -26,6 +26,5 @@ class BradescoCnab240(Cnab240): - def __init__(self): super(Cnab240, self).__init__() 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 f786f24..a7fc7c9 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 @@ -25,6 +25,5 @@ class Cef240(Cnab240): - def __init__(self): super(Cnab240, self).__init__() 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 old mode 100644 new mode 100755 index fe5de22..7d503c0 --- 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 @@ -23,6 +23,9 @@ from ..cnab import Cnab from cnab240.tipos import Arquivo +from cnab240.tipos import Evento +from cnab240.tipos import Lote +from cnab240.bancos import banco from decimal import Decimal from openerp.addons.l10n_br_base.tools.misc import punctuation_rm import datetime @@ -35,6 +38,7 @@ class Cnab240(Cnab): """ """ + def __init__(self): super(Cnab, self).__init__() @@ -66,17 +70,24 @@ def _prepare_header(self): :param: :return: """ + data_de_geracao = (self.order.date_created[8:11] + + self.order.date_created[5:7] + + self.order.date_created[0:4]) + # hora_de_geracao = (str(datetime.datetime.now().hour-3) + + # str(datetime.datetime.now().minute)) + t = datetime.datetime.now() - datetime.timedelta(hours=3) # FIXME + hora_de_geracao = t.strftime("%H%M%S") return { - 'arquivo_data_de_geracao': 27062012, - 'arquivo_hora_de_geracao': 112000, - 'arquivo_sequencia': 1, + 'arquivo_data_de_geracao': int(data_de_geracao), + 'arquivo_hora_de_geracao': int(hora_de_geracao), + 'arquivo_sequencia': self.order.id, '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_agencia_conta_dv': int( - self.order.mode.bank_id.bra_number_dig), + self.order.mode.bank_id.acc_number_dig), 'cedente_nome': self.order.company_id.legal_name, 'cedente_codigo_agencia_digito': int( self.order.mode.bank_id.bra_number_dig), @@ -118,25 +129,38 @@ def _prepare_segmento(self, line): :return: """ carteira, nosso_numero, digito = self.nosso_numero( - line.move_line_id.transaction_ref) # TODO: Improve! + str(line.move_line_id.transaction_ref)) # TODO: Improve! prefixo, sulfixo = self.cep(line.partner_id.zip) + if self.order.mode.boleto_aceite == 'S': + aceite = 'A' + else: + aceite = 'N' return { - 'cedente_agencia': 4459, # FIXME - 'cedente_conta': 17600, # FIXME - 'cedente_agencia_conta_dv': 6, + 'cedente_agencia': int( + self.order.mode.bank_id.bra_number), # FIXME + 'cedente_conta': int(self.order.mode.bank_id.acc_number), # FIXME + 'cedente_agencia_conta_dv': int( + self.order.mode.bank_id.acc_number_dig), 'carteira_numero': int(carteira), 'nosso_numero': int(nosso_numero), 'nosso_numero_dv': int(digito), - 'identificacao_titulo': u'0000000', # TODO - 'numero_documento': line.name, + 'identificacao_titulo': u'%s' % str(line.move_line_id.move_id.id), + # u'0000000', TODO + 'numero_documento': line.move_line_id.invoice.internal_number, 'vencimento_titulo': self.format_date( line.ml_maturity_date), - 'valor_titulo': Decimal('100.00'), - 'especie_titulo': 8, # TODO: - 'aceite_titulo': u'A', # TODO: + # 'valor_titulo': Decimal(v_t), + 'valor_titulo': Decimal("{0:,.2f}".format( + line.move_line_id.debit)), + # Decimal('100.00'), + 'especie_titulo': int(self.order.mode.boleto_especie), + 'aceite_titulo': u'%s' % (aceite), # TODO: 'data_emissao_titulo': self.format_date( line.ml_date_created), - 'juros_mora_taxa_dia': Decimal('2.00'), + # 'juros_mora_taxa_dia': Decimal('2.00'), + 'juros_mora_taxa_dia': Decimal( + "{0:,.2f}".format(line.move_line_id.debit * 0.00066666667)), + # FIXME 'valor_abatimento': Decimal('0.00'), 'sacado_inscricao_tipo': int( self.sacado_inscricao_tipo(line.partner_id)), @@ -150,8 +174,8 @@ def _prepare_segmento(self, line): 'sacado_cep_sufixo': int(sulfixo), 'sacado_cidade': line.partner_id.l10n_br_city_id.name, 'sacado_uf': line.partner_id.state_id.code, - 'codigo_protesto': 3, - 'prazo_protesto': 0, + 'codigo_protesto': int(self.order.mode.boleto_protesto), + 'prazo_protesto': int(self.order.mode.boleto_protesto_prazo), 'codigo_baixa': 0, 'prazo_baixa': 0, } @@ -164,8 +188,37 @@ def remessa(self, order): """ self.order = order self.arquivo = Arquivo(self.bank, **self._prepare_header()) + codigo_evento = 1 + evento = Evento(self.bank, codigo_evento) + for line in order.line_ids: - self.arquivo.incluir_cobranca(**self._prepare_segmento(line)) + seg = self._prepare_segmento(line) + seg_p = banco.registros.SegmentoP(**seg) + evento.adicionar_segmento(seg_p) + + seg_q = banco.registros.SegmentoQ(**seg) + evento.adicionar_segmento(seg_q) + + lote_cobranca = self.arquivo.encontrar_lote(codigo_evento) + + if lote_cobranca is None: + header = banco.registros.HeaderLoteCobranca( + **self.arquivo.header.todict()) + trailer = banco.registros.TrailerLoteCobranca() + lote_cobranca = Lote(self.bank, header, trailer) + self.arquivo.adicionar_lote(lote_cobranca) + + if header.controlecob_numero is None: + header.controlecob_numero = int('{0}{1:02}'.format( + self.arquivo.header.arquivo_sequencia, + lote_cobranca.codigo)) + + if header.controlecob_data_gravacao is None: + header.controlecob_data_gravacao = \ + self.arquivo.header.arquivo_data_de_geracao + + lote_cobranca.adicionar_evento(evento) + self.arquivo.trailer.totais_quantidade_registros += len(evento) remessa = unicode(self.arquivo) return unicodedata.normalize( 'NFKD', remessa).encode('ascii', 'ignore') 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 42b4a19..16e2694 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 @@ -22,7 +22,6 @@ class Cnab400(Cnab): - def __init__(self): super(Cnab, self).__init__() diff --git a/l10n_br_account_banking_payment_cnab/view/l10n_br_payment_cnab.xml b/l10n_br_account_banking_payment_cnab/view/l10n_br_payment_cnab.xml index eadaaa2..eec1388 100644 --- a/l10n_br_account_banking_payment_cnab/view/l10n_br_payment_cnab.xml +++ b/l10n_br_account_banking_payment_cnab/view/l10n_br_payment_cnab.xml @@ -1,23 +1,26 @@ - + - payment.cnab.form - payment.cnab - -
+ payment.cnab.form + payment.cnab + + - + - +
-