From c4ea64dfbae135f39c04ad82e09debead2a6a00d Mon Sep 17 00:00:00 2001 From: Luis Felipe Mileo Date: Fri, 21 Jul 2017 09:23:03 -0300 Subject: [PATCH 01/60] [WIP] Financial Payment Order --- .../model/bank_payment_line.py | 20 + l10n_br_financial_payment_order/README.rst | 79 +++ l10n_br_financial_payment_order/__init__.py | 1 + .../__openerp__.py | 37 ++ .../demo/bank_payment_line.xml | 15 + .../demo/payment_mode.xml | 15 + .../demo/payment_mode_type.xml | 15 + .../demo/payment_order.xml | 15 + .../febraban/__init__.py | 22 + .../febraban/boleto/__init__.py | 23 + .../febraban/boleto/document.py | 318 ++++++++++ .../febraban/cnab.py | 51 ++ .../febraban/cnab_240/__init__.py | 20 + .../febraban/cnab_240/bancos/__init__.py | 22 + .../febraban/cnab_240/bancos/bb.py | 60 ++ .../febraban/cnab_240/bancos/bradesco.py | 84 +++ .../febraban/cnab_240/bancos/cef.py | 108 ++++ .../febraban/cnab_240/bancos/itau.py | 83 +++ .../febraban/cnab_240/bancos/santander.py | 59 ++ .../febraban/cnab_240/cnab_240.py | 564 +++++++++++++++++ .../febraban/cnab_400/__init__.py | 19 + .../febraban/cnab_400/bancos/__init__.py | 20 + .../febraban/cnab_400/bancos/bradesco.py | 113 ++++ .../febraban/cnab_400/cnab_400.py | 375 ++++++++++++ .../febraban/pag_for/__init__.py | 24 + .../febraban/pag_for/bancos/__init__.py | 22 + .../febraban/pag_for/bancos/bradesco.py | 75 +++ .../febraban/pag_for/pag_for500.py | 575 ++++++++++++++++++ .../models/__init__.py | 4 + .../models/bank_payment_line.py | 30 + .../models/payment_line.py | 55 ++ .../models/payment_mode.py | 51 ++ .../models/payment_mode_type.py | 17 + .../models/payment_order.py | 25 + .../security/bank_payment_line.xml | 20 + .../security/payment_line.xml | 20 + .../security/payment_mode.xml | 20 + .../security/payment_mode_type.xml | 20 + .../security/payment_order.xml | 20 + .../static/description/icon.png | Bin 0 -> 9455 bytes .../views/bank_payment_line.xml | 51 ++ .../views/payment_line.xml | 51 ++ .../views/payment_mode.xml | 51 ++ .../views/payment_mode_type.xml | 51 ++ .../views/payment_order.xml | 51 ++ 45 files changed, 3371 insertions(+) create mode 100644 l10n_br_financial_payment_order/README.rst create mode 100644 l10n_br_financial_payment_order/__init__.py create mode 100644 l10n_br_financial_payment_order/__openerp__.py create mode 100644 l10n_br_financial_payment_order/demo/bank_payment_line.xml create mode 100644 l10n_br_financial_payment_order/demo/payment_mode.xml create mode 100644 l10n_br_financial_payment_order/demo/payment_mode_type.xml create mode 100644 l10n_br_financial_payment_order/demo/payment_order.xml create mode 100644 l10n_br_financial_payment_order/febraban/__init__.py create mode 100644 l10n_br_financial_payment_order/febraban/boleto/__init__.py create mode 100644 l10n_br_financial_payment_order/febraban/boleto/document.py create mode 100644 l10n_br_financial_payment_order/febraban/cnab.py create mode 100644 l10n_br_financial_payment_order/febraban/cnab_240/__init__.py create mode 100644 l10n_br_financial_payment_order/febraban/cnab_240/bancos/__init__.py create mode 100644 l10n_br_financial_payment_order/febraban/cnab_240/bancos/bb.py create mode 100644 l10n_br_financial_payment_order/febraban/cnab_240/bancos/bradesco.py create mode 100644 l10n_br_financial_payment_order/febraban/cnab_240/bancos/cef.py create mode 100644 l10n_br_financial_payment_order/febraban/cnab_240/bancos/itau.py create mode 100644 l10n_br_financial_payment_order/febraban/cnab_240/bancos/santander.py create mode 100644 l10n_br_financial_payment_order/febraban/cnab_240/cnab_240.py create mode 100644 l10n_br_financial_payment_order/febraban/cnab_400/__init__.py create mode 100644 l10n_br_financial_payment_order/febraban/cnab_400/bancos/__init__.py create mode 100644 l10n_br_financial_payment_order/febraban/cnab_400/bancos/bradesco.py create mode 100644 l10n_br_financial_payment_order/febraban/cnab_400/cnab_400.py create mode 100644 l10n_br_financial_payment_order/febraban/pag_for/__init__.py create mode 100644 l10n_br_financial_payment_order/febraban/pag_for/bancos/__init__.py create mode 100644 l10n_br_financial_payment_order/febraban/pag_for/bancos/bradesco.py create mode 100644 l10n_br_financial_payment_order/febraban/pag_for/pag_for500.py create mode 100644 l10n_br_financial_payment_order/models/__init__.py create mode 100644 l10n_br_financial_payment_order/models/bank_payment_line.py create mode 100644 l10n_br_financial_payment_order/models/payment_line.py create mode 100644 l10n_br_financial_payment_order/models/payment_mode.py create mode 100644 l10n_br_financial_payment_order/models/payment_mode_type.py create mode 100644 l10n_br_financial_payment_order/models/payment_order.py create mode 100644 l10n_br_financial_payment_order/security/bank_payment_line.xml create mode 100644 l10n_br_financial_payment_order/security/payment_line.xml create mode 100644 l10n_br_financial_payment_order/security/payment_mode.xml create mode 100644 l10n_br_financial_payment_order/security/payment_mode_type.xml create mode 100644 l10n_br_financial_payment_order/security/payment_order.xml create mode 100644 l10n_br_financial_payment_order/static/description/icon.png create mode 100644 l10n_br_financial_payment_order/views/bank_payment_line.xml create mode 100644 l10n_br_financial_payment_order/views/payment_line.xml create mode 100644 l10n_br_financial_payment_order/views/payment_mode.xml create mode 100644 l10n_br_financial_payment_order/views/payment_mode_type.xml create mode 100644 l10n_br_financial_payment_order/views/payment_order.xml 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 index ddd64c9..b58ff5f 100644 --- a/l10n_br_account_banking_payment_cnab/model/bank_payment_line.py +++ b/l10n_br_account_banking_payment_cnab/model/bank_payment_line.py @@ -98,3 +98,23 @@ def default_get(self, fields_list): string=u'Código de finalidade complementar', help=u'Campo P013 do CNAB', ) + + @api.model + def same_fields_payment_line_and_bank_payment_line(self): + """ + This list of fields is used both to compute the grouping + hashcode and to copy the values from payment line + to bank payment line + The fields must have the same name on the 2 objects + """ + same_fields = super( + BankPaymentLine, self + ).same_fields_payment_line_and_bank_payment_line() + + # TODO: Implementar campo brasileiros que permitem mesclar linhas + + # same_fields = [ + # 'currency', 'partner_id', + # 'bank_id', 'date', 'state'] + + return same_fields \ No newline at end of file diff --git a/l10n_br_financial_payment_order/README.rst b/l10n_br_financial_payment_order/README.rst new file mode 100644 index 0000000..ec0d556 --- /dev/null +++ b/l10n_br_financial_payment_order/README.rst @@ -0,0 +1,79 @@ +.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 + +=============================== +L10n Br Financial Payment Order +=============================== + +Integracao entre o modulo financeiro e a ordem de pagamento + +Installation +============ + +To install this module, you need to: + +#. Do this ... + +Configuration +============= + +To configure this module, you need to: + +#. Go to ... + +Usage +===== + +To use this module, you need to: + +#. Go to ... + +.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas + :alt: Try me on Runbot + :target: https://runbot.odoo-community.org/runbot/{repo_id}/{branch} + +.. repo_id is available in https://github.com/OCA/maintainer-tools/blob/master/tools/repos_with_ids.txt +.. branch is "8.0" for example + +Known issues / Roadmap +====================== + +* ... + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues +`_. In case of trouble, please +check there if your issue has already been reported. If you spotted it first, +help us smashing it by providing a detailed and welcomed feedback. + +Credits +======= + +Images +------ + +* Odoo Community Association: `Icon `_. + +Contributors +------------ + +* Firstname Lastname +* Second Person + +Maintainer +---------- + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +This module is maintained by the OCA. + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +To contribute to this module, please visit https://odoo-community.org. diff --git a/l10n_br_financial_payment_order/__init__.py b/l10n_br_financial_payment_order/__init__.py new file mode 100644 index 0000000..0650744 --- /dev/null +++ b/l10n_br_financial_payment_order/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/l10n_br_financial_payment_order/__openerp__.py b/l10n_br_financial_payment_order/__openerp__.py new file mode 100644 index 0000000..524df3a --- /dev/null +++ b/l10n_br_financial_payment_order/__openerp__.py @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- +# Copyright 2017 KMEE +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +{ + 'name': 'L10n Br Financial Payment Order', + 'summary': """ + Integracao entre o modulo financeiro e a ordem de pagamento""", + 'version': '8.0.1.0.0', + 'license': 'AGPL-3', + 'author': 'KMEE,Odoo Community Association (OCA)', + 'website': 'www.kmee.com.br', + 'depends': [ + 'account_banking_payment_export', + 'l10n_br_account_product', + 'financial_account', + ], + 'data': [ + 'security/payment_mode.xml', + 'security/payment_mode_type.xml', + 'security/bank_payment_line.xml', + 'security/payment_line.xml', + 'security/payment_order.xml', + + 'views/payment_mode.xml', + 'views/payment_mode_type.xml', + 'views/bank_payment_line.xml', + 'views/payment_line.xml', + 'views/payment_order.xml', + ], + 'demo': [ + 'demo/payment_mode.xml', + 'demo/payment_mode_type.xml', + 'demo/bank_payment_line.xml', + 'demo/payment_order.xml', + ], +} diff --git a/l10n_br_financial_payment_order/demo/bank_payment_line.xml b/l10n_br_financial_payment_order/demo/bank_payment_line.xml new file mode 100644 index 0000000..1ce6210 --- /dev/null +++ b/l10n_br_financial_payment_order/demo/bank_payment_line.xml @@ -0,0 +1,15 @@ + + + + + + + + + + diff --git a/l10n_br_financial_payment_order/demo/payment_mode.xml b/l10n_br_financial_payment_order/demo/payment_mode.xml new file mode 100644 index 0000000..2434e3a --- /dev/null +++ b/l10n_br_financial_payment_order/demo/payment_mode.xml @@ -0,0 +1,15 @@ + + + + + + + + + + diff --git a/l10n_br_financial_payment_order/demo/payment_mode_type.xml b/l10n_br_financial_payment_order/demo/payment_mode_type.xml new file mode 100644 index 0000000..8fddc48 --- /dev/null +++ b/l10n_br_financial_payment_order/demo/payment_mode_type.xml @@ -0,0 +1,15 @@ + + + + + + + + + + diff --git a/l10n_br_financial_payment_order/demo/payment_order.xml b/l10n_br_financial_payment_order/demo/payment_order.xml new file mode 100644 index 0000000..19d9d78 --- /dev/null +++ b/l10n_br_financial_payment_order/demo/payment_order.xml @@ -0,0 +1,15 @@ + + + + + + + + + + diff --git a/l10n_br_financial_payment_order/febraban/__init__.py b/l10n_br_financial_payment_order/febraban/__init__.py new file mode 100644 index 0000000..0104e25 --- /dev/null +++ b/l10n_br_financial_payment_order/febraban/__init__.py @@ -0,0 +1,22 @@ +# coding: utf-8 +# ########################################################################### +# +# Author: Luis Felipe Mileo +# Fernando Marcato Rodrigues +# Daniel Sadamo Hirayama +# Copyright 2015 KMEE - www.kmee.com.br +# +# 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 . +# +############################################################################## diff --git a/l10n_br_financial_payment_order/febraban/boleto/__init__.py b/l10n_br_financial_payment_order/febraban/boleto/__init__.py new file mode 100644 index 0000000..4696cde --- /dev/null +++ b/l10n_br_financial_payment_order/febraban/boleto/__init__.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Account Payment Boleto module for Odoo +# Copyright (C) 2012-2015 KMEE (http://www.kmee.com.br) +# @author Luis Felipe Miléo +# +# 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 . +# +############################################################################## + +from . import document diff --git a/l10n_br_financial_payment_order/febraban/boleto/document.py b/l10n_br_financial_payment_order/febraban/boleto/document.py new file mode 100644 index 0000000..c851239 --- /dev/null +++ b/l10n_br_financial_payment_order/febraban/boleto/document.py @@ -0,0 +1,318 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Account Payment Boleto module for Odoo +# Copyright (C) 2012-2015 KMEE (http://www.kmee.com.br) +# @author Luis Felipe Miléo +# +# 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 . +# +############################################################################## + +from datetime import datetime, date +import logging + +_logger = logging.getLogger(__name__) + +try: + from pyboleto import bank +except ImportError as err: + _logger.debug = err + + +try: + from cStringIO import StringIO +except ImportError: + from StringIO import StringIO +BoletoException = bank.BoletoException + + +class Boleto: + boleto = object + account_number = '' + account_digit = '' + + branch_number = '' + branch_digit = '' + + nosso_numero = '' + + @staticmethod + def getBoleto(move_line, nosso_numero): + boleto_type = move_line.payment_mode_id.boleto_type + if boleto_type: + return dict_boleto[boleto_type][0](move_line, nosso_numero) + raise BoletoException(u'Configure o tipo de boleto no modo de ' + u'pagamento') + + @staticmethod + def getBoletoClass(move_line): + bank_code = move_line.payment_mode_id.bank_id.bank.bic + return bank.get_class_for_codigo(bank_code) + + def __init__(self, move_line, nosso_numero): + self._cedente(move_line.company_id) + self._sacado(move_line.partner_id) + self._move_line(move_line) + self.nosso_numero = nosso_numero + + def getAccountNumber(self): + if self.account_digit: + return str(self.account_number + '-' + + self.account_digit).encode('utf-8') + return self.account_number.encode('utf-8') + + def getBranchNumber(self): + if self.branch_digit: + return str(self.branch_number + '-' + + self.branch_digit).encode('utf-8') + return self.branch_number.encode('utf-8') + + def _move_line(self, move_line): + self._payment_mode(move_line.payment_mode_id) + self.boleto.data_vencimento = datetime.date(datetime.strptime( + move_line.date_maturity, '%Y-%m-%d')) + self.boleto.data_documento = datetime.date(datetime.strptime( + move_line.invoice.date_invoice, '%Y-%m-%d')) + self.boleto.data_processamento = date.today() + self.boleto.valor = str("%.2f" % move_line.debit or move_line.credit) + self.boleto.valor_documento = str("%.2f" % move_line.debit or + move_line.credit) + self.boleto.especie = \ + move_line.currency_id and move_line.currency_id.symbol or 'R$' + self.boleto.quantidade = '' # str("%.2f" % move_line.amount_currency) + self.boleto.numero_documento = move_line.name.encode('utf-8') + + def _payment_mode(self, payment_mode_id): + """ + :param payment_mode: + :return: + """ + self.boleto.convenio = payment_mode_id.boleto_convenio + self.boleto.especie_documento = payment_mode_id.boleto_modalidade + self.boleto.aceite = payment_mode_id.boleto_aceite + self.boleto.carteira = payment_mode_id.boleto_carteira + + def _cedente(self, company): + """ + :param company: + :return: + """ + self.boleto.cedente = company.partner_id.legal_name.encode('utf-8') + self.boleto.cedente_documento = company.cnpj_cpf.encode('utf-8') + self.boleto.cedente_bairro = company.district + self.boleto.cedente_cep = company.zip + self.boleto.cedente_cidade = company.city + self.boleto.cedente_logradouro = company.street + ', ' + company.number + self.boleto.cedente_uf = company.state_id.code + self.boleto.agencia_cedente = self.getBranchNumber() + self.boleto.conta_cedente = self.getAccountNumber() + + def _sacado(self, partner): + """ + + :param partner: + :return: + """ + self.boleto.sacado_endereco = partner.street + ', ' + partner.number + self.boleto.sacado_cidade = partner.city + self.boleto.sacado_bairro = partner.district + self.boleto.sacado_uf = partner.state_id.code + self.boleto.sacado_cep = partner.zip + self.boleto.sacado_nome = partner.legal_name + self.boleto.sacado_documento = partner.cnpj_cpf + + @classmethod + def get_pdfs(cls, boleto_list): + """ + + :param boletoList: + :return: + """ + fbuffer = StringIO() + + fbuffer.reset() + from pyboleto.pdf import BoletoPDF + + boleto = BoletoPDF(fbuffer) + for i in range(len(boleto_list)): + boleto.drawBoleto(boleto_list[i]) + boleto.nextPage() + boleto.save() + boleto_file = fbuffer.getvalue() + + fbuffer.close() + return boleto_file + + +class BoletoBB(Boleto): + + def __init__(self, move_line, nosso_numero): + # TODO: size o convenio and nosso numero, replace (7,2) + # Size of convenio 4, 6, 7 or 8 + # Nosso Numero format. 1 or 2 + # Used only for convenio=6 + # 1: Nosso Numero with 5 positions + # 2: Nosso Numero with 17 positions + self.boleto = Boleto.getBoletoClass(move_line)(7, 2) + self.account_number = move_line.payment_mode_id.bank_id.acc_number + self.branch_number = move_line.payment_mode_id.bank_id.bra_number + Boleto.__init__(self, move_line, nosso_numero) + self.boleto.nosso_numero = self.nosso_numero + + +class BoletoBarisul(Boleto): + + def __init__(self, move_line, nosso_numero): + self.boleto = Boleto.getBoletoClass(move_line)() + self.account_number = move_line.payment_mode_id.bank_id.acc_number + self.branch_number = move_line.payment_mode_id.bank_id.bra_number + Boleto.__init__(self, move_line, nosso_numero) + self.boleto.nosso_numero = self.nosso_numero + + +class BoletoBradesco(Boleto): + + def __init__(self, move_line, nosso_numero): + self.boleto = Boleto.getBoletoClass(move_line)() + self.account_number = move_line.payment_mode_id.bank_id.acc_number + self.branch_number = move_line.payment_mode_id.bank_id.bra_number + # bank specific + self.account_digit = move_line.payment_mode_id.bank_id.acc_number_dig + self.branch_digit = move_line.payment_mode_id.bank_id.bra_number_dig + # end bank specific + Boleto.__init__(self, move_line, nosso_numero) + self.boleto.nosso_numero = self.nosso_numero + + +class BoletoCaixa(Boleto): + + def __init__(self, move_line, nosso_numero): + self.boleto = Boleto.getBoletoClass(move_line)() + self.account_number = move_line.payment_mode_id.bank_id.acc_number + self.branch_number = move_line.payment_mode_id.bank_id.bra_number + # bank specific + self.account_digit = move_line.payment_mode_id.bank_id.acc_number_dig + # end bank specific + Boleto.__init__(self, move_line, nosso_numero) + self.boleto.nosso_numero = self.nosso_numero + + +class BoletoHsbc(Boleto): + + def __init__(self, move_line, nosso_numero): + self.boleto = Boleto.getBoletoClass(move_line)() + self.account_number = move_line.payment_mode_id.bank_id.acc_number + self.branch_number = move_line.payment_mode_id.bank_id.bra_number + Boleto.__init__(self, move_line, nosso_numero) + self.boleto.nosso_numero = self.nosso_numero + + +class BoletoItau157(Boleto): + + def __init__(self, move_line, nosso_numero): + self.boleto = Boleto.getBoletoClass(move_line)() + self.account_number = move_line.payment_mode_id.bank_id.acc_number + self.branch_number = move_line.payment_mode_id.bank_id.bra_number + Boleto.__init__(self, move_line, nosso_numero) + self.boleto.nosso_numero = self.nosso_numero + + +class BoletoItau(Boleto): + + def __init__(self, move_line, nosso_numero): + self.boleto = Boleto.getBoletoClass(move_line)() + self.account_number = move_line.payment_mode_id.bank_id.acc_number + self.branch_number = move_line.payment_mode_id.bank_id.bra_number + Boleto.__init__(self, move_line, nosso_numero) + self.boleto.nosso_numero = self.nosso_numero + + +class BoletoReal(Boleto): + + def __init__(self, move_line, nosso_numero): + self.boleto = Boleto.getBoletoClass(move_line)() + self.account_number = move_line.payment_mode_id.bank_id.acc_number + self.branch_number = move_line.payment_mode_id.bank_id.bra_number + Boleto.__init__(self, move_line, nosso_numero) + self.boleto.nosso_numero = self.nosso_numero + + +class BoletoSantander101(Boleto): + + def __init__(self, move_line, nosso_numero): + self.boleto = Boleto.getBoletoClass(move_line)() + self.account_number = move_line.payment_mode_id.bank_id.acc_number + self.branch_number = move_line.payment_mode_id.bank_id.bra_number + Boleto.__init__(self, move_line, nosso_numero) + self.boleto.ios = '0' + self.boleto.nosso_numero = self.nosso_numero + + +class BoletoStatander101201(Boleto): + + def __init__(self, move_line, nosso_numero): + self.boleto = Boleto.getBoletoClass(move_line)() + self.account_number = move_line.payment_mode_id.bank_id.acc_number + self.branch_number = move_line.payment_mode_id.bank_id.bra_number + Boleto.__init__(self, move_line, nosso_numero) + self.boleto.ios = '0' + self.boleto.nosso_numero = self.nosso_numero + + +class BoletoCaixaSigcb(Boleto): + + def __init__(self, move_line, nosso_numero): + from pyboleto.bank.caixa_sigcb import BoletoCaixaSigcb + self.boleto = BoletoCaixaSigcb() + self.account_number = move_line.payment_mode_id.bank_id.acc_number + self.branch_number = move_line.payment_mode_id.bank_id.bra_number + # bank specific + self.account_digit = move_line.payment_mode_id.bank_id.acc_number_dig + # end bank specific + Boleto.__init__(self, move_line, nosso_numero) + self.boleto.nosso_numero = self.nosso_numero + + +class BoletoSicredi(Boleto): + + def __init__(self, move_line, nosso_numero): + self.boleto = Boleto.getBoletoClass(move_line)() + self.account_number = move_line.payment_mode_id.bank_id.acc_number + self.branch_number = move_line.payment_mode_id.bank_id.bra_number + Boleto.__init__(self, move_line, nosso_numero) + self.boleto.nosso_numero = self.nosso_numero + + +dict_boleto = { + '1': (BoletoBB, 'Banco do Brasil 18'), + '2': (BoletoBarisul, 'Barisul x'), + '3': (BoletoBradesco, 'Bradesco 06, 03'), + '4': (BoletoCaixa, 'Caixa Economica SR'), + '5': (BoletoHsbc, 'HSBC CNR CSB'), + '6': (BoletoItau157, 'Itau 157'), + '7': (BoletoItau, 'Itau 175, 174, 178, 104, 109'), + '8': (BoletoReal, 'Real 57'), + '9': (BoletoSantander101, 'Santander 102'), + '10': (BoletoStatander101201, 'Santander 101, 201'), + '11': (BoletoCaixaSigcb, 'Caixa Sigcb'), + '12': (BoletoSicredi, 'Sicredi'), +} + + +def getBoletoSelection(): + list = [] + for i in dict_boleto: + list.append((i, dict_boleto[i][1])) + return list diff --git a/l10n_br_financial_payment_order/febraban/cnab.py b/l10n_br_financial_payment_order/febraban/cnab.py new file mode 100644 index 0000000..2a384e4 --- /dev/null +++ b/l10n_br_financial_payment_order/febraban/cnab.py @@ -0,0 +1,51 @@ +# coding: utf-8 +# ########################################################################### +# +# Author: Luis Felipe Mileo +# Fernando Marcato Rodrigues +# Daniel Sadamo Hirayama +# Copyright 2015 KMEE - www.kmee.com.br +# +# 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 . +# +############################################################################## +# TODO: implement abc factory? + +from __future__ import division, print_function, unicode_literals + + +class Cnab(object): + + def __init__(self): + pass + + @staticmethod + def get_cnab(bank, cnab_type='240'): + if cnab_type == '240': + from .cnab_240.cnab_240 import Cnab240 + return Cnab240.get_bank(bank) + elif cnab_type == '400': + from .cnab_400.cnab_400 import Cnab400 + return Cnab400.get_bank(bank) + elif cnab_type == '500': + from .pag_for.pag_for500 import PagFor500 + return PagFor500.get_bank(bank) + else: + return False + + def remessa(self, order): + return False + + def retorno(self, cnab_file): + return object diff --git a/l10n_br_financial_payment_order/febraban/cnab_240/__init__.py b/l10n_br_financial_payment_order/febraban/cnab_240/__init__.py new file mode 100644 index 0000000..9a4bbb7 --- /dev/null +++ b/l10n_br_financial_payment_order/febraban/cnab_240/__init__.py @@ -0,0 +1,20 @@ +# coding: utf-8 +# ########################################################################### +# +# Author: Luis Felipe Mileo +# Copyright 2015 KMEE - www.kmee.com.br +# +# 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 . +# +############################################################################## diff --git a/l10n_br_financial_payment_order/febraban/cnab_240/bancos/__init__.py b/l10n_br_financial_payment_order/febraban/cnab_240/bancos/__init__.py new file mode 100644 index 0000000..0104e25 --- /dev/null +++ b/l10n_br_financial_payment_order/febraban/cnab_240/bancos/__init__.py @@ -0,0 +1,22 @@ +# coding: utf-8 +# ########################################################################### +# +# Author: Luis Felipe Mileo +# Fernando Marcato Rodrigues +# Daniel Sadamo Hirayama +# Copyright 2015 KMEE - www.kmee.com.br +# +# 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 . +# +############################################################################## diff --git a/l10n_br_financial_payment_order/febraban/cnab_240/bancos/bb.py b/l10n_br_financial_payment_order/febraban/cnab_240/bancos/bb.py new file mode 100644 index 0000000..5580359 --- /dev/null +++ b/l10n_br_financial_payment_order/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_financial_payment_order/febraban/cnab_240/bancos/bradesco.py b/l10n_br_financial_payment_order/febraban/cnab_240/bancos/bradesco.py new file mode 100644 index 0000000..3dea8ad --- /dev/null +++ b/l10n_br_financial_payment_order/febraban/cnab_240/bancos/bradesco.py @@ -0,0 +1,84 @@ +# coding: utf-8 +# ########################################################################### +# +# Author: Luis Felipe Mileo +# Fernando Marcato Rodrigues +# Daniel Sadamo Hirayama +# Copyright 2015 KMEE - www.kmee.com.br +# +# 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 . +# +############################################################################## + + +import re +import string +from decimal import Decimal + +from ..cnab_240 import Cnab240 + + +class Bradesco240(Cnab240): + + def __init__(self): + super(Cnab240, self).__init__() + from cnab240.bancos import bradesco + self.bank = bradesco + + def _prepare_header(self): + """ + + :param order: + :return: + """ + + vals = super(Bradesco240, self)._prepare_header() + vals['servico_servico'] = 1 + return vals + + def _prepare_cobranca(self, line): + """ + + :param line: + :return: + """ + vals = super(Bradesco240, 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_financial_payment_order/febraban/cnab_240/bancos/cef.py b/l10n_br_financial_payment_order/febraban/cnab_240/bancos/cef.py new file mode 100644 index 0000000..14193fe --- /dev/null +++ b/l10n_br_financial_payment_order/febraban/cnab_240/bancos/cef.py @@ -0,0 +1,108 @@ +# coding: utf-8 +# ########################################################################### +# +# Author: Luis Felipe Mileo +# Fernando Marcato Rodrigues +# Daniel Sadamo Hirayama +# Copyright 2015 KMEE - www.kmee.com.br +# +# 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 . +# +############################################################################## + +import re +import string +from decimal import Decimal + +from ..cnab_240 import Cnab240 + + +class Cef240(Cnab240): + + def __init__(self): + super(Cnab240, self).__init__() + from cnab240.bancos import cef + self.bank = cef + + def _prepare_header(self): + """ + + :return: + """ + vals = super(Cef240, self)._prepare_header() + vals['cedente_dv_ag_cc'] = unicode(str( + vals['cedente_dv_ag_cc']), "utf-8") + vals['cedente_agencia_dv'] = unicode(str( + vals['cedente_agencia_dv']), "utf-8") + # TODO: adicionar campo para preencher o codigo do cedente no + # cadastro da conta bancária + vals['cedente_codigo_codCedente'] = 6088 + vals['nome_do_banco'] = u'CAIXA ECONOMICA FEDERAL' + # Não pode pegar comentário da payment_line. + vals['reservado_cedente_campo23'] = u'REMESSA TESTE' + # reservado_banco_campo22 não é required. Código atualizado na + # biblioteca cnab240 + vals['data_credito_hd_lote'] = 15052015 + + return vals + + def _prepare_cobranca(self, line): + """ + + :param line: + :return: + """ + vals = super(Cef240, self)._prepare_cobranca(line) + + carteira, nosso_numero, digito = self.nosso_numero( + line.move_line_id.transaction_ref) + + vals['cedente_dv_ag_cc'] = unicode(str( + vals['cedente_dv_ag_cc']), "utf-8") + # Informar o Número do Documento - Seu Número (mesmo das posições + # 63-73 do Segmento P) + vals['identificacao_titulo'] = unicode(str( + vals['numero_documento']), "utf-8") + # TODO: campo 27.3P CEF. Código do juros de mora + vals['juros_cod_mora'] = 3 + vals['carteira_numero'] = int(carteira) + vals['nosso_numero'] = int(nosso_numero) + vals['nosso_numero_dv'] = int(digito) + vals['prazo_baixa'] = unicode(str( + vals['prazo_baixa']), "utf-8") + + # Precisam estar preenchidos + # Header lote + # vals['servico_operacao'] = u'R' + # vals['servico_servico'] = 1 + vals['cedente_conta_dv'] = unicode(str( + vals['cedente_conta_dv']), "utf-8") + vals['cedente_codigo_codCedente'] = 6088 + vals['data_credito_hd_lote'] = 15052015 + + vals['desconto1_cod'] = 3 + vals['desconto1_data'] = 0 + vals['desconto1_percentual'] = Decimal('0.00') + vals['valor_iof'] = Decimal('0.00') + + 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 = 14 + nosso_numero = re.sub( + '[%s]' % re.escape(string.punctuation), '', format[3:-1] or '') + return carteira, nosso_numero, digito diff --git a/l10n_br_financial_payment_order/febraban/cnab_240/bancos/itau.py b/l10n_br_financial_payment_order/febraban/cnab_240/bancos/itau.py new file mode 100644 index 0000000..84c5706 --- /dev/null +++ b/l10n_br_financial_payment_order/febraban/cnab_240/bancos/itau.py @@ -0,0 +1,83 @@ +# coding: utf-8 +# ########################################################################### +# +# Author: Luis Felipe Mileo +# Fernando Marcato Rodrigues +# Daniel Sadamo Hirayama +# Copyright 2015 KMEE - www.kmee.com.br +# +# 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 . +# +############################################################################## + +import re +import string + +from ..cnab_240 import Cnab240 + + +class Itau240(Cnab240): + """ + + """ + + def __init__(self): + """ + + :return: + """ + super(Cnab240, self).__init__() + from cnab240.bancos import itau + self.bank = itau + + def _prepare_header(self): + """ + + :param order: + :return: + """ + vals = super(Itau240, self)._prepare_header() + vals['cedente_dv_ag_cc'] = int( + vals['cedente_dv_ag_cc']) + vals['cedente_agencia_dv'] = int( + vals['cedente_agencia_dv']), + return vals + + def _prepare_cobranca(self, line): + """ + + :param line: + :return: + """ + vals = super(Itau240, self)._prepare_cobranca(line) + + carteira, nosso_numero, digito = self.nosso_numero( + line.move_line_id.transaction_ref) + + vals['cedente_dv_ag_cc'] = int( + vals['cedente_dv_ag_cc']) + vals['carteira_numero'] = int(carteira) + vals['nosso_numero'] = int(nosso_numero) + vals['nosso_numero_dv'] = int(digito) + + 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 diff --git a/l10n_br_financial_payment_order/febraban/cnab_240/bancos/santander.py b/l10n_br_financial_payment_order/febraban/cnab_240/bancos/santander.py new file mode 100644 index 0000000..cd8a3a5 --- /dev/null +++ b/l10n_br_financial_payment_order/febraban/cnab_240/bancos/santander.py @@ -0,0 +1,59 @@ +# coding: utf-8 +# ########################################################################### +# +# Author: Luis Felipe Mileo +# Fernando Marcato Rodrigues +# Daniel Sadamo Hirayama +# Gustavo Lepri +# Copyright 2015 KMEE - www.kmee.com.br +# +# 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 . +# +############################################################################## + +from ..cnab_240 import Cnab240 + + +class Santander240(Cnab240): + """ + + """ + + def __init__(self): + """ + + :return: + """ + super(Cnab240, self).__init__() + from cnab240.bancos import santander + self.bank = santander + + def _prepare_header(self): + """ + + :param order: + :return: + """ + vals = super(Santander240, self)._prepare_header() + del vals['arquivo_hora_de_geracao'] + return vals + + def _prepare_cobranca(self, line): + """ + + :param line: + :return: + """ + vals = super(Santander240, self)._prepare_cobranca(line) + return vals diff --git a/l10n_br_financial_payment_order/febraban/cnab_240/cnab_240.py b/l10n_br_financial_payment_order/febraban/cnab_240/cnab_240.py new file mode 100644 index 0000000..b67d6b8 --- /dev/null +++ b/l10n_br_financial_payment_order/febraban/cnab_240/cnab_240.py @@ -0,0 +1,564 @@ +# coding: utf-8 +# ########################################################################### +# +# Author: Luis Felipe Mileo +# Fernando Marcato Rodrigues +# Daniel Sadamo Hirayama +# Copyright 2015 KMEE - www.kmee.com.br +# +# 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 . +# +############################################################################## + +from __future__ import division, print_function, unicode_literals + +import datetime +import logging +import re +import string +import time +import unicodedata +from decimal import Decimal + +from openerp.addons.l10n_br_base.tools.misc import punctuation_rm + +from ..cnab import Cnab + +_logger = logging.getLogger(__name__) +try: + from cnab240.tipos import Arquivo, Lote +except ImportError as err: + _logger.debug = err + + +class Cnab240(Cnab): + """ + CNAB240 + """ + + def __init__(self): + super(Cnab, self).__init__() + + @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 + elif bank == '237': + from .bancos.bradesco import Bradesco240 + return Bradesco240 + elif bank == '104': + from .bancos.cef import Cef240 + return Cef240 + elif bank == '033': + from .bancos.santander import Santander240 + return Santander240 + elif bank == '001': + from .bancos.bb import BB240 + return BB240 + else: + return Cnab240 + + def get_inscricao_tipo(self, partner_id): + # TODO: Implementar codigo para PIS/PASEP + if partner_id.is_company: + return 2 + else: + return 1 + + def _prepare_header(self): + """ + Preparar o header do arquivo do CNAB + :return: dict - Header do arquivo + """ + 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(), + # 19.0 TODO: Número sequencial de arquivo + 'arquivo_sequencia': int(self.get_file_numeration()), + # 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 + } + + return header_arquivo + + 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 + + header_arquivo_lote = { + + # 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 get_file_numeration(self): + # Função para retornar a numeração sequencial do arquivo + return 1 + + def _prepare_cobranca(self, line): + """ + :param line: + :return: + """ + # prefixo, sufixo = self.cep(line.partner_id.zip) + + aceite = u'N' + if not self.order.mode.boleto_aceite == 'S': + aceite = u'A' + + # Código agencia do cedente + # cedente_agencia = cedente_agencia + + # Dígito verificador da agência do cedente + # cedente_agencia_conta_dv = cedente_agencia_dv + + # Código da conta corrente do cedente + # cedente_conta = cedente_conta + + # Dígito verificador da conta corrente do cedente + # cedente_conta_dv = cedente_conta_dv + + # Dígito verificador de agencia e conta + # Era cedente_agencia_conta_dv agora é cedente_dv_ag_cc + + return { + 'controle_banco': int(self.order.mode.bank_id.bank_bic), + '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, + 'identificacao_titulo': u'0000000', # TODO + 'identificacao_titulo_banco': u'0000000', # TODO + 'identificacao_titulo_empresa': line.move_line_id.move_id.name, + 'numero_documento': line.name, + 'vencimento_titulo': self.format_date( + 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), + 'aceite_titulo': aceite, + 'data_emissao_titulo': self.format_date( + line.ml_date_created), + # TODO: trazer taxa de juros do Odoo. Depende do valor do 27.3P + # CEF/FEBRABAN e Itaú não tem. + 'juros_mora_data': self.format_date( + line.ml_maturity_date), + 'juros_mora_taxa_dia': Decimal('0.00'), + 'valor_abatimento': Decimal('0.00'), + 'sacado_inscricao_tipo': int( + 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': 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), + 'prazo_protesto': int(self.order.mode.boleto_protesto_prazo), + 'codigo_baixa': 2, + 'prazo_baixa': 0, # De 5 a 120 dias. + 'controlecob_data_gravacao': self.data_hoje(), + 'cobranca_carteira': int(self.order.mode.boleto_carteira), + } + + 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 = { + + # 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 + """ + # 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()) + + 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')) + + remessa = unicode(self.arquivo) + 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_financial_payment_order/febraban/cnab_400/__init__.py b/l10n_br_financial_payment_order/febraban/cnab_400/__init__.py new file mode 100644 index 0000000..a0d3830 --- /dev/null +++ b/l10n_br_financial_payment_order/febraban/cnab_400/__init__.py @@ -0,0 +1,19 @@ +# coding: utf-8 +# ########################################################################### +# +# Ainda não implementado! +# +# 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 . +# +############################################################################## diff --git a/l10n_br_financial_payment_order/febraban/cnab_400/bancos/__init__.py b/l10n_br_financial_payment_order/febraban/cnab_400/bancos/__init__.py new file mode 100644 index 0000000..cce59cd --- /dev/null +++ b/l10n_br_financial_payment_order/febraban/cnab_400/bancos/__init__.py @@ -0,0 +1,20 @@ +# coding: utf-8 +# ########################################################################### +# +# Author: Fernando Marcato Rodrigues +# Copyright 2015 KMEE - www.kmee.com.br +# +# 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 . +# +############################################################################## diff --git a/l10n_br_financial_payment_order/febraban/cnab_400/bancos/bradesco.py b/l10n_br_financial_payment_order/febraban/cnab_400/bancos/bradesco.py new file mode 100644 index 0000000..fa3cf04 --- /dev/null +++ b/l10n_br_financial_payment_order/febraban/cnab_400/bancos/bradesco.py @@ -0,0 +1,113 @@ +# coding: utf-8 +# ########################################################################### +# +# Author: Luis Felipe Mileo +# Fernando Marcato Rodrigues +# Daniel Sadamo Hirayama +# Copyright 2015 KMEE - www.kmee.com.br +# +# 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 . +# +############################################################################## + + +import re +import string +from decimal import Decimal + +from ..cnab_400 import Cnab400 + + +class Bradesco400(Cnab400): + + def __init__(self): + super(Cnab400, self).__init__() + from cnab240.bancos import bradesco_cobranca_400 + self.bank = bradesco_cobranca_400 + self.controle_linha = 2 + + def _prepare_header(self): + """ + + :param order: + :return: + """ + + vals = super(Bradesco400, self)._prepare_header() + vals['servico_servico'] = 1 + return vals + + def _prepare_cobranca(self, line): + """ + + :param line: + :return: + """ + vals = super(Bradesco400, 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") + + vals['sacado_cc_dv'] = u'0' + vals['identificacao_empresa_beneficiaria_banco'] = \ + self.retorna_id_empr_benef() + vals['digito_conferencia_numero_bancario'] = u'0' + vals['condicao_emissao_papeleta'] = 1 + + vals['indicador_rateio_credito'] = u"" + self.controle_linha += 1 + + return vals + + 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 retorna_id_empr_benef(self): + dig_cart = 3 + dig_ag = 5 + dig_conta = 7 + + carteira = self.adiciona_digitos( + self.order.mode.boleto_carteira, dig_cart) + agencia = self.adiciona_digitos( + self.order.mode.bank_id.bra_number, dig_ag) + conta = self.adiciona_digitos( + self.order.mode.bank_id.acc_number, dig_conta) + + ident = u'0' + (carteira) + (agencia) + (conta) + \ + (self.order.mode.bank_id.acc_number_dig) + return ident + + def adiciona_digitos(self, campo, num_digitos): + chars_faltantes = num_digitos - len(campo) + return (u'0' * chars_faltantes) + campo + + +def str_to_unicode(inp_str): + inp_str = unicode(inp_str, "utf-8") + return inp_str diff --git a/l10n_br_financial_payment_order/febraban/cnab_400/cnab_400.py b/l10n_br_financial_payment_order/febraban/cnab_400/cnab_400.py new file mode 100644 index 0000000..cb1e3d8 --- /dev/null +++ b/l10n_br_financial_payment_order/febraban/cnab_400/cnab_400.py @@ -0,0 +1,375 @@ +# coding: utf-8 +# ########################################################################### +# +# Author: Fernando Marcato Rodrigues +# Copyright 2015 KMEE - www.kmee.com.br +# +# 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 . +# +############################################################################## + +import datetime +import logging +import re +import string +import time +import unicodedata +from decimal import Decimal + +from openerp.addons.l10n_br_base.tools.misc import punctuation_rm + +from ..cnab import Cnab + +_logger = logging.getLogger(__name__) +try: + from cnab240.tipos import ArquivoCobranca400 +except ImportError as err: + _logger.debug = (err) + +IDENTIFICACAO_DA_OCORRENCIA = [ + ('01', u'Remessa'), + ('02', u'Pedido de baixa'), + ('03', u'Pedido de Protesto Falimentar'), + ('04', u'Concessão de abatimento'), + ('05', u'Cancelamento de abatimento concedido'), + ('06', u'Alteração de vencimento'), + ('07', u'Alteração do controle do participante'), + ('08', u'Alteração de seu número'), + ('09', u'Pedido de protesto'), + ('18', u'Sustar protesto e baixar Título'), + ('19', u'Sustar protesto e manter em carteira'), + ('22', u'Transferência Cessão crédito ID. Prod.10'), + ('23', u'Transferência entre Carteiras'), + ('24', u'Dev. Transferência entre Carteiras'), + ('31', u'Alteração de outros dados'), + ('45', u'Pedido de Negativação (NOVO)'), + ('46', u'Excluir Negativação com baixa (NOVO)'), + ('47', u'Excluir negativação e manter pendente (NOVO)'), + ('68', u'Acerto nos dados do rateio de Crédito'), + ('69', u'Cancelamento do rateio de crédito'), +] + +ESPECIE_DE_TITULO = [ + ('01', u'Duplicata'), + ('02', u'Nota Promissória'), + ('03', u'Nota de Seguro'), + ('04', u'Cobrança Seriada'), + ('05', u'Recibo'), + ('10', u'Letras de Câmbio'), + ('11', u'Nota de Débito'), + ('12', u'Duplicata de Serv'), + ('30', u'Boleto de Proposta'), + ('99', u'Outros'), +] + +# Essas instruções deverão ser enviadas no Arquivo-Remessa, quando da +# entrada, desde que código de ocorrência na posição 109 a 110 do registro +# de transação, seja “01”, para as instruções de protesto/negativação, o +# CNPJ / CPF e o endereço do Pagador deverão ser informados corretamente +LISTA_PRIMEIRA_INSTRUCAO = [ + ('05', u'Protesto Falimentar'), + ('06', u'Protestar'), + ('07', u'Negativar'), + ('18', u'Decurso de prazo'), + + ('08', u'Não cobrar juros de mora'), + ('09', u'Não receber após o vencimento'), + ('10', u'Multas de 10% após o 4o dia do Vencimento'), + ('11', u'Não receber após o 8o dia do vencimento.'), + ('12', u'Cobrar encargos após o 5o dia do vencimento'), + ('13', u'Cobrar encargos após o 10o dia do vencimento'), + ('14', u'Cobrar encargos após o 15o dia do vencimento'), + ('15', u'Conceder desconto mesmo se pago após o vencimento'), +] + + +class Cnab400(Cnab): + + def __init__(self): + super(Cnab, self).__init__() + + @staticmethod + def get_bank(bank): + if bank == '237': + from .bancos.bradesco import Bradesco400 + return Bradesco400 + else: + return Cnab400 + + @property + def inscricao_tipo(self): + # TODO: Implementar codigo para PIS/PASEP + if self.order.company_id.partner_id.is_company: + return 2 + else: + return 1 + + def _prepare_header(self): + """ + + :param: + :return: + """ + return { + 'controle_banco': int(self.order.mode.bank_id.bank_bic), + 'arquivo_data_de_geracao': self.data_hoje(), + 'arquivo_hora_de_geracao': self.hora_agora(), + # 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, + 'arquivo_codigo': 1, # Remessa/Retorno + 'servico_operacao': u'R', + 'nome_banco': unicode(self.order.mode.bank_id.bank_name), + 'codigo_empresa': int(self.order.mode.boleto_convenio), + } + + def get_file_numeration(self): + numero = self.order.get_next_number() + if not numero: + numero = 1 + return numero + + 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 cep(self, format): + sulfixo = format[-3:] + prefixo = format[:5] + return prefixo, sulfixo + + def sacado_inscricao_tipo(self, partner_id): + # TODO: Implementar codigo para PIS/PASEP + if partner_id.is_company: + return 2 + else: + return 1 + + def rmchar(self, format): + return re.sub('[%s]' % re.escape(string.punctuation), '', + format or '') + + def codificar(self, texto): + return texto.encode('utf-8') + + def _prepare_cobranca(self, line): + """ + :param line: + :return: + """ + prefixo, sulfixo = self.cep(line.partner_id.zip) + + aceite = u'N' + if not self.order.mode.boleto_aceite == 'S': + aceite = u'A' + + codigo_protesto = 0 + dias_protestar = 0 + if self.order.mode.boleto_protesto == '3' \ + or self.order.mode.boleto_protesto == '0': + codigo_protesto = 0 + dias_protestar = 0 + elif self.order.mode.boleto_protesto == '1' \ + or self.order.mode.boleto_protesto == '2': + codigo_protesto = 6 + if (int(self.order.mode.boleto_protesto_prazo)) < 5: + dias_protestar = 5 + else: + dias_protestar = int(self.order.mode.boleto_protesto_prazo) + + sacado_endereco = self.retorna_endereco(line.partner_id.id) + + # Código agencia do cedente + # cedente_agencia = cedente_agencia + + # Dígito verificador da agência do cedente + # cedente_agencia_conta_dv = cedente_agencia_dv + + # Código da conta corrente do cedente + # cedente_conta = cedente_conta + + # Dígito verificador da conta corrente do cedente + # cedente_conta_dv = cedente_conta_dv + + # Dígito verificador de agencia e conta + # Era cedente_agencia_conta_dv agora é cedente_dv_ag_cc + + return { + + 'percentual_multa': Decimal('0.00'), + 'valor_desconto': Decimal('0.00'), + 'valor_abatimento_concedido_cancelado': Decimal('0.00'), + 'primeira_instrucao': codigo_protesto, + 'segunda_instrucao': dias_protestar, + 'sacado_cep': int(prefixo), + 'sacado_cep_sufixo': int(sulfixo), + 'sacador_avalista': self.order.mode.comunicacao_2, + # 'sacador_avalista': u'Protestar após 5 dias', + 'num_seq_registro': self.controle_linha, + + 'controle_banco': int(self.order.mode.bank_id.bank_bic), + '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, + 'identificacao_titulo': u'0000000', # TODO + 'identificacao_titulo_banco': u'0000000', # TODO + 'identificacao_titulo_empresa': line.move_line_id.move_id.name, + + 'vencimento_titulo': self.format_date( + line.ml_maturity_date), + 'valor_titulo': Decimal(str(line.amount_currency)).quantize( + Decimal('1.00')), + # 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), + 'aceite_titulo': aceite, + 'data_emissao_titulo': self.format_date( + line.ml_date_created), + # TODO: trazer taxa de juros do Odoo. Depende do valor do 27.3P + # CEF/FEBRABAN e Itaú não tem. + 'juros_mora_data': self.format_date( + line.ml_maturity_date), + + # 'juros_mora_taxa_dia': Decimal('0.20'), + 'juros_mora_taxa_dia': self.calcula_valor_juros_dia( + line.amount_currency, line.percent_interest), + + 'valor_abatimento': Decimal('0.00'), + 'sacado_inscricao_tipo': int( + self.sacado_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 + + # ' ' + str(line.partner_id.number) + # ), + + 'sacado_endereco': sacado_endereco, + + 'sacado_bairro': line.partner_id.district, + 'sacado_cidade': line.partner_id.l10n_br_city_id.name, + 'sacado_uf': line.partner_id.state_id.code, + 'codigo_baixa': 2, + 'prazo_baixa': 0, # De 5 a 120 dias. + 'controlecob_data_gravacao': self.data_hoje(), + 'cobranca_carteira': int(self.order.mode.boleto_carteira), + + 'primeira_mensagem': u'', + # Trazer da nova tela do payment_mode + 'identificacao_ocorrencia': 1, + + # numero fatura esta copiando para communication + 'numero_documento': self.adiciona_digitos_num_doc( + line.communication), + # 'numero_documento': str(line.move_line_id.invoice.number), + + } + + def remessa(self, order): + """ + + :param order: + :return: + """ + self.order = order + self.arquivo = ArquivoCobranca400(self.bank, **self._prepare_header()) + for line in order.line_ids: + self.arquivo.incluir_cobranca(**self._prepare_cobranca(line)) + self.arquivo.trailer.num_seq_registro = self.controle_linha + + remessa = unicode(self.arquivo) + return unicodedata.normalize( + 'NFKD', remessa).encode('ascii', 'ignore') + + def data_hoje(self): + return (int(time.strftime("%d%m%y"))) + + def hora_agora(self): + return (int(time.strftime("%H%M%S"))) + + def calcula_valor_juros_dia(self, total_titulo, percent_juros): + valor_juros = 0 + valor_juros = (total_titulo * (percent_juros / 100)) + return (Decimal(valor_juros).quantize(Decimal('1.00'))) + + def adiciona_digitos_num_doc(self, campo): + num_digitos = 10 + campo = str(campo) + chars_faltantes = num_digitos - len(campo) + return (u' ' * chars_faltantes) + campo + + # @api.multi + def retorna_endereco(self, id_parceiro): + # self.ensure_one() + # workaround to get env + res_partner_model = self.order.env['res.partner'] + res_partner_end_cobranca = res_partner_model.search( + [('parent_id', '=', id_parceiro), ('type', '=', 'cnab_cobranca')], + limit=1) + if res_partner_end_cobranca: + str_endereco = self.monta_endereco(res_partner_end_cobranca) + else: + res_partner_end_cobranca = res_partner_model.search( + [('id', '=', id_parceiro)] + ) + str_endereco = self.monta_endereco(res_partner_end_cobranca) + # Essa abordagem substitui caracteres especiais por '?' + # str_endereco = / + # unicode(str_endereco.encode("ascii", errors="replace")) + + # Substitui sinal de grau por espaço + str_endereco = str_endereco.replace(u"\xb0", u" ") + + return str_endereco + + def monta_endereco(self, partner_item): + + street = self.check_address_item_filled(partner_item.street) + number = self.check_address_item_filled(partner_item.number) + complemento = self.check_address_item_filled(partner_item.street2) + distrito = self.check_address_item_filled(partner_item.district) + + str_endereco = ( + street + + ' ' + + number + + ' ' + + complemento + + ' ' + + distrito + # + ' ' + + # partner_item.l10n_br_city_id.name + + # ' ' + partner_item.state_id.name + ) + return str_endereco + + def check_address_item_filled(self, item): + if not item: + return ('') + else: + return item diff --git a/l10n_br_financial_payment_order/febraban/pag_for/__init__.py b/l10n_br_financial_payment_order/febraban/pag_for/__init__.py new file mode 100644 index 0000000..dec8c03 --- /dev/null +++ b/l10n_br_financial_payment_order/febraban/pag_for/__init__.py @@ -0,0 +1,24 @@ +# coding: utf-8 +# ########################################################################### +# +# Author: Luis Felipe Mileo +# Fernando Marcato Rodrigues +# Daniel Sadamo Hirayama +# Copyright 2015 KMEE - www.kmee.com.br +# +# 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 . +# +############################################################################## + +from . import pag_for500 diff --git a/l10n_br_financial_payment_order/febraban/pag_for/bancos/__init__.py b/l10n_br_financial_payment_order/febraban/pag_for/bancos/__init__.py new file mode 100644 index 0000000..0104e25 --- /dev/null +++ b/l10n_br_financial_payment_order/febraban/pag_for/bancos/__init__.py @@ -0,0 +1,22 @@ +# coding: utf-8 +# ########################################################################### +# +# Author: Luis Felipe Mileo +# Fernando Marcato Rodrigues +# Daniel Sadamo Hirayama +# Copyright 2015 KMEE - www.kmee.com.br +# +# 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 . +# +############################################################################## diff --git a/l10n_br_financial_payment_order/febraban/pag_for/bancos/bradesco.py b/l10n_br_financial_payment_order/febraban/pag_for/bancos/bradesco.py new file mode 100644 index 0000000..1edd242 --- /dev/null +++ b/l10n_br_financial_payment_order/febraban/pag_for/bancos/bradesco.py @@ -0,0 +1,75 @@ +# coding: utf-8 +# ########################################################################### +# +# Author: Luis Felipe Mileo +# Fernando Marcato Rodrigues +# Copyright 2015 KMEE - www.kmee.com.br +# +# 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 . +# +############################################################################## + + +import re +import string + +from ..pag_for500 import PagFor500 + + +class BradescoPagFor(PagFor500): + + def __init__(self): + super(PagFor500, self).__init__() + from cnab240.bancos import bradescoPagFor + self.bank = bradescoPagFor + self.controle_linha = 2 + + def _prepare_header(self): + """ + + :param order: + :return: + """ + vals = super(BradescoPagFor, self)._prepare_header() + vals['codigo_comunicacao'] = int(self.order.mode.boleto_convenio) + return vals + + def _prepare_cobranca(self, line, vals): + """ + + :param line: + :return: + """ + 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( + vals['vencimento_titulo']) + self.controle_linha += 1 + + 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 muda_campos_data(self, campo): + campo = str(campo) + campo = campo[-4:] + campo[2:4] + campo[:2] + return int(campo) diff --git a/l10n_br_financial_payment_order/febraban/pag_for/pag_for500.py b/l10n_br_financial_payment_order/febraban/pag_for/pag_for500.py new file mode 100644 index 0000000..3666832 --- /dev/null +++ b/l10n_br_financial_payment_order/febraban/pag_for/pag_for500.py @@ -0,0 +1,575 @@ +# coding: utf-8 +# ########################################################################### +# +# Author: Luis Felipe Mileo +# Fernando Marcato Rodrigues +# Copyright 2015 KMEE - www.kmee.com.br +# +# 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 . +# +############################################################################## + +import datetime +import logging +import re +import string +import time +import unicodedata +from decimal import Decimal + +from openerp import _ +from openerp.addons.l10n_br_base.tools.misc import punctuation_rm +from openerp.exceptions import Warning as UserError + +from ..cnab import Cnab + +_logger = logging.getLogger(__name__) +try: + from cnab240.tipos import Arquivo +except ImportError as err: + _logger.debug = (err) +try: + from pyboleto.data import BoletoData +except ImportError as err: + _logger.debug = (err) + +TIPO_CONTA_FORNECEDOR = [ + ('1', u'Conta corrente'), + ('2', u'Conta Poupança'), +] + +TIPO_DOCUMENTO = [ + ('01', u'Nota Fiscal/Fatura'), + ('02', u'Fatura'), + ('03', u'Nota Fiscal'), + ('01', u'Duplicata'), + ('01', u'Outros'), +] + +MODALIDADE = [ + ('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'), +] + +TIPO_MOVIMENTO = [ + ('0', u'Inclusão'), + ('5', u'Alteração'), + ('9', u'Exclusão'), +] + +CODIGO_MOVIMENTO = [ + ('00', u'Autoriza agendamento'), + ('25', u'Desautoriza Agendamento'), + ('50', u'Efetuar Alegçação'), +] + +TIPO_DOC = [ + ('C', u'Titularidade Diferente'), + ('D', u'Mesma Titularidade'), +] + +FINALIDADE_DOC_TED = [ + ('01', u'Crédito em Conta Corrente'), + ('02', u'Pagamento de Aluguel /Condomínios'), + ('03', u'Pagamento de Duplicatas/Títulos'), + ('04', u'Pagamento de Dividendos'), + ('05', u'Pagamento de Mensal. Escolares'), + ('06', u'Pagamento de Salário'), + ('07', u'Pagamento de Fornec/Honor.'), + ('08', u'Operações de Câmbio /Fundos /Bolsa de Valores'), + ('09', u'Repasse de Arrec./Pagto de Tributos'), + ('10', u'Transferência Internacional em Reais'), + ('11', u'DOC COMPE/TED para Poupança'), + ('12', u'DOC COMPE/TED para Depósito Judicial'), + ('13', u'Pensão Alimentícia'), + ('14', u'Restituição de Imposto de Renda'), + ('18', u'Operações Seguro Habit.', u'SFH'), + ('19', u'Operações do FDS', u'Caixa'), + ('20', u'Pagamento De Operação De Crédito'), + ('23', u'Taxa de Administração'), + ('27', u'Pagamento Acordo/Execução Judicial'), + ('28', u'Liquidação de Empréstimos Consignados'), + ('29', u'Pagamento de Bolsa Auxilio'), + ('30', u'Remuneração A Cooperado'), + ('31', u'Pagamento de Prebenda'), + ('33', u'Pagamento de Juros sobre Capital Próprio'), + ('34', u'Pagamento de Rendimentos ou Amortização s/ Cotas ' + u'e/ou Debêntures'), + ('35', u'Taxa De Serviço'), + ('37', u'Pagamento de Juros e/ou Amortização de Títulos ' + u'Depositados em Garantia.'), + ('38', u'Estorno Ou Restituição', u'Diversos'), + ('59', u'Restituição de Prêmios de Seguros'), + ('60', u'Pagamento de Indenização Sinistro Seguro'), + ('61', u'Pagamento de Premio de Co-Seguro'), + ('63', u'Pagamento de Indenização Sinistro Co-Seguro'), + ('64', u'Pagamento de Premio De Resseguro'), + ('65', u'Restituição de Premio De Resseguro'), + ('66', u'Pagamento de Indenização Sinistro Resseguro'), + ('67', u'Restituição Indenização Sinistro Resseguro'), + ('68', u'Pagamento de Despesas Com Sinistro'), + ('69', u'Pagamento de Inspeções/Vistorias Prévias'), + ('70', u'Pagamento de Resgate de Titulo de Capitalização'), + ('71', u'Pagamento de Sorteio de Titulo de Capitalização'), + ('72', u'Devolução Mensal de Titulo de Capitalização.'), + ('73', u'Restituição de Contribuição de Plano Previdenciário'), + ('74', u'Pagamento de Beneficio Previdenciário Pecúlio'), + ('75', u'Pagamento de Beneficio Previdenciário Pensão'), + ('76', u'Pagamento de Beneficio Previdenciário Aposentadoria'), + ('77', u'Pagamento de Resgate Previdenciário'), + ('78', u'Pagamento de Comissão de Corretagem'), + ('79', u'Pagamento de Transferências/Portabilidade de Reserva ' + u'Seguro/Previdência'), + ('80', u'Pagamento de Impostos'), + ('81', u'Pagamento de Serviços Públicos'), + ('82', u'Pagamento de Honorários'), + ('83', u'Pagamento de Corretoras'), + ('84', u'Repasse de Valores BNDES'), + ('85', u'Liquidação de Compromissos com BNDES'), + ('86', u'Compra e Venda de Ações'), + ('87', u'Contratos Referenciados em Ações ou Índices de Ações'), + ('88', u'Operação De Cambio'), + ('89', u'Pagamento de Boleto Bancário em Cartório'), + ('90', u'Pagamento de Tarifas pela Prestação de Serviços de Arrecadação' + u' de Convênios'), + ('91', u'Operações no Mercado de Renda Fixa e Variável com Utilização ' + u'de Intermediário'), + ('92', u'Operação de Câmbio Mercado Interbancário Instituições ' + u'sem Reservas Bancárias'), + ('93', u'Pagamento de Operações com Identificação de Destinatário Final'), + ('94', u'Ordem Bancaria do Tesouro - OBT'), + ('99', u'Outros'), +] + + +class PagFor500(Cnab): + """ + + """ + + def __init__(self): + super(Cnab, self).__init__() + + @staticmethod + def get_bank(bank): + if bank == '237': + from .bancos.bradesco import BradescoPagFor + return BradescoPagFor + else: + return PagFor500 + + @property + def inscricao_tipo(self): + # TODO: Implementar codigo para PIS/PASEP + if self.order.company_id.partner_id.is_company: + return 2 + else: + return 1 + + def _prepare_header(self): + """ + + :param: + :return: + """ + return { + 'arquivo_data_de_geracao': self.data_hoje_pag_for(), + 'arquivo_hora_de_geracao': self.hora_agora(), + # TODO: Número sequencial de arquivo + 'numero_remessa': int(self.get_file_numeration()), + 'cedente_inscricao_tipo': self.inscricao_tipo, + 'cnpj_cpf_base': int(punctuation_rm( + self.order.company_id.cnpj_cpf)[0:8]), + 'cnpj_cpf_filial': int(punctuation_rm( + self.order.company_id.cnpj_cpf)[9:12]), + 'sufixo_cnpj': int(punctuation_rm( + self.order.company_id.cnpj_cpf)[12:14]), + 'cedente_agencia': int(self.order.mode.bank_id.bra_number), + 'cedente_conta': int(self.order.mode.bank_id.acc_number), + 'cedente_agencia_conta_dv': + self.order.mode.bank_id.bra_number_dig, + 'nome_empresa_pagadora': self.order.company_id.legal_name, + 'cedente_codigo_agencia_digito': + self.order.mode.bank_id.bra_number_dig, + 'arquivo_codigo': 1, # Remessa/Retorno + 'servico_operacao': u'R', + 'reservado_empresa': u'BRADESCO PAG FOR', + # Sequencial crescente e nunca pode ser repetido + 'numero_lista_debito': int(self.get_file_numeration()), + # TODO: Sequencial crescente de 1 a 1 no arquivo. O primeiro header + # será sempre 000001 + 'sequencial': 1 + } + + def get_file_numeration(self): + numero = self.order.get_next_number() + if not numero: + numero = 1 + return numero + + def format_date(self, srt_date): + return int(datetime.datetime.strptime( + srt_date, '%Y-%m-%d').strftime('%d%m%Y')) + + def format_date_ano_mes_dia(self, srt_date): + return int(datetime.datetime.strptime( + srt_date, '%Y-%m-%d').strftime('%Y%m%d')) + + def nosso_numero(self, format): + pass + + def cep(self, format): + sulfixo = format[-3:] + prefixo = format[:5] + return prefixo, sulfixo + + def sacado_inscricao_tipo(self, partner_id): + # TODO: Implementar codigo para PIS/PASEP + if partner_id.is_company: + return 2 + else: + return 1 + + def rmchar(self, format): + return re.sub('[%s]' % re.escape(string.punctuation), '', format or '') + + def _prepare_cobranca(self, line, vals): + """ + + :param line: + :return: + """ + segmento = {} + + vals.update(segmento) + + # TODO this zip code + prefixo, sulfixo = self.cep(line.partner_id.zip) + + segmento = { + 'conta_complementar': int(self.order.mode.bank_id.acc_number), + # 'especie_titulo': 8, + + 'tipo_inscricao': int( + self.sacado_inscricao_tipo(line.partner_id)), + 'cnpj_cpf_base_forn': int( + self.rmchar(line.partner_id.cnpj_cpf)[0:8]), + 'cnpj_cpf_filial_forn': int( + self.rmchar(line.partner_id.cnpj_cpf)[9:12]), + 'cnpj_cpf_forn_sufixo': int( + self.rmchar(line.partner_id.cnpj_cpf)[12:14]), + 'nome_forn': line.partner_id.legal_name, + 'endereco_forn': ( + line.partner_id.street + ' ' + line.partner_id.number), + 'cep_forn': int(prefixo), + 'cep_complemento_forn': int(sulfixo), + + # TODO quando banco é 237, deve-se extrair da linha + # digitável. Do contrário, zeros. + # 'nosso_numero': 11, # FIXME + + # 'numero_documento': line.name, + # 'vencimento_titulo': self.format_date_ano_mes_dia( + # line.ml_maturity_date), + + 'data_emissao_titulo': self.format_date_ano_mes_dia( + line.ml_date_created), + + 'desconto1_data': 0, + 'fator_vencimento': 0, # FIXME + + 'valor_titulo': Decimal(str(line.amount_currency)).quantize( + Decimal('1.00')), + + 'valor_pagto': Decimal(str(line.amount_currency)).quantize( + Decimal('1.00')), + + 'valor_desconto': Decimal('0.00'), + + 'valor_acrescimo': Decimal('0.00'), + + # FIXME + 'tipo_documento': 2, # NF, Fatura, Duplicata... + # NF_Fatura_01/Fatura_02/NF_03/Duplicata_04/Outros_05 + 'numero_nf': int(line.ml_inv_ref.internal_number), + + 'modalidade_pagamento': int( + line.order_id.mode.type_purchase_payment), + + # Quando não informada o sistema assume a data constante do campo + # Vencimento + 'data_para_efetivacao_pag': 0, + + 'tipo_movimento': 0, + # TODO Tipo de Movimento. + # 0 - Inclusão. + # 5 - Alteração. + # 9 - Exclusão. + + 'codigo_movimento': 0, # Autoriza agendamento + + # Quando não informado consulta em todos processamentos + # 'horario_consulta_saldo': u'5', + + 'codigo_area_empresa': 0, + + 'codigo_lancamento': 0, # FIXME + + 'tipo_conta_fornecedor': 1, # FIXME + + # O Primeiro registro de transação sempre será o registro + # “000002”, e assim sucessivamente. + 'sequencial': 3, # FIXME + + # Trailer + 'totais_quantidade_registros': 0, + 'total_valor_arq': Decimal('0.00'), + # FIXME: lib nao reconhece campo + 'sequencial_trailer': int(self.get_file_numeration()), + 'sequencial_transacao': self.controle_linha, + 'codigo_protesto': int(self.order.mode.boleto_protesto), + 'prazo_protesto': int(self.order.mode.boleto_protesto_prazo), + 'codigo_baixa': 2, + 'prazo_baixa': 0, # De 5 a 120 dias. + 'controlecob_data_gravacao': self.data_hoje(), + + } + segmento.update(vals) + return segmento + + def remessa(self, order): + """ + + :param order: + :return: + """ + + pag_valor_titulos = 0 + + self.order = order + self.arquivo = Arquivo(self.bank, **self._prepare_header()) + cont_lote = 0 + + for line in order.line_ids: + self.arquivo.incluir_pagamento(**self.incluir_pagamento_for(line)) + pag_valor_titulos += line.amount_currency + self.arquivo.trailer.total_valor_arq = Decimal( + pag_valor_titulos).quantize(Decimal('1.00')) + self.arquivo.trailer.sequencial_transacao = self.controle_linha + + cont_lote += 1 + remessa = unicode(self.arquivo) + return unicodedata.normalize( + 'NFKD', remessa).encode('ascii', 'ignore') + + def data_hoje(self): + return (int(time.strftime("%d%m%Y"))) + + def data_hoje_pag_for(self): + return (int(time.strftime("%Y%m%d"))) + + def hora_agora(self): + return (int(time.strftime("%H%M%S"))) + + @staticmethod + def modulo11(num, base, r): + return BoletoData.modulo11(num, base=9, r=0) + + def incluir_pagamento_for(self, line): + mode = line.order_id.mode.type_purchase_payment + if mode in ('01'): + return self.lancamento_credito_bradesco(line) + elif mode in ('02'): + raise UserError(_(u'Operação não suportada')) + elif mode in ('03'): + return self.lancamento_doc(line) + elif mode in ('05'): + raise UserError(_(u'Operação não suportada')) + elif mode in ('08'): + return self.lancamento_ted(line) + elif mode in ('30'): + raise UserError(_(u'Operação não suportada')) + elif mode in ('31'): + # titulos de terceiros + return self.lancamento_titulos_terceiros(line) + raise UserError(_(u'Operação não suportada')) + + def lancamento_credito_bradesco(self, line): + # TODO: + # modalidade 01. + + vals = { + 'especie_titulo': line.order_id.mode.type_purchase_payment, + + 'codigo_banco_forn': 237, + 'codigo_agencia_forn': int(line.bank_id.bra_number), + 'digito_agencia_forn_transacao': line.bank_id.bra_number_dig, + 'conta_corrente_forn': int(line.bank_id.acc_number), + 'digito_conta_forn_transacao': line.bank_id.acc_number_dig, + + 'numero_pagamento': self.adiciona_digitos_num_pag( + line.communication), + + 'carteira': int(self.order.mode.boleto_carteira), + + 'nosso_numero': 0, + + 'vencimento_titulo': self.format_date_ano_mes_dia( + line.ml_maturity_date), + + 'informacoes_complementares': u'', + } + + return self._prepare_cobranca(line, vals) + + def lancamento_ted(self, line): + # TODO: + # modalidade 08. + + vals = { + 'conta_complementar': int(self.order.mode.bank_id.acc_number), + 'especie_titulo': line.order_id.mode.type_purchase_payment, + + + # TODO: código do banco. Para a Modalidade de Pagamento valor + # pode variar + 'codigo_banco_forn': int(line.bank_id.bank.bic), + 'codigo_agencia_forn': int(line.bank_id.bra_number), + 'digito_agencia_forn_transacao': line.bank_id.bra_number_dig, + 'conta_corrente_forn': int(line.bank_id.acc_number), + 'digito_conta_forn_transacao': line.bank_id.acc_number_dig, + # TODO Gerado pelo cliente pagador quando do agendamento de + # pagamento por parte desse, exceto para a modalidade 30 - + # Títulos em Cobrança Bradesco + # communication + 'numero_pagamento': self.adiciona_digitos_num_pag( + line.communication), + + 'carteira': 0, + + 'nosso_numero': 0, + + 'vencimento_titulo': self.format_date_ano_mes_dia( + line.ml_maturity_date), + + 'fator_vencimento': 0, # FIXME + + # 'modalidade_pagamento': int(self.order.mode.boleto_especie), + + 'tipo_movimento': 0, + # TODO Tipo de Movimento. + # 0 - Inclusão. + # 5 - Alteração. + # 9 - Exclusão. Wkf Odoo. + 'codigo_movimento': 0, # FIXME + # 'horario_consulta_saldo': u'5', # FIXME + + # 'informacoes_complementares': self.montar_info_comple_ted(), + 'informacoes_complementares': u'', + + 'codigo_lancamento': 0, # FIXME + 'tipo_conta_fornecedor': 1, # FIXME + + } + + return self._prepare_cobranca(line, vals) + + def lancamento_doc(self): + # TODO: + + vals = {} + + return self._prepare_cobranca(vals) + + def lancamento_titulos_terceiros(self, line): + # TODO: + + res_cods_ag_cc = \ + self.ler_linha_digitavel_codigos_ag_cc(line.linha_digitavel) + + vals = { + 'conta_complementar': int(self.order.mode.bank_id.acc_number), + 'especie_titulo': line.order_id.mode.type_purchase_payment, + + # extrair do código de barras + 'codigo_banco_forn': res_cods_ag_cc['codigo_banco_forn'], + 'codigo_agencia_forn': res_cods_ag_cc['codigo_agencia_forn'], + 'digito_agencia_forn_transacao': res_cods_ag_cc[ + 'digito_agencia_forn_transacao'], + 'conta_corrente_forn': res_cods_ag_cc['conta_corrente_forn'], + 'digito_conta_forn_transacao': res_cods_ag_cc[ + 'digito_conta_forn_transacao'], + + 'carteira': res_cods_ag_cc['carteira'] + + } + + return self._prepare_cobranca(vals) + + def adiciona_digitos_num_pag(self, campo): + num_digitos = 16 + campo = str(campo) + chars_faltantes = num_digitos - len(campo) + return (u' ' * chars_faltantes) + campo + + def montar_info_comple_ted(self): + tipo_doc_compe = TIPO_DOC[0][0] + num_doc_ted = '000000' + # pagamento duplicatas. Ou será 01? + finalidade_doc_compe = FINALIDADE_DOC_TED[2][0] + tipo_conta_doc_ted = '01' + codigo_identif_transf = '0000000000000000000000000' + fim_do_campo = ' ' + info_comple = tipo_doc_compe + num_doc_ted + finalidade_doc_compe + \ + tipo_conta_doc_ted + codigo_identif_transf + fim_do_campo + return (info_comple.encode('utf-8')) + + def ler_linha_digitavel_codigos_ag_cc(self, linha_digitavel): + codigo_banco_fornecedor = linha_digitavel[:3] + res = {} + + # para banco = 237, bradesco + if (codigo_banco_fornecedor == '237'): + res = { + 'codigo_banco_forn': int(codigo_banco_fornecedor), + 'codigo_agencia_forn': int(linha_digitavel[4:8]), + # Calcular usando modulo 11 base 7 + 'digito_agencia_forn_transacao': u'', + 'conta_corrente_forn': int(linha_digitavel[23:30]), + # Calcular usando modulo 11 base 7 + 'digito_conta_forn_transacao': u'', + + 'carteira': int(linha_digitavel[8:10]), + + 'nosso_numero': int(linha_digitavel[11:21]) + } + # para outros bancos + else: + res = { + 'codigo_banco_forn': int(codigo_banco_fornecedor), + 'codigo_agencia_forn': 0, + 'digito_agencia_forn_transacao': u'', + 'conta_corrente_forn': 0, + 'digito_conta_forn_transacao': u'', + + 'carteira': 0, + + 'nosso_numero': 0, + } + return res diff --git a/l10n_br_financial_payment_order/models/__init__.py b/l10n_br_financial_payment_order/models/__init__.py new file mode 100644 index 0000000..d674af8 --- /dev/null +++ b/l10n_br_financial_payment_order/models/__init__.py @@ -0,0 +1,4 @@ +from . import payment_order +from . import payment_line +from . import bank_payment_line +from . import payment_mode_type diff --git a/l10n_br_financial_payment_order/models/bank_payment_line.py b/l10n_br_financial_payment_order/models/bank_payment_line.py new file mode 100644 index 0000000..4fdc47b --- /dev/null +++ b/l10n_br_financial_payment_order/models/bank_payment_line.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- +# Copyright 2017 KMEE INFORMATICA LTDA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from openerp import api, fields, models, _ + + +class BankPaymentLine(models.Model): + + _inherit = 'bank.payment.line' + + @api.model + def same_fields_payment_line_and_bank_payment_line(self): + """ + This list of fields is used both to compute the grouping + hashcode and to copy the values from payment line + to bank payment line + The fields must have the same name on the 2 objects + """ + same_fields = super( + BankPaymentLine, self + ).same_fields_payment_line_and_bank_payment_line() + + # TODO: Implementar campo brasileiros que permitem mesclar linhas + + # same_fields = [ + # 'currency', 'partner_id', + # 'bank_id', 'date', 'state'] + + return same_fields diff --git a/l10n_br_financial_payment_order/models/payment_line.py b/l10n_br_financial_payment_order/models/payment_line.py new file mode 100644 index 0000000..9034d0d --- /dev/null +++ b/l10n_br_financial_payment_order/models/payment_line.py @@ -0,0 +1,55 @@ +# -*- coding: utf-8 -*- +# Copyright 2017 KMEE INFORMATICA LTDA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from __future__ import division, print_function, unicode_literals + + +from openerp import api, fields, models, _ + + +class PaymentLine(models.Model): + + _inherit = 'payment.line' + + # @api.one + # @api.depends('percent_interest', 'amount_currency') + # def _compute_interest(self): + # precision = self.env['decimal.precision'].precision_get('Account') + # self.amount_interest = round(self.amount_currency * + # (self.percent_interest / 100), + # precision) + + amount_other_discounts = fields.Float( + string='Valor Abatimento', + ) + amount_discount = fields.Float( + string='Valor Desconto', + ) + amount_interest = fields.Float( + string='Valor Mora', + ) + amount_penalty = fields.Float( + string='Valor Multa', + ) + # TODO: Definir campos do segmento P/Q/R/T/U + + linha_digitavel = fields.Char(string=u"Linha Digitável") + + def _get_info_partner(self, cr, uid, partner_record, context=None): + # TODO: Melhorar este método + if not partner_record: + return False + st = partner_record.street or '' + n = partner_record.number or '' + st1 = partner_record.street2 or '' + zip = partner_record.zip or '' + city = partner_record.l10n_br_city_id.name or '' + uf = partner_record.state_id.code or '' + zip_city = city + '-' + uf + '\n' + zip + cntry = partner_record.country_id and \ + partner_record.country_id.name or '' + cnpj = partner_record.cnpj_cpf or '' + return partner_record.legal_name or '' + "\n" + cnpj + "\n" + st \ + + ", " + n + " " + st1 + "\n" + zip_city + "\n" + cntry + diff --git a/l10n_br_financial_payment_order/models/payment_mode.py b/l10n_br_financial_payment_order/models/payment_mode.py new file mode 100644 index 0000000..d3e614a --- /dev/null +++ b/l10n_br_financial_payment_order/models/payment_mode.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Copyright 2017 KMEE INFORMATICA LTDA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from __future__ import division, print_function, unicode_literals + +from openerp import api, fields, models, _ + +from ..febraban.boleto.document import getBoletoSelection + +boleto_selection = getBoletoSelection() + + +class PaymentMode(models.Model): + + _inherit = 'payment.mode' + + boleto_carteira = fields.Char('Carteira', size=3) + boleto_modalidade = fields.Char('Modalidade', size=2) + boleto_convenio = fields.Char('Codigo convênio', size=10) + boleto_variacao = fields.Char('Variação', size=2) + boleto_cnab_code = fields.Char('Código Cnab', size=20) + boleto_aceite = fields.Selection( + [('S', 'Sim'), ('N', 'Não')], string='Aceite', default='N') + boleto_type = fields.Selection( + boleto_selection, string="Boleto") + boleto_especie = fields.Selection([ + ('01', 'DUPLICATA MERCANTIL'), + ('02', 'NOTA PROMISSÓRIA'), + ('03', 'NOTA DE SEGURO'), + ('04', 'MENSALIDADE ESCOLAR'), + ('05', 'RECIBO'), + ('06', 'CONTRATO'), + ('07', 'COSSEGUROS'), + ('08', 'DUPLICATA DE SERVIÇO'), + ('09', 'LETRA DE CÂMBIO'), + ('13', 'NOTA DE DÉBITOS'), + ('15', 'DOCUMENTO DE DÍVIDA'), + ('16', 'ENCARGOS CONDOMINIAIS'), + ('17', 'CONTA DE PRESTAÇÃO DE SERVIÇOS'), + ('99', 'DIVERSOS'), + ], string='Espécie do Título', default='01') + boleto_protesto = fields.Selection([ + ('0', 'Sem instrução'), + ('1', 'Protestar (Dias Corridos)'), + ('2', 'Protestar (Dias Úteis)'), + ('3', 'Não protestar'), + ('7', 'Negativar (Dias Corridos)'), + ('8', 'Não Negativar') + ], string='Códigos de Protesto', default='0') + boleto_protesto_prazo = fields.Char('Prazo protesto', size=2) diff --git a/l10n_br_financial_payment_order/models/payment_mode_type.py b/l10n_br_financial_payment_order/models/payment_mode_type.py new file mode 100644 index 0000000..450e7f4 --- /dev/null +++ b/l10n_br_financial_payment_order/models/payment_mode_type.py @@ -0,0 +1,17 @@ +# -*- coding: utf-8 -*- +# Copyright 2017 KMEE INFORMATICA LTDA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from __future__ import division, print_function, unicode_literals + +from openerp import api, fields, models, _ + + +class PaymentModeType(models.Model): + + _inherit = 'payment.mode.type' + + payment_order_type = fields.Selection( + selection_add=[ + ('cobranca', u'Cobrança'), + ]) diff --git a/l10n_br_financial_payment_order/models/payment_order.py b/l10n_br_financial_payment_order/models/payment_order.py new file mode 100644 index 0000000..d7414c2 --- /dev/null +++ b/l10n_br_financial_payment_order/models/payment_order.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +# Copyright 2017 KMEE INFORMATICA LTDA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from __future__ import division, print_function, unicode_literals + +from openerp import api, fields, models, _ +from openerp.exceptions import ValidationError + + +class PaymentOrder(models.Model): + + _inherit = 'payment.order' + + @api.multi + def action_open(self): + """ + Validacao ao confirmar ordem: + """ + for record in self: + if not record.line_ids: + raise ValidationError( + _("Impossivel confirmar linha vazia!")) + res = super(PaymentOrder, self).action_open() + return res diff --git a/l10n_br_financial_payment_order/security/bank_payment_line.xml b/l10n_br_financial_payment_order/security/bank_payment_line.xml new file mode 100644 index 0000000..6cb5701 --- /dev/null +++ b/l10n_br_financial_payment_order/security/bank_payment_line.xml @@ -0,0 +1,20 @@ + + + + + + + + bank.payment.line access name + + + + + + + + + + + diff --git a/l10n_br_financial_payment_order/security/payment_line.xml b/l10n_br_financial_payment_order/security/payment_line.xml new file mode 100644 index 0000000..4f663de --- /dev/null +++ b/l10n_br_financial_payment_order/security/payment_line.xml @@ -0,0 +1,20 @@ + + + + + + + + payment.line access name + + + + + + + + + + + diff --git a/l10n_br_financial_payment_order/security/payment_mode.xml b/l10n_br_financial_payment_order/security/payment_mode.xml new file mode 100644 index 0000000..56f428d --- /dev/null +++ b/l10n_br_financial_payment_order/security/payment_mode.xml @@ -0,0 +1,20 @@ + + + + + + + + payment.mode access name + + + + + + + + + + + diff --git a/l10n_br_financial_payment_order/security/payment_mode_type.xml b/l10n_br_financial_payment_order/security/payment_mode_type.xml new file mode 100644 index 0000000..f30ad9f --- /dev/null +++ b/l10n_br_financial_payment_order/security/payment_mode_type.xml @@ -0,0 +1,20 @@ + + + + + + + + payment.mode.type access name + + + + + + + + + + + diff --git a/l10n_br_financial_payment_order/security/payment_order.xml b/l10n_br_financial_payment_order/security/payment_order.xml new file mode 100644 index 0000000..559abc8 --- /dev/null +++ b/l10n_br_financial_payment_order/security/payment_order.xml @@ -0,0 +1,20 @@ + + + + + + + + payment.order access name + + + + + + + + + + + diff --git a/l10n_br_financial_payment_order/static/description/icon.png b/l10n_br_financial_payment_order/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..3a0328b516c4980e8e44cdb63fd945757ddd132d GIT binary patch literal 9455 zcmW++2RxMjAAjx~&dlBk9S+%}OXg)AGE&Cb*&}d0jUxM@u(PQx^-s)697TX`ehR4?GS^qbkof1cslKgkU)h65qZ9Oc=ml_0temigYLJfnz{IDzUf>bGs4N!v3=Z3jMq&A#7%rM5eQ#dc?k~! zVpnB`o+K7|Al`Q_U;eD$B zfJtP*jH`siUq~{KE)`jP2|#TUEFGRryE2`i0**z#*^6~AI|YzIWy$Cu#CSLW3q=GA z6`?GZymC;dCPk~rBS%eCb`5OLr;RUZ;D`}um=H)BfVIq%7VhiMr)_#G0N#zrNH|__ zc+blN2UAB0=617@>_u;MPHN;P;N#YoE=)R#i$k_`UAA>WWCcEVMh~L_ zj--gtp&|K1#58Yz*AHCTMziU1Jzt_jG0I@qAOHsk$2}yTmVkBp_eHuY$A9)>P6o~I z%aQ?!(GqeQ-Y+b0I(m9pwgi(IIZZzsbMv+9w{PFtd_<_(LA~0H(xz{=FhLB@(1&qHA5EJw1>>=%q2f&^X>IQ{!GJ4e9U z&KlB)z(84HmNgm2hg2C0>WM{E(DdPr+EeU_N@57;PC2&DmGFW_9kP&%?X4}+xWi)( z;)z%wI5>D4a*5XwD)P--sPkoY(a~WBw;E~AW`Yue4kFa^LM3X`8x|}ZUeMnqr}>kH zG%WWW>3ml$Yez?i%)2pbKPI7?5o?hydokgQyZsNEr{a|mLdt;X2TX(#B1j35xPnPW z*bMSSOauW>o;*=kO8ojw91VX!qoOQb)zHJ!odWB}d+*K?#sY_jqPdg{Sm2HdYzdEx zOGVPhVRTGPtv0o}RfVP;Nd(|CB)I;*t&QO8h zFfekr30S!-LHmV_Su-W+rEwYXJ^;6&3|L$mMC8*bQptyOo9;>Qb9Q9`ySe3%V$A*9 zeKEe+b0{#KWGp$F+tga)0RtI)nhMa-K@JS}2krK~n8vJ=Ngm?R!9G<~RyuU0d?nz# z-5EK$o(!F?hmX*2Yt6+coY`6jGbb7tF#6nHA zuKk=GGJ;ZwON1iAfG$E#Y7MnZVmrY|j0eVI(DN_MNFJmyZ|;w4tf@=CCDZ#5N_0K= z$;R~bbk?}TpfDjfB&aiQ$VA}s?P}xPERJG{kxk5~R`iRS(SK5d+Xs9swCozZISbnS zk!)I0>t=A<-^z(cmSFz3=jZ23u13X><0b)P)^1T_))Kr`e!-pb#q&J*Q`p+B6la%C zuVl&0duN<;uOsB3%T9Fp8t{ED108<+W(nOZd?gDnfNBC3>M8WE61$So|P zVvqH0SNtDTcsUdzaMDpT=Ty0pDHHNL@Z0w$Y`XO z2M-_r1S+GaH%pz#Uy0*w$Vdl=X=rQXEzO}d6J^R6zjM1u&c9vYLvLp?W7w(?np9x1 zE_0JSAJCPB%i7p*Wvg)pn5T`8k3-uR?*NT|J`eS#_#54p>!p(mLDvmc-3o0mX*mp_ zN*AeS<>#^-{S%W<*mz^!X$w_2dHWpcJ6^j64qFBft-o}o_Vx80o0>}Du;>kLts;$8 zC`7q$QI(dKYG`Wa8#wl@V4jVWBRGQ@1dr-hstpQL)Tl+aqVpGpbSfN>5i&QMXfiZ> zaA?T1VGe?rpQ@;+pkrVdd{klI&jVS@I5_iz!=UMpTsa~mBga?1r}aRBm1WS;TT*s0f0lY=JBl66Upy)-k4J}lh=P^8(SXk~0xW=T9v*B|gzIhN z>qsO7dFd~mgxAy4V?&)=5ieYq?zi?ZEoj)&2o)RLy=@hbCRcfT5jigwtQGE{L*8<@Yd{zg;CsL5mvzfDY}P-wos_6PfprFVaeqNE%h zKZhLtcQld;ZD+>=nqN~>GvROfueSzJD&BE*}XfU|H&(FssBqY=hPCt`d zH?@s2>I(|;fcW&YM6#V#!kUIP8$Nkdh0A(bEVj``-AAyYgwY~jB zT|I7Bf@%;7aL7Wf4dZ%VqF$eiaC38OV6oy3Z#TER2G+fOCd9Iaoy6aLYbPTN{XRPz z;U!V|vBf%H!}52L2gH_+j;`bTcQRXB+y9onc^wLm5wi3-Be}U>k_u>2Eg$=k!(l@I zcCg+flakT2Nej3i0yn+g+}%NYb?ta;R?(g5SnwsQ49U8Wng8d|{B+lyRcEDvR3+`O{zfmrmvFrL6acVP%yG98X zo&+VBg@px@i)%o?dG(`T;n*$S5*rnyiR#=wW}}GsAcfyQpE|>a{=$Hjg=-*_K;UtD z#z-)AXwSRY?OPefw^iI+ z)AXz#PfEjlwTes|_{sB?4(O@fg0AJ^g8gP}ex9Ucf*@_^J(s_5jJV}c)s$`Myn|Kd z$6>}#q^n{4vN@+Os$m7KV+`}c%4)4pv@06af4-x5#wj!KKb%caK{A&Y#Rfs z-po?Dcb1({W=6FKIUirH&(yg=*6aLCekcKwyfK^JN5{wcA3nhO(o}SK#!CINhI`-I z1)6&n7O&ZmyFMuNwvEic#IiOAwNkR=u5it{B9n2sAJV5pNhar=j5`*N!Na;c7g!l$ z3aYBqUkqqTJ=Re-;)s!EOeij=7SQZ3Hq}ZRds%IM*PtM$wV z@;rlc*NRK7i3y5BETSKuumEN`Xu_8GP1Ri=OKQ$@I^ko8>H6)4rjiG5{VBM>B|%`&&s^)jS|-_95&yc=GqjNo{zFkw%%HHhS~e=s zD#sfS+-?*t|J!+ozP6KvtOl!R)@@-z24}`9{QaVLD^9VCSR2b`b!KC#o;Ki<+wXB6 zx3&O0LOWcg4&rv4QG0)4yb}7BFSEg~=IR5#ZRj8kg}dS7_V&^%#Do==#`u zpy6{ox?jWuR(;pg+f@mT>#HGWHAJRRDDDv~@(IDw&R>9643kK#HN`!1vBJHnC+RM&yIh8{gG2q zA%e*U3|N0XSRa~oX-3EAneep)@{h2vvd3Xvy$7og(sayr@95+e6~Xvi1tUqnIxoIH zVWo*OwYElb#uyW{Imam6f2rGbjR!Y3`#gPqkv57dB6K^wRGxc9B(t|aYDGS=m$&S!NmCtrMMaUg(c zc2qC=2Z`EEFMW-me5B)24AqF*bV5Dr-M5ig(l-WPS%CgaPzs6p_gnCIvTJ=Y<6!gT zVt@AfYCzjjsMEGi=rDQHo0yc;HqoRNnNFeWZgcm?f;cp(6CNylj36DoL(?TS7eU#+ z7&mfr#y))+CJOXQKUMZ7QIdS9@#-}7y2K1{8)cCt0~-X0O!O?Qx#E4Og+;A2SjalQ zs7r?qn0H044=sDN$SRG$arw~n=+T_DNdSrarmu)V6@|?1-ZB#hRn`uilTGPJ@fqEy zGt(f0B+^JDP&f=r{#Y_wi#AVDf-y!RIXU^0jXsFpf>=Ji*TeqSY!H~AMbJdCGLhC) zn7Rx+sXw6uYj;WRYrLd^5IZq@6JI1C^YkgnedZEYy<&4(z%Q$5yv#Boo{AH8n$a zhb4Y3PWdr269&?V%uI$xMcUrMzl=;w<_nm*qr=c3Rl@i5wWB;e-`t7D&c-mcQl7x! zZWB`UGcw=Y2=}~wzrfLx=uet<;m3~=8I~ZRuzvMQUQdr+yTV|ATf1Uuomr__nDf=X zZ3WYJtHp_ri(}SQAPjv+Y+0=fH4krOP@S&=zZ-t1jW1o@}z;xk8 z(Nz1co&El^HK^NrhVHa-_;&88vTU>_J33=%{if;BEY*J#1n59=07jrGQ#IP>@u#3A z;!q+E1Rj3ZJ+!4bq9F8PXJ@yMgZL;>&gYA0%_Kbi8?S=XGM~dnQZQ!yBSgcZhY96H zrWnU;k)qy`rX&&xlDyA%(a1Hhi5CWkmg(`Gb%m(HKi-7Z!LKGRP_B8@`7&hdDy5n= z`OIxqxiVfX@OX1p(mQu>0Ai*v_cTMiw4qRt3~NBvr9oBy0)r>w3p~V0SCm=An6@3n)>@z!|o-$HvDK z|3D2ZMJkLE5loMKl6R^ez@Zz%S$&mbeoqH5`Bb){Ei21q&VP)hWS2tjShfFtGE+$z zzCR$P#uktu+#!w)cX!lWN1XU%K-r=s{|j?)Akf@q#3b#{6cZCuJ~gCxuMXRmI$nGtnH+-h z+GEi!*X=AP<|fG`1>MBdTb?28JYc=fGvAi2I<$B(rs$;eoJCyR6_bc~p!XR@O-+sD z=eH`-ye})I5ic1eL~TDmtfJ|8`0VJ*Yr=hNCd)G1p2MMz4C3^Mj?7;!w|Ly%JqmuW zlIEW^Ft%z?*|fpXda>Jr^1noFZEwFgVV%|*XhH@acv8rdGxeEX{M$(vG{Zw+x(ei@ zmfXb22}8-?Fi`vo-YVrTH*C?a8%M=Hv9MqVH7H^J$KsD?>!SFZ;ZsvnHr_gn=7acz z#W?0eCdVhVMWN12VV^$>WlQ?f;P^{(&pYTops|btm6aj>_Uz+hqpGwB)vWp0Cf5y< zft8-je~nn?W11plq}N)4A{l8I7$!ks_x$PXW-2XaRFswX_BnF{R#6YIwMhAgd5F9X zGmwdadS6(a^fjHtXg8=l?Rc0Sm%hk6E9!5cLVloEy4eh(=FwgP`)~I^5~pBEWo+F6 zSf2ncyMurJN91#cJTy_u8Y}@%!bq1RkGC~-bV@SXRd4F{R-*V`bS+6;W5vZ(&+I<9$;-V|eNfLa5n-6% z2(}&uGRF;p92eS*sE*oR$@pexaqr*meB)VhmIg@h{uzkk$9~qh#cHhw#>O%)b@+(| z^IQgqzuj~Sk(J;swEM-3TrJAPCq9k^^^`q{IItKBRXYe}e0Tdr=Huf7da3$l4PdpwWDop%^}n;dD#K4s#DYA8SHZ z&1!riV4W4R7R#C))JH1~axJ)RYnM$$lIR%6fIVA@zV{XVyx}C+a-Dt8Y9M)^KU0+H zR4IUb2CJ{Hg>CuaXtD50jB(_Tcx=Z$^WYu2u5kubqmwp%drJ6 z?Fo40g!Qd<-l=TQxqHEOuPX0;^z7iX?Ke^a%XT<13TA^5`4Xcw6D@Ur&VT&CUe0d} z1GjOVF1^L@>O)l@?bD~$wzgf(nxX1OGD8fEV?TdJcZc2KoUe|oP1#=$$7ee|xbY)A zDZq+cuTpc(fFdj^=!;{k03C69lMQ(|>uhRfRu%+!k&YOi-3|1QKB z z?n?eq1XP>p-IM$Z^C;2L3itnbJZAip*Zo0aw2bs8@(s^~*8T9go!%dHcAz2lM;`yp zD=7&xjFV$S&5uDaiScyD?B-i1ze`+CoRtz`Wn+Zl&#s4&}MO{@N!ufrzjG$B79)Y2d3tBk&)TxUTw@QS0TEL_?njX|@vq?Uz(nBFK5Pq7*xj#u*R&i|?7+6# z+|r_n#SW&LXhtheZdah{ZVoqwyT{D>MC3nkFF#N)xLi{p7J1jXlmVeb;cP5?e(=f# zuT7fvjSbjS781v?7{)-X3*?>tq?)Yd)~|1{BDS(pqC zC}~H#WXlkUW*H5CDOo<)#x7%RY)A;ShGhI5s*#cRDA8YgqG(HeKDx+#(ZQ?386dv! zlXCO)w91~Vw4AmOcATuV653fa9R$fyK8ul%rG z-wfS zihugoZyr38Im?Zuh6@RcF~t1anQu7>#lPpb#}4cOA!EM11`%f*07RqOVkmX{p~KJ9 z^zP;K#|)$`^Rb{rnHGH{~>1(fawV0*Z#)}M`m8-?ZJV<+e}s9wE# z)l&az?w^5{)`S(%MRzxdNqrs1n*-=jS^_jqE*5XDrA0+VE`5^*p3CuM<&dZEeCjoz zR;uu_H9ZPZV|fQq`Cyw4nscrVwi!fE6ciMmX$!_hN7uF;jjKG)d2@aC4ropY)8etW=xJvni)8eHi`H$%#zn^WJ5NLc-rqk|u&&4Z6fD_m&JfSI1Bvb?b<*n&sfl0^t z=HnmRl`XrFvMKB%9}>PaA`m-fK6a0(8=qPkWS5bb4=v?XcWi&hRY?O5HdulRi4?fN zlsJ*N-0Qw+Yic@s0(2uy%F@ib;GjXt01Fmx5XbRo6+n|pP(&nodMoap^z{~q ziEeaUT@Mxe3vJSfI6?uLND(CNr=#^W<1b}jzW58bIfyWTDle$mmS(|x-0|2UlX+9k zQ^EX7Nw}?EzVoBfT(-LT|=9N@^hcn-_p&sqG z&*oVs2JSU+N4ZD`FhCAWaS;>|wH2G*Id|?pa#@>tyxX`+4HyIArWDvVrX)2WAOQff z0qyHu&-S@i^MS-+j--!pr4fPBj~_8({~e1bfcl0wI1kaoN>mJL6KUPQm5N7lB(ui1 zE-o%kq)&djzWJ}ob<-GfDlkB;F31j-VHKvQUGQ3sp`CwyGJk_i!y^sD0fqC@$9|jO zOqN!r!8-p==F@ZVP=U$qSpY(gQ0)59P1&t@y?5rvg<}E+GB}26NYPp4f2YFQrQtot5mn3wu_qprZ=>Ig-$ zbW26Ws~IgY>}^5w`vTB(G`PTZaDiGBo5o(tp)qli|NeV( z@H_=R8V39rt5J5YB2Ky?4eJJ#b`_iBe2ot~6%7mLt5t8Vwi^Jy7|jWXqa3amOIoRb zOr}WVFP--DsS`1WpN%~)t3R!arKF^Q$e12KEqU36AWwnCBICpH4XCsfnyrHr>$I$4 z!DpKX$OKLWarN7nv@!uIA+~RNO)l$$w}p(;b>mx8pwYvu;dD_unryX_NhT8*Tj>BTrTTL&!?O+%Rv;b?B??gSzdp?6Uug9{ zd@V08Z$BdI?fpoCS$)t4mg4rT8Q_I}h`0d-vYZ^|dOB*Q^S|xqTV*vIg?@fVFSmMpaw0qtTRbx} z({Pg?#{2`sc9)M5N$*N|4;^t$+QP?#mov zGVC@I*lBVrOU-%2y!7%)fAKjpEFsgQc4{amtiHb95KQEwvf<(3T<9-Zm$xIew#P22 zc2Ix|App^>v6(3L_MCU0d3W##AB0M~3D00EWoKZqsJYT(#@w$Y_H7G22M~ApVFTRHMI_3be)Lkn#0F*V8Pq zc}`Cjy$bE;FJ6H7p=0y#R>`}-m4(0F>%@P|?7fx{=R^uFdISRnZ2W_xQhD{YuR3t< z{6yxu=4~JkeA;|(J6_nv#>Nvs&FuLA&PW^he@t(UwFFE8)|a!R{`E`K`i^ZnyE4$k z;(749Ix|oi$c3QbEJ3b~D_kQsPz~fIUKym($a_7dJ?o+40*OLl^{=&oq$<#Q(yyrp z{J-FAniyAw9tPbe&IhQ|a`DqFTVQGQ&Gq3!C2==4x{6EJwiPZ8zub-iXoUtkJiG{} zPaR&}_fn8_z~(=;5lD-aPWD3z8PZS@AaUiomF!G8I}Mf>e~0g#BelA-5#`cj;O5>N Xviia!U7SGha1wx#SCgwmn*{w2TRX*I literal 0 HcmV?d00001 diff --git a/l10n_br_financial_payment_order/views/bank_payment_line.xml b/l10n_br_financial_payment_order/views/bank_payment_line.xml new file mode 100644 index 0000000..1e9bf9b --- /dev/null +++ b/l10n_br_financial_payment_order/views/bank_payment_line.xml @@ -0,0 +1,51 @@ + + + + + + + + bank.payment.line.form (in l10n_br_financial_payment_order) + bank.payment.line + + + + + + + + bank.payment.line.search (in l10n_br_financial_payment_order) + bank.payment.line + + + + + + + + bank.payment.line.tree (in l10n_br_financial_payment_order) + bank.payment.line + + + + + + + + Bank Payment Line + bank.payment.line + tree,form + [] + {} + + + + Bank Payment Line + + + + + + + diff --git a/l10n_br_financial_payment_order/views/payment_line.xml b/l10n_br_financial_payment_order/views/payment_line.xml new file mode 100644 index 0000000..6697108 --- /dev/null +++ b/l10n_br_financial_payment_order/views/payment_line.xml @@ -0,0 +1,51 @@ + + + + + + + + payment.line.form (in l10n_br_financial_payment_order) + payment.line + + + + + + + + payment.line.search (in l10n_br_financial_payment_order) + payment.line + + + + + + + + payment.line.tree (in l10n_br_financial_payment_order) + payment.line + + + + + + + + Payment Line + payment.line + tree,form + [] + {} + + + + Payment Line + + + + + + + diff --git a/l10n_br_financial_payment_order/views/payment_mode.xml b/l10n_br_financial_payment_order/views/payment_mode.xml new file mode 100644 index 0000000..1c5de38 --- /dev/null +++ b/l10n_br_financial_payment_order/views/payment_mode.xml @@ -0,0 +1,51 @@ + + + + + + + + payment.mode.form (in l10n_br_financial_payment_order) + payment.mode + + + + + + + + payment.mode.search (in l10n_br_financial_payment_order) + payment.mode + + + + + + + + payment.mode.tree (in l10n_br_financial_payment_order) + payment.mode + + + + + + + + Payment Mode + payment.mode + tree,form + [] + {} + + + + Payment Mode + + + + + + + diff --git a/l10n_br_financial_payment_order/views/payment_mode_type.xml b/l10n_br_financial_payment_order/views/payment_mode_type.xml new file mode 100644 index 0000000..117090c --- /dev/null +++ b/l10n_br_financial_payment_order/views/payment_mode_type.xml @@ -0,0 +1,51 @@ + + + + + + + + payment.mode.type.form (in l10n_br_financial_payment_order) + payment.mode.type + + + + + + + + payment.mode.type.search (in l10n_br_financial_payment_order) + payment.mode.type + + + + + + + + payment.mode.type.tree (in l10n_br_financial_payment_order) + payment.mode.type + + + + + + + + Payment Mode Type + payment.mode.type + tree,form + [] + {} + + + + Payment Mode Type + + + + + + + diff --git a/l10n_br_financial_payment_order/views/payment_order.xml b/l10n_br_financial_payment_order/views/payment_order.xml new file mode 100644 index 0000000..3675a67 --- /dev/null +++ b/l10n_br_financial_payment_order/views/payment_order.xml @@ -0,0 +1,51 @@ + + + + + + + + payment.order.form (in l10n_br_financial_payment_order) + payment.order + + + + + + + + payment.order.search (in l10n_br_financial_payment_order) + payment.order + + + + + + + + payment.order.tree (in l10n_br_financial_payment_order) + payment.order + + + + + + + + Payment Order + payment.order + tree,form + [] + {} + + + + Payment Order + + + + + + + From 81a1bacf1477fb01a3443c5fa231d3ecd4c09930 Mon Sep 17 00:00:00 2001 From: Luis Felipe Mileo Date: Fri, 21 Jul 2017 10:25:53 -0300 Subject: [PATCH 02/60] =?UTF-8?q?[NEW]=20Inclus=C3=A3o=20de=20vis=C3=B5es?= =?UTF-8?q?=20separadas=20por=20payment=5Forder=5Ftype?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../__openerp__.py | 32 ++-- .../models/bank_payment_line.py | 4 +- .../models/payment_line.py | 2 +- .../models/payment_mode.py | 2 +- .../models/payment_mode_type.py | 2 +- .../models/payment_order.py | 7 +- .../views/payment_menu.xml | 15 ++ .../views/payment_order.xml | 51 ------ .../views/payment_order_cobranca.xml | 76 +++++++++ .../views/payment_order_debito.xml | 74 +++++++++ .../views/payment_order_pagamento.xml | 67 ++++++++ .../views/primary/payment_order.xml | 155 ++++++++++++++++++ 12 files changed, 417 insertions(+), 70 deletions(-) create mode 100644 l10n_br_financial_payment_order/views/payment_menu.xml delete mode 100644 l10n_br_financial_payment_order/views/payment_order.xml create mode 100644 l10n_br_financial_payment_order/views/payment_order_cobranca.xml create mode 100644 l10n_br_financial_payment_order/views/payment_order_debito.xml create mode 100644 l10n_br_financial_payment_order/views/payment_order_pagamento.xml create mode 100644 l10n_br_financial_payment_order/views/primary/payment_order.xml diff --git a/l10n_br_financial_payment_order/__openerp__.py b/l10n_br_financial_payment_order/__openerp__.py index 524df3a..c240c40 100644 --- a/l10n_br_financial_payment_order/__openerp__.py +++ b/l10n_br_financial_payment_order/__openerp__.py @@ -16,22 +16,26 @@ 'financial_account', ], 'data': [ - 'security/payment_mode.xml', - 'security/payment_mode_type.xml', - 'security/bank_payment_line.xml', - 'security/payment_line.xml', - 'security/payment_order.xml', + 'views/payment_menu.xml', + 'views/primary/payment_order.xml', + 'views/payment_order_cobranca.xml', + 'views/payment_order_debito.xml', + 'views/payment_order_pagamento.xml', + # 'security/payment_mode.xml', + # 'security/payment_mode_type.xml', + # 'security/bank_payment_line.xml', + # 'security/payment_line.xml', + # 'security/payment_order.xml', - 'views/payment_mode.xml', - 'views/payment_mode_type.xml', - 'views/bank_payment_line.xml', - 'views/payment_line.xml', - 'views/payment_order.xml', + # 'views/payment_mode.xml', + # 'views/payment_mode_type.xml', + # 'views/bank_payment_line.xml', + # 'views/payment_line.xml', ], 'demo': [ - 'demo/payment_mode.xml', - 'demo/payment_mode_type.xml', - 'demo/bank_payment_line.xml', - 'demo/payment_order.xml', + # 'demo/payment_mode.xml', + # 'demo/payment_mode_type.xml', + # 'demo/bank_payment_line.xml', + # 'demo/payment_order.xml', ], } diff --git a/l10n_br_financial_payment_order/models/bank_payment_line.py b/l10n_br_financial_payment_order/models/bank_payment_line.py index 4fdc47b..3322c26 100644 --- a/l10n_br_financial_payment_order/models/bank_payment_line.py +++ b/l10n_br_financial_payment_order/models/bank_payment_line.py @@ -2,12 +2,14 @@ # Copyright 2017 KMEE INFORMATICA LTDA # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). +from __future__ import division, print_function, unicode_literals + from openerp import api, fields, models, _ class BankPaymentLine(models.Model): - _inherit = 'bank.payment.line' + _inherit = b'bank.payment.line' @api.model def same_fields_payment_line_and_bank_payment_line(self): diff --git a/l10n_br_financial_payment_order/models/payment_line.py b/l10n_br_financial_payment_order/models/payment_line.py index 9034d0d..6fa86d1 100644 --- a/l10n_br_financial_payment_order/models/payment_line.py +++ b/l10n_br_financial_payment_order/models/payment_line.py @@ -10,7 +10,7 @@ class PaymentLine(models.Model): - _inherit = 'payment.line' + _inherit = b'payment.line' # @api.one # @api.depends('percent_interest', 'amount_currency') diff --git a/l10n_br_financial_payment_order/models/payment_mode.py b/l10n_br_financial_payment_order/models/payment_mode.py index d3e614a..b372ea8 100644 --- a/l10n_br_financial_payment_order/models/payment_mode.py +++ b/l10n_br_financial_payment_order/models/payment_mode.py @@ -13,7 +13,7 @@ class PaymentMode(models.Model): - _inherit = 'payment.mode' + _inherit = b'payment.mode' boleto_carteira = fields.Char('Carteira', size=3) boleto_modalidade = fields.Char('Modalidade', size=2) diff --git a/l10n_br_financial_payment_order/models/payment_mode_type.py b/l10n_br_financial_payment_order/models/payment_mode_type.py index 450e7f4..0e4a158 100644 --- a/l10n_br_financial_payment_order/models/payment_mode_type.py +++ b/l10n_br_financial_payment_order/models/payment_mode_type.py @@ -9,7 +9,7 @@ class PaymentModeType(models.Model): - _inherit = 'payment.mode.type' + _inherit = b'payment.mode.type' payment_order_type = fields.Selection( selection_add=[ diff --git a/l10n_br_financial_payment_order/models/payment_order.py b/l10n_br_financial_payment_order/models/payment_order.py index d7414c2..2fc739c 100644 --- a/l10n_br_financial_payment_order/models/payment_order.py +++ b/l10n_br_financial_payment_order/models/payment_order.py @@ -10,7 +10,12 @@ class PaymentOrder(models.Model): - _inherit = 'payment.order' + _inherit = b'payment.order' + + payment_order_type = fields.Selection( + selection_add=[ + ('cobranca', u'Cobrança'), + ]) @api.multi def action_open(self): diff --git a/l10n_br_financial_payment_order/views/payment_menu.xml b/l10n_br_financial_payment_order/views/payment_menu.xml new file mode 100644 index 0000000..af2531e --- /dev/null +++ b/l10n_br_financial_payment_order/views/payment_menu.xml @@ -0,0 +1,15 @@ + + + + + + Operações + + + + + + diff --git a/l10n_br_financial_payment_order/views/payment_order.xml b/l10n_br_financial_payment_order/views/payment_order.xml deleted file mode 100644 index 3675a67..0000000 --- a/l10n_br_financial_payment_order/views/payment_order.xml +++ /dev/null @@ -1,51 +0,0 @@ - - - - - - - - payment.order.form (in l10n_br_financial_payment_order) - payment.order - - - - - - - - payment.order.search (in l10n_br_financial_payment_order) - payment.order - - - - - - - - payment.order.tree (in l10n_br_financial_payment_order) - payment.order - - - - - - - - Payment Order - payment.order - tree,form - [] - {} - - - - Payment Order - - - - - - - diff --git a/l10n_br_financial_payment_order/views/payment_order_cobranca.xml b/l10n_br_financial_payment_order/views/payment_order_cobranca.xml new file mode 100644 index 0000000..13a6711 --- /dev/null +++ b/l10n_br_financial_payment_order/views/payment_order_cobranca.xml @@ -0,0 +1,76 @@ + + + + + + + + payment.order.cobranca.form (in l10n_br_financial_payment_order) + payment.order + primary + + + + Cobrança + + +

TODO: Importar Cobranças

+
+ +

TODO: Informações específicas

+
+
+
+ + + + + + + + + + + + + + + + + + + + + Cobrança + payment.order + tree,form + [('payment_order_type', '=', 'cobranca')] + {'default_payment_order_type': 'cobranca'} + + + + + Cobrança + + + + + + + + + form + + + + + + + tree + + + + +
+
diff --git a/l10n_br_financial_payment_order/views/payment_order_debito.xml b/l10n_br_financial_payment_order/views/payment_order_debito.xml new file mode 100644 index 0000000..2c58f33 --- /dev/null +++ b/l10n_br_financial_payment_order/views/payment_order_debito.xml @@ -0,0 +1,74 @@ + + + + + + + + payment.order.debito.form (in l10n_br_financial_payment_order) + payment.order + primary + + + + Débito + + +

TODO: Importar Débitos

+
+ +

TODO: Informações específicas

+
+
+
+ + + + + + + + + + + + + + + + + + + + + Débito + payment.order + tree,form + [('payment_order_type', '=', 'debit')] + {'default_payment_order_type': 'debit'} + + + + Débito + + + + + + + + form + + + + + + + tree + + + + +
+
diff --git a/l10n_br_financial_payment_order/views/payment_order_pagamento.xml b/l10n_br_financial_payment_order/views/payment_order_pagamento.xml new file mode 100644 index 0000000..6ac4708 --- /dev/null +++ b/l10n_br_financial_payment_order/views/payment_order_pagamento.xml @@ -0,0 +1,67 @@ + + + + + + + + payment.order.pagamento.form (in l10n_br_financial_payment_order) + payment.order + primary + + + + Pagamento + + +

TODO: Importar Pagamentos

+
+ +

TODO: Informações específicas

+
+
+
+ + + + + + + + + + + + + + + + + + + + + Pagamento + payment.order + tree,form + [('payment_order_type', '=', 'payment')] + {'default_payment_order_type': 'payment'} + + + + Pagamento + + + + + + + + tree + + + + +
+
diff --git a/l10n_br_financial_payment_order/views/primary/payment_order.xml b/l10n_br_financial_payment_order/views/primary/payment_order.xml new file mode 100644 index 0000000..e5e9d91 --- /dev/null +++ b/l10n_br_financial_payment_order/views/primary/payment_order.xml @@ -0,0 +1,155 @@ + + + + + + + + payment.order.form (in l10n_br_financial_payment_order) + payment.order + 9999 + primary + +
+
+
+ +
+
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+
+ + + payment.order.search (in l10n_br_financial_payment_order) + payment.order + 9999 + primary + + + + + + + + + + + + + + + + + + + payment.order.tree (in l10n_br_financial_payment_order) + payment.order + 9999 + primary + + + + + + + + + + + + + + +
+
From f33676b5fec189c508913f34b17fc9521fa5796f Mon Sep 17 00:00:00 2001 From: Luiz Felipe do Divino Date: Fri, 21 Jul 2017 18:36:44 -0300 Subject: [PATCH 03/60] [ADD] Gerar ordem de pagamento Holerites - Wizard para buscar os holerites para pagamento e a associacao entre o holerite e as payment.lines --- .../hr_payroll_workflow.xml | 15 +++ .../models/hr_payslip.py | 126 ++++++++++++++++++ .../views/hr_payslip.xml | 0 .../wizards/__init__.py | 0 .../wizards/ordem_pagamento_holerite.py | 0 .../ordem_pagamento_holerite_wizard.xml | 0 6 files changed, 141 insertions(+) create mode 100644 l10n_br_financial_payment_order/hr_payroll_workflow.xml create mode 100644 l10n_br_financial_payment_order/models/hr_payslip.py create mode 100644 l10n_br_financial_payment_order/views/hr_payslip.xml create mode 100644 l10n_br_financial_payment_order/wizards/__init__.py create mode 100644 l10n_br_financial_payment_order/wizards/ordem_pagamento_holerite.py create mode 100644 l10n_br_financial_payment_order/wizards/ordem_pagamento_holerite_wizard.xml diff --git a/l10n_br_financial_payment_order/hr_payroll_workflow.xml b/l10n_br_financial_payment_order/hr_payroll_workflow.xml new file mode 100644 index 0000000..6e6ccd3 --- /dev/null +++ b/l10n_br_financial_payment_order/hr_payroll_workflow.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + paid_order + + + diff --git a/l10n_br_financial_payment_order/models/hr_payslip.py b/l10n_br_financial_payment_order/models/hr_payslip.py new file mode 100644 index 0000000..befd522 --- /dev/null +++ b/l10n_br_financial_payment_order/models/hr_payslip.py @@ -0,0 +1,126 @@ +# -*- coding: utf-8 -*- +# Copyright 2017 KMEE +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from openerp import api, fields, models, _ +from openerp.exceptions import Warning as UserError + + +class HrPayslip(models.Model): + + _inherit = 'hr.payslip' + + payment_mode_id = fields.Many2one( + string="Payment Mode", + comodel_name='payment.mode', + # domain="[('type', '=', type)]" + ) + + payment_line_ids = fields.One2many( + string="Ordens de Pagamento", + comodel_name="payment.line", + inverse_name="payslip_id", + ) + + paid_order = fields.Boolean( + compute='_compute_paid', + readonly=True, + store=True, + ) + + @api.multi + def test_paid(self): + if not self.payment_line_ids: + return False + for line in self.payment_line_ids: + if not line.state2: + return False + if line.state2 != 'paid': + return False + return True + + @api.one + @api.depends('payment_line_ids.bank_line_id.state2') + def _compute_paid(self): + self.paid_order = self.test_paid() + + def _compute_set_employee_id(self): + super(HrPayslip, self)._compute_set_employee_id() + for record in self: + if record.contract_id: + partner_id = \ + record.contract_id.employee_id.parent_id.user_id.partner_id + record.payment_mode_id = partner_id.supplier_payment_mode + + @api.multi + def action_done(self): + self.write({'state': 'done'}) + return True + + def create_payorder(self, mode_payment): + ''' + Cria um payment order com base no metodo de pagamento + :param mode_payment: Modo de pagamento + :return: objeto do payment.order + ''' + payment_order_model = self.env['payment.order'] + vals = {'mode': mode_payment.id, } + return payment_order_model.create(vals) + + @api.multi + def create_payment_order_line( + self, payment_order, total, communication, partner_id): + """ + Cria a linha da ordem de pagamento + """ + payment_line_model = self.env['payment.line'] + vals = { + 'order_id': payment_order.id, + 'bank_id': self.contract_id.conta_bancaria_id.id, + 'partner_id': partner_id.id, + # 'move_line_id': self.id, + 'communication': communication, + # 'communication_type': communication_type, + # 'currency_id': currency_id, + 'amount_currency': total, + # date is set when the user confirms the payment order + 'payslip_id': self.id, + } + return payment_line_model.create(vals) + + @api.multi + def create_payment_order(self): + + payment_order_model = self.env['payment.order'] + + for holerite in self: + if holerite.state != 'draft': + raise UserError(_( + "The payslip %s is not in Open state") % + holerite.contract_id.nome_contrato) + if not holerite.payment_mode_id: + raise UserError(_( + "No Payment Mode on holerite %s") % holerite.number) + + # Buscar ordens de pagamento do mesmo tipo + payorders = payment_order_model.search([ + ('mode', '=', holerite.payment_mode_id.id), + ('state', '=', 'draft')] + ) + + if payorders: + payorder = payorders[0] + else: + payorder = self.create_payorder(holerite.payment_mode_id) + + for rubrica in holerite.line_ids: + if rubrica.code == 'LIQUIDO': + self.create_payment_order_line( + payorder, rubrica.total, + 'SALARIO ' + holerite.data_mes_ano, rubrica.partner_id) + + if rubrica.code == 'PENSAO_ALIMENTICIA': + self.create_payment_order_line( + payorder, rubrica.total, + 'PENSAO ALIMENTICIA ' + holerite.data_mes_ano, + rubrica.partner_id) diff --git a/l10n_br_financial_payment_order/views/hr_payslip.xml b/l10n_br_financial_payment_order/views/hr_payslip.xml new file mode 100644 index 0000000..e69de29 diff --git a/l10n_br_financial_payment_order/wizards/__init__.py b/l10n_br_financial_payment_order/wizards/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/l10n_br_financial_payment_order/wizards/ordem_pagamento_holerite.py b/l10n_br_financial_payment_order/wizards/ordem_pagamento_holerite.py new file mode 100644 index 0000000..e69de29 diff --git a/l10n_br_financial_payment_order/wizards/ordem_pagamento_holerite_wizard.xml b/l10n_br_financial_payment_order/wizards/ordem_pagamento_holerite_wizard.xml new file mode 100644 index 0000000..e69de29 From e68c3c96f8adce258a6ef7080758d10e15d6e2da Mon Sep 17 00:00:00 2001 From: Luiz Felipe do Divino Date: Fri, 21 Jul 2017 18:38:44 -0300 Subject: [PATCH 04/60] [REM] State da payment.line e bank.payment.line --- .../model/__init__.py | 2 +- .../model/bank_payment_line.py | 12 ------------ .../model/payment_line.py | 12 ------------ .../view/bank_payment_line.xml | 5 ----- .../view/payment_line.xml | 12 ------------ 5 files changed, 1 insertion(+), 42 deletions(-) diff --git a/l10n_br_account_banking_payment_cnab/model/__init__.py b/l10n_br_account_banking_payment_cnab/model/__init__.py index c630028..06babab 100644 --- a/l10n_br_account_banking_payment_cnab/model/__init__.py +++ b/l10n_br_account_banking_payment_cnab/model/__init__.py @@ -9,5 +9,5 @@ from . import res_partner from .. import constantes from . import payment_line -from . import bank_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 index b58ff5f..f7c4560 100644 --- a/l10n_br_account_banking_payment_cnab/model/bank_payment_line.py +++ b/l10n_br_account_banking_payment_cnab/model/bank_payment_line.py @@ -3,13 +3,6 @@ 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' @@ -82,11 +75,6 @@ def default_get(self, fields_list): 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", diff --git a/l10n_br_account_banking_payment_cnab/model/payment_line.py b/l10n_br_account_banking_payment_cnab/model/payment_line.py index 0c66474..d9f78a2 100644 --- a/l10n_br_account_banking_payment_cnab/model/payment_line.py +++ b/l10n_br_account_banking_payment_cnab/model/payment_line.py @@ -3,13 +3,6 @@ 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' @@ -87,8 +80,3 @@ def default_get(self, fields_list): 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/view/bank_payment_line.xml b/l10n_br_account_banking_payment_cnab/view/bank_payment_line.xml index 738b932..51bba21 100644 --- a/l10n_br_account_banking_payment_cnab/view/bank_payment_line.xml +++ b/l10n_br_account_banking_payment_cnab/view/bank_payment_line.xml @@ -6,11 +6,6 @@ bank.payment.line - -
- -
-
diff --git a/l10n_br_account_banking_payment_cnab/view/payment_line.xml b/l10n_br_account_banking_payment_cnab/view/payment_line.xml index bf79e1d..c5dfbf9 100644 --- a/l10n_br_account_banking_payment_cnab/view/payment_line.xml +++ b/l10n_br_account_banking_payment_cnab/view/payment_line.xml @@ -21,17 +21,5 @@ - - payment.line.form - payment.line - - - -
- -
-
-
-
\ No newline at end of file From a99cef7aa95dddb53183b1ca593c0eacd110c10a Mon Sep 17 00:00:00 2001 From: Luiz Felipe do Divino Date: Fri, 21 Jul 2017 18:39:31 -0300 Subject: [PATCH 05/60] [ADD] Workflow do pagamento de folha de pagamento --- l10n_br_financial_payment_order/__init__.py | 1 + .../__openerp__.py | 5 + .../models/__init__.py | 1 + .../models/bank_payment_line.py | 17 +++ .../models/hr_payslip.py | 8 - .../models/payment_line.py | 12 +- .../models/payment_order.py | 37 +++++ .../views/bank_payment_line.xml | 83 ++++++----- .../views/hr_payslip.xml | 40 +++++ .../views/payment_line.xml | 8 +- .../views/payment_order_pagamento.xml | 13 +- .../wizards/__init__.py | 1 + .../wizards/ordem_pagamento_holerite.py | 139 ++++++++++++++++++ .../ordem_pagamento_holerite_wizard.xml | 66 +++++++++ 14 files changed, 380 insertions(+), 51 deletions(-) diff --git a/l10n_br_financial_payment_order/__init__.py b/l10n_br_financial_payment_order/__init__.py index 0650744..aee8895 100644 --- a/l10n_br_financial_payment_order/__init__.py +++ b/l10n_br_financial_payment_order/__init__.py @@ -1 +1,2 @@ from . import models +from . import wizards diff --git a/l10n_br_financial_payment_order/__openerp__.py b/l10n_br_financial_payment_order/__openerp__.py index c240c40..164f244 100644 --- a/l10n_br_financial_payment_order/__openerp__.py +++ b/l10n_br_financial_payment_order/__openerp__.py @@ -14,13 +14,18 @@ 'account_banking_payment_export', 'l10n_br_account_product', 'financial_account', + 'l10n_br_hr_payroll', ], 'data': [ + 'wizards/ordem_pagamento_holerite_wizard.xml', 'views/payment_menu.xml', 'views/primary/payment_order.xml', 'views/payment_order_cobranca.xml', 'views/payment_order_debito.xml', 'views/payment_order_pagamento.xml', + 'views/bank_payment_line.xml', + 'views/hr_payslip.xml', + 'hr_payroll_workflow.xml', # 'security/payment_mode.xml', # 'security/payment_mode_type.xml', # 'security/bank_payment_line.xml', diff --git a/l10n_br_financial_payment_order/models/__init__.py b/l10n_br_financial_payment_order/models/__init__.py index d674af8..3b70e19 100644 --- a/l10n_br_financial_payment_order/models/__init__.py +++ b/l10n_br_financial_payment_order/models/__init__.py @@ -2,3 +2,4 @@ from . import payment_line from . import bank_payment_line from . import payment_mode_type +from . import hr_payslip diff --git a/l10n_br_financial_payment_order/models/bank_payment_line.py b/l10n_br_financial_payment_order/models/bank_payment_line.py index 3322c26..9639991 100644 --- a/l10n_br_financial_payment_order/models/bank_payment_line.py +++ b/l10n_br_financial_payment_order/models/bank_payment_line.py @@ -6,11 +6,28 @@ from openerp import api, fields, models, _ +STATE = [ + ('draft', 'Draft'), + ('wait', 'Waiting Paiment'), + ('exception', 'Exception'), + ('paid', 'Paid'), +] + class BankPaymentLine(models.Model): _inherit = b'bank.payment.line' + state2 = fields.Selection( + string="State", + selection=STATE, + default="draft", + ) + + @api.multi + def set_paid(self): + self.write({'state2': 'paid'}) + @api.model def same_fields_payment_line_and_bank_payment_line(self): """ diff --git a/l10n_br_financial_payment_order/models/hr_payslip.py b/l10n_br_financial_payment_order/models/hr_payslip.py index befd522..1ae26d2 100644 --- a/l10n_br_financial_payment_order/models/hr_payslip.py +++ b/l10n_br_financial_payment_order/models/hr_payslip.py @@ -44,14 +44,6 @@ def test_paid(self): def _compute_paid(self): self.paid_order = self.test_paid() - def _compute_set_employee_id(self): - super(HrPayslip, self)._compute_set_employee_id() - for record in self: - if record.contract_id: - partner_id = \ - record.contract_id.employee_id.parent_id.user_id.partner_id - record.payment_mode_id = partner_id.supplier_payment_mode - @api.multi def action_done(self): self.write({'state': 'done'}) diff --git a/l10n_br_financial_payment_order/models/payment_line.py b/l10n_br_financial_payment_order/models/payment_line.py index 6fa86d1..ad543bc 100644 --- a/l10n_br_financial_payment_order/models/payment_line.py +++ b/l10n_br_financial_payment_order/models/payment_line.py @@ -6,6 +6,8 @@ from openerp import api, fields, models, _ +from openerp.addons.l10n_br_financial_payment_order.models.bank_payment_line \ + import STATE class PaymentLine(models.Model): @@ -33,8 +35,16 @@ class PaymentLine(models.Model): string='Valor Multa', ) # TODO: Definir campos do segmento P/Q/R/T/U - + payslip_id = fields.Many2one( + string="Ref do Holerite", + comodel_name="hr.payslip", + ) linha_digitavel = fields.Char(string=u"Linha Digitável") + state2 = fields.Selection( + related="bank_line_id.state2", + selection=STATE, + default="draft", + ) def _get_info_partner(self, cr, uid, partner_record, context=None): # TODO: Melhorar este método diff --git a/l10n_br_financial_payment_order/models/payment_order.py b/l10n_br_financial_payment_order/models/payment_order.py index 2fc739c..fc2ff01 100644 --- a/l10n_br_financial_payment_order/models/payment_order.py +++ b/l10n_br_financial_payment_order/models/payment_order.py @@ -6,6 +6,7 @@ from openerp import api, fields, models, _ from openerp.exceptions import ValidationError +from openerp.addons.l10n_br_hr_payroll.models.hr_payslip import TIPO_DE_FOLHA class PaymentOrder(models.Model): @@ -17,6 +18,12 @@ class PaymentOrder(models.Model): ('cobranca', u'Cobrança'), ]) + tipo_de_folha = fields.Selection( + selection=TIPO_DE_FOLHA, + string=u'Tipo de folha', + default='normal', + ) + @api.multi def action_open(self): """ @@ -28,3 +35,33 @@ def action_open(self): _("Impossivel confirmar linha vazia!")) res = super(PaymentOrder, self).action_open() return res + + @api.multi + def cancel(self): + for line in self.line_ids: + if line.payslip_id: + line.write({'payslip_id': ''}) + self.write({'state': 'cancel'}) + return True + + @api.multi + def buscar_holerites_wizard(self): + context = dict(self.env.context) + context.update({ + 'active_id': self.id, + }) + form = self.env.ref( + 'l10n_br_financial_payment_order.' + 'payslip_payment_create_order_view', + True + ) + return { + 'view_type': 'form', + 'view_id': [form.id], + 'view_mode': 'form', + 'res_model': 'payslip.payment.order.created', + 'views': [(form.id, 'form')], + 'type': 'ir.actions.act_window', + 'target': 'new', + 'context': context, + } diff --git a/l10n_br_financial_payment_order/views/bank_payment_line.xml b/l10n_br_financial_payment_order/views/bank_payment_line.xml index 1e9bf9b..6a94875 100644 --- a/l10n_br_financial_payment_order/views/bank_payment_line.xml +++ b/l10n_br_financial_payment_order/views/bank_payment_line.xml @@ -3,49 +3,54 @@ License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). --> - + - - bank.payment.line.form (in l10n_br_financial_payment_order) - bank.payment.line - - - - - + + bank.payment.line.form (in l10n_br_financial_payment_order) + bank.payment.line + + + +
+
+
+
+
- - bank.payment.line.search (in l10n_br_financial_payment_order) - bank.payment.line - - - - - + + + + + + + + - - bank.payment.line.tree (in l10n_br_financial_payment_order) - bank.payment.line - - - - - + + + + + + + + - - Bank Payment Line - bank.payment.line - tree,form - [] - {} - + + + + + + + - - Bank Payment Line - - - - + + + + + + -
+
diff --git a/l10n_br_financial_payment_order/views/hr_payslip.xml b/l10n_br_financial_payment_order/views/hr_payslip.xml index e69de29..b1a7683 100644 --- a/l10n_br_financial_payment_order/views/hr_payslip.xml +++ b/l10n_br_financial_payment_order/views/hr_payslip.xml @@ -0,0 +1,40 @@ + + + + + + + + hr.payslip.form (in l10n_br_hr_payment_order) + hr.payslip + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/l10n_br_financial_payment_order/views/payment_line.xml b/l10n_br_financial_payment_order/views/payment_line.xml index 6697108..614fd83 100644 --- a/l10n_br_financial_payment_order/views/payment_line.xml +++ b/l10n_br_financial_payment_order/views/payment_line.xml @@ -8,9 +8,13 @@ payment.line.form (in l10n_br_financial_payment_order) payment.line - + - + +
+ +
+
diff --git a/l10n_br_financial_payment_order/views/payment_order_pagamento.xml b/l10n_br_financial_payment_order/views/payment_order_pagamento.xml index 6ac4708..771fb3f 100644 --- a/l10n_br_financial_payment_order/views/payment_order_pagamento.xml +++ b/l10n_br_financial_payment_order/views/payment_order_pagamento.xml @@ -15,11 +15,15 @@ Pagamento -

TODO: Importar Pagamentos

+ +
+ + + + From 7b405532fe1cb18560652915c7513ed2bebc9f2f Mon Sep 17 00:00:00 2001 From: Luis Felipe Mileo Date: Sun, 23 Jul 2017 01:52:40 -0300 Subject: [PATCH 28/60] =?UTF-8?q?[NEW]=20Importa=C3=A7=C3=A3o=20de=20payme?= =?UTF-8?q?nt.lines=20a=20partir=20de=20financial.moves?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../models/inherited_payment_order.py | 151 +++++++++++++++++- .../models/operacoes/cobranca.py | 32 ++-- .../payment_order/payment_order_base_view.xml | 6 +- 3 files changed, 168 insertions(+), 21 deletions(-) diff --git a/l10n_br_financial_payment_order/models/inherited_payment_order.py b/l10n_br_financial_payment_order/models/inherited_payment_order.py index 852dbf2..e3d084c 100644 --- a/l10n_br_financial_payment_order/models/inherited_payment_order.py +++ b/l10n_br_financial_payment_order/models/inherited_payment_order.py @@ -7,8 +7,15 @@ from openerp import api, fields, models, _ from openerp.exceptions import ValidationError # from openerp.addons.l10n_br_hr_payroll.models.hr_payslip import TIPO_DE_FOLHA - -from ..constantes import TIPO_ORDEM_PAGAMENTO +from openerp.addons.financial.constants import ( + FINANCIAL_DEBT_2RECEIVE, + FINANCIAL_DEBT_2PAY, +) +from ..constantes import ( + TIPO_ORDEM_PAGAMENTO, + TIPO_ORDEM_PAGAMENTO_BOLETO, + TIPO_ORDEM_PAGAMENTO_PAGAMENTO +) class PaymentOrder(models.Model): @@ -66,9 +73,147 @@ def cancel(self): self.write({'state': 'cancel'}) return True + @api.multi + def _prepare_financial_payment_line(self, line): + """This function is designed to be inherited + The resulting dict is passed to the create method of payment.line""" + + self.ensure_one() + _today = fields.Date.context_today(self) + date_to_pay = False # no payment date => immediate payment + + if self.date_prefered == 'due': + # + # Caso a data preferida seja a data de vencimento + # + + # + # TODO: Verificar o que fazer com lançamentos vencidos + # + + date_to_pay = ( + line.date_maturity + if line.date_maturity and line.date_maturity > _today + else False) + + elif self.date_prefered == 'fixed': + # + # Caso da data preferida seja uma data fixa e esta data seja maior + # que a data de hoje. + # + date_to_pay = ( + self.date_scheduled + if self.date_scheduled and self.date_scheduled > _today + else False) + + state = 'normal' + communication = line.display_name or '-' + # communication = line.ref or '-' + # TODO: + # - Implementar novamente o campo ref? Pois o display name pode + # ser alterado + # - Como devemos lidar com um deposito identificado? + # - Podemos inserir com uma moeda diferente da ordem de pagamento? + # + + amount_currency = line.amount_document + + # TODO: Devemos expressar o valor com sinal negativo em alguns casos? + # if self.payment_order_type == 'debit': + # amount_currency *= -1 + # + + # + # Método para buscar a conta bancária aplicável a operação: + # - Exemplo de um caso de uso possível: + # - O funcionário tem 2 contas, mas ao receber o seu salário, + # o valor deve ser depositado na conta salário + + # line2bank = line.line2bank(self.mode.id) + + res = { + 'financial_id': line.id, + 'amount_currency': amount_currency, + # 'bank_id': line2bank.get(line.id), + 'order_id': self.id, + 'partner_id': line.partner_id and line.partner_id.id or False, + 'communication': communication, + 'state': state, + 'date': date_to_pay, + 'currency': (line.currency_id and line.currency_id.id or + line.journal_id.currency.id or + line.journal_id.company_id.currency_id.id) + } + return res + + @api.multi + def filter_financial_lines(self, lines): + """ Filter move lines before proposing them for inclusion + in the payment order. + + This implementation filters out financial lines that are already + included in draft or open payment orders. This prevents the + user to include the same line in two different open payment + orders. + + See also https://github.com/OCA/bank-payment/issues/93. + + :param lines: recordset of move lines + :returns: list of move line ids + """ + self.ensure_one() + to_exclude = self.env['payment.line']. \ + search([('order_id.state', 'in', ('draft', 'open')), + ('financial_id', 'in', lines.ids)]).mapped('financial_id') + + # TODO: Verificar quando podemos incluir duas vezes um financial_move. + + return lines - to_exclude + + @api.multi + def extend_payment_order_domain(self, domain): + self.ensure_one() + + domain += [ + ('company_id', '=', self.company_id.id), + # ('amount_residual', '>', 0), # FIXME + ] + + if self.mode.tipo_pagamento == TIPO_ORDEM_PAGAMENTO_BOLETO: + domain += [ + ('payment_mode_id', '=', self.mode.id), + ('type', '=', FINANCIAL_DEBT_2RECEIVE), + ] + elif self.mode.tipo_pagamento == TIPO_ORDEM_PAGAMENTO_PAGAMENTO: + domain += [ + ('type', '=', FINANCIAL_DEBT_2PAY), + ] + else: + raise NotImplemented + @api.one def financial_payment_import(self): - print ("dummy") + """ + 1. Buscar + 2. Extender + 3. Filtrar + 4. Preparar + 5. Criar + + :return: + """ + payment_line_obj = self.env['payment.line'] + + domain = [] + + self.extend_payment_order_domain(domain) + lines = self.env['financial.move'].search(domain) + filtered_lines = self.filter_financial_lines(lines) + + for line in filtered_lines: + vals = self._prepare_financial_payment_line(line) + payment_line_obj.create(vals) + return diff --git a/l10n_br_financial_payment_order/models/operacoes/cobranca.py b/l10n_br_financial_payment_order/models/operacoes/cobranca.py index 36a336f..bc89d09 100644 --- a/l10n_br_financial_payment_order/models/operacoes/cobranca.py +++ b/l10n_br_financial_payment_order/models/operacoes/cobranca.py @@ -12,18 +12,20 @@ class PaymentOrder(models.Model): _inherit = b'payment.order' - def financial_payment_import(self): - self.ensure_one() - - if self.tipo_pagamento == 'cobranca': - financial_move_ids = self.env['financial.move'].search([ - ('company_id', '=', self.company_id.id), - ('type', '=', FINANCIAL_DEBT_2RECEIVE), - # ('document_type_id', '=', ) - ]) - - print (financial_move_ids) - - result = super(PaymentOrder, self).financial_payment_import() - - return result \ No newline at end of file + # @api.one + # def financial_payment_import(self): + # self.ensure_one() + # + # if self.tipo_pagamento == 'cobranca': + # financial_move_ids = self.env['financial.move'].search([ + # ('company_id', '=', self.company_id.id), + # ('type', '=', FINANCIAL_DEBT_2RECEIVE), + # ('payment_mode_id', '=', self.mode.id), + # # ('document_type_id', '=', ) + # ]) + # + # print (financial_move_ids) + # + # result = super(PaymentOrder, self).financial_payment_import() + # + # return result \ No newline at end of file diff --git a/l10n_br_financial_payment_order/views/payment_order/payment_order_base_view.xml b/l10n_br_financial_payment_order/views/payment_order/payment_order_base_view.xml index 41512c0..08de31b 100644 --- a/l10n_br_financial_payment_order/views/payment_order/payment_order_base_view.xml +++ b/l10n_br_financial_payment_order/views/payment_order/payment_order_base_view.xml @@ -46,7 +46,7 @@
@@ -104,8 +104,8 @@ - - + + From 8bddd14e92f65486b027e2a151744fc8634396ab Mon Sep 17 00:00:00 2001 From: Luis Felipe Mileo Date: Sun, 23 Jul 2017 19:22:26 -0300 Subject: [PATCH 29/60] [NEW] Payment Order mail.thread and ir.needaction_mixin --- .../models/inherited_payment_order.py | 3 ++- .../views/payment_order/payment_order_base_view.xml | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/l10n_br_financial_payment_order/models/inherited_payment_order.py b/l10n_br_financial_payment_order/models/inherited_payment_order.py index e3d084c..dad430e 100644 --- a/l10n_br_financial_payment_order/models/inherited_payment_order.py +++ b/l10n_br_financial_payment_order/models/inherited_payment_order.py @@ -20,7 +20,8 @@ class PaymentOrder(models.Model): - _inherit = b'payment.order' + _name = b'payment.order' + _inherit = ['payment.order', 'mail.thread', 'ir.needaction_mixin'] tipo_pagamento = fields.Selection( string="Tipos de Ordem de Pagamento", diff --git a/l10n_br_financial_payment_order/views/payment_order/payment_order_base_view.xml b/l10n_br_financial_payment_order/views/payment_order/payment_order_base_view.xml index 08de31b..5a0bbb9 100644 --- a/l10n_br_financial_payment_order/views/payment_order/payment_order_base_view.xml +++ b/l10n_br_financial_payment_order/views/payment_order/payment_order_base_view.xml @@ -130,6 +130,10 @@ +
+ + +
From ed282404914c88d03396267d86b1b1c233339563 Mon Sep 17 00:00:00 2001 From: Luis Felipe Mileo Date: Sun, 23 Jul 2017 19:23:15 -0300 Subject: [PATCH 30/60] [REF] Readonly states --- .../models/inherited_payment_order.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/l10n_br_financial_payment_order/models/inherited_payment_order.py b/l10n_br_financial_payment_order/models/inherited_payment_order.py index dad430e..ce1258f 100644 --- a/l10n_br_financial_payment_order/models/inherited_payment_order.py +++ b/l10n_br_financial_payment_order/models/inherited_payment_order.py @@ -31,11 +31,11 @@ class PaymentOrder(models.Model): ) search_date_start = fields.Date( string="De", - states={'done': [('readonly', True)]}, + states={'draft': [('readonly', False)]}, ) search_date_stop = fields.Date( string="Até", - states={'done': [('readonly', True)]}, + states={'draft': [('readonly', False)]}, ) search_date_type = fields.Selection( selection=[ @@ -44,9 +44,8 @@ class PaymentOrder(models.Model): ('date_business_maturity', 'Vencimento útil'), ('date_payment', 'Pagamento'), ], - default='date_document', string="Data", - states={'done': [('readonly', True)]}, + states={'draft': [('readonly', False)]}, ) # tipo_de_folha = fields.Selection( # selection=TIPO_DE_FOLHA, From 68f85144350868de8b062ec91e2c5e5a0198f41d Mon Sep 17 00:00:00 2001 From: Luis Felipe Mileo Date: Sun, 23 Jul 2017 19:24:11 -0300 Subject: [PATCH 31/60] [REF] Melhorias na payment order --- .../models/inherited_payment_order.py | 27 ++++++++++++++----- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/l10n_br_financial_payment_order/models/inherited_payment_order.py b/l10n_br_financial_payment_order/models/inherited_payment_order.py index ce1258f..7d302f5 100644 --- a/l10n_br_financial_payment_order/models/inherited_payment_order.py +++ b/l10n_br_financial_payment_order/models/inherited_payment_order.py @@ -179,6 +179,14 @@ def extend_payment_order_domain(self, domain): # ('amount_residual', '>', 0), # FIXME ] + if self.search_date_start: + domain += [ + (self.search_date_type, '>=', self.search_date_start), + ] + if self.search_date_stop: + domain += [ + (self.search_date_type, '<=', self.search_date_stop), + ] if self.mode.tipo_pagamento == TIPO_ORDEM_PAGAMENTO_BOLETO: domain += [ ('payment_mode_id', '=', self.mode.id), @@ -193,16 +201,21 @@ def extend_payment_order_domain(self, domain): @api.one def financial_payment_import(self): - """ - 1. Buscar - 2. Extender - 3. Filtrar - 4. Preparar + """ A importação de lançamentos financeiros nas payment orders + funciona da seguinte maneira: + + 1. Prepara o dominio de busca: extend_payment_order_domain + 2. Realiza a busca + 3. Filtrar os registros já inseridos em payment.orders: + filter_financial_lines + 4. Preparar: Prepara os dados para inclusão: + _prepare_financial_payment_line 5. Criar :return: """ - payment_line_obj = self.env['payment.line'] + + self.line_ids.unlink() domain = [] @@ -212,7 +225,7 @@ def financial_payment_import(self): for line in filtered_lines: vals = self._prepare_financial_payment_line(line) - payment_line_obj.create(vals) + self.line_ids.create(vals) return From 47e1aa9955b5b7039732f5047c548a0a6eef4d42 Mon Sep 17 00:00:00 2001 From: Luis Felipe Mileo Date: Sun, 23 Jul 2017 22:14:11 -0300 Subject: [PATCH 32/60] =?UTF-8?q?[IMP]=20Integra=C3=A7=C3=A3o=20banc=C3=A1?= =?UTF-8?q?ria:=20Campos=20do=20financeiro=20nas=20linhas?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../models/inherited_payment_order.py | 4 +- .../models/payment_line.py | 58 +++++++++++++++++++ .../payment_order/payment_order_base_view.xml | 39 +++++++------ .../payment_order_cobranca_view.xml | 4 +- .../payment_order_pagamento_view.xml | 5 +- 5 files changed, 85 insertions(+), 25 deletions(-) diff --git a/l10n_br_financial_payment_order/models/inherited_payment_order.py b/l10n_br_financial_payment_order/models/inherited_payment_order.py index 7d302f5..092e57b 100644 --- a/l10n_br_financial_payment_order/models/inherited_payment_order.py +++ b/l10n_br_financial_payment_order/models/inherited_payment_order.py @@ -107,7 +107,7 @@ def _prepare_financial_payment_line(self, line): else False) state = 'normal' - communication = line.display_name or '-' + communication = line.document_number or '-' # communication = line.ref or '-' # TODO: # - Implementar novamente o campo ref? Pois o display name pode @@ -116,7 +116,7 @@ def _prepare_financial_payment_line(self, line): # - Podemos inserir com uma moeda diferente da ordem de pagamento? # - amount_currency = line.amount_document + amount_currency = line.amount_residual # TODO: Devemos expressar o valor com sinal negativo em alguns casos? # if self.payment_order_type == 'debit': diff --git a/l10n_br_financial_payment_order/models/payment_line.py b/l10n_br_financial_payment_order/models/payment_line.py index f32c851..ce688ba 100644 --- a/l10n_br_financial_payment_order/models/payment_line.py +++ b/l10n_br_financial_payment_order/models/payment_line.py @@ -10,6 +10,8 @@ import STATE + + class PaymentLine(models.Model): _inherit = b'payment.line' @@ -21,6 +23,26 @@ class PaymentLine(models.Model): # (self.percent_interest / 100), # precision) + def _get_payment_line_reference(self): + return [ + ( + self.env['financial.move']._name, + self.env['financial.move']._description + ), + ] + + @api.multi + @api.depends('financial_id') + def _compute_reference_id(self): + + for record in self: + if record.financial_id: + record.reference_id = ( + record.financial_id._name + + ',' + + str(record.financial_id.id) + ) + amount_other_discounts = fields.Float( string='Valor Abatimento', ) @@ -45,10 +67,46 @@ class PaymentLine(models.Model): default="draft", ) + reference_id = fields.Reference( + compute='_compute_reference_id', + selection=_get_payment_line_reference, + string='Origem' + ) + financial_id = fields.Many2one( comodel_name='financial.move', string="Financeiro", ) + fn_date_document = fields.Date( + related='financial_id.date_document', + string="Criação", + readonly=True, + ) + fn_date_maturity = fields.Date( + related='financial_id.date_maturity', + string='Vencimento', + readonly=True, + ) + fn_date_business_maturity = fields.Date( + related='financial_id.date_business_maturity', + string='Vencimento útil', + readonly=True, + ) + fn_boleto_linha_digitavel = fields.Char( + related='financial_id.boleto_linha_digitavel', + string='Linha digitável', + readonly=True, + ) + fb_boleto_codigo_barras = fields.Char( + related='financial_id.boleto_codigo_barras', + string='Código de barras', + readonly=True, + ) + fn_nosso_numero = fields.Float( + string='Nosso número', + related='financial_id.nosso_numero', + ) + def _get_info_partner(self, cr, uid, partner_record, context=None): # TODO: Melhorar este método diff --git a/l10n_br_financial_payment_order/views/payment_order/payment_order_base_view.xml b/l10n_br_financial_payment_order/views/payment_order/payment_order_base_view.xml index 5a0bbb9..6cb5268 100644 --- a/l10n_br_financial_payment_order/views/payment_order/payment_order_base_view.xml +++ b/l10n_br_financial_payment_order/views/payment_order/payment_order_base_view.xml @@ -74,6 +74,10 @@ + + + + @@ -84,39 +88,36 @@ - - - - - - - - + + + + + - - + + - + - + @@ -125,9 +126,9 @@ - - - + + +
diff --git a/l10n_br_financial_payment_order/views/payment_order/payment_order_cobranca_view.xml b/l10n_br_financial_payment_order/views/payment_order/payment_order_cobranca_view.xml index 7f489a6..b78d681 100644 --- a/l10n_br_financial_payment_order/views/payment_order/payment_order_cobranca_view.xml +++ b/l10n_br_financial_payment_order/views/payment_order/payment_order_cobranca_view.xml @@ -25,10 +25,10 @@
-

TODO: Informações específicas

+
-

TODO: Informações específicas

+
diff --git a/l10n_br_financial_payment_order/views/payment_order/payment_order_pagamento_view.xml b/l10n_br_financial_payment_order/views/payment_order/payment_order_pagamento_view.xml index 0eb40f3..2e2e64d 100644 --- a/l10n_br_financial_payment_order/views/payment_order/payment_order_pagamento_view.xml +++ b/l10n_br_financial_payment_order/views/payment_order/payment_order_pagamento_view.xml @@ -15,10 +15,11 @@ Pagamento -

TODO: Informações específicas

+
-

TODO: Informações específicas

+ +
From 9b841803ae9975c61fac2745410fa75626acf83d Mon Sep 17 00:00:00 2001 From: Hendrix Costa Date: Sun, 23 Jul 2017 22:13:58 -0300 Subject: [PATCH 33/60] =?UTF-8?q?[FIX]=20Rename=20arquivos=20da=20integra?= =?UTF-8?q?=C3=A7=C3=A3o=20bancaraia=20[ADD]=20Campos=20auxiliares=20[ADD]?= =?UTF-8?q?=20Valida=C3=A7=C3=B5es=20para=20importa=C3=A7=C3=A3o=20do=20re?= =?UTF-8?q?torno?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../__openerp__.py | 2 +- .../models/__init__.py | 2 +- ..._cnab.py => financial_retorno_bancario.py} | 309 ++++++++++++------ ...nab.xml => financial_retorno_bancario.xml} | 46 ++- 4 files changed, 235 insertions(+), 124 deletions(-) rename l10n_br_financial_payment_order/models/{l10n_br_cnab.py => financial_retorno_bancario.py} (59%) rename l10n_br_financial_payment_order/views/{l10n_br_cnab.xml => financial_retorno_bancario.xml} (80%) diff --git a/l10n_br_financial_payment_order/__openerp__.py b/l10n_br_financial_payment_order/__openerp__.py index a7a98b4..41de7b3 100644 --- a/l10n_br_financial_payment_order/__openerp__.py +++ b/l10n_br_financial_payment_order/__openerp__.py @@ -31,7 +31,7 @@ 'views/payment_order/payment_order_cobranca_view.xml', 'views/payment_order/payment_order_pagamento_view.xml', - 'views/l10n_br_cnab.xml', + 'views/financial_retorno_bancario.xml', 'views/financial_move.xml', # 'security/payment_mode.xml', # 'security/payment_mode_type.xml', diff --git a/l10n_br_financial_payment_order/models/__init__.py b/l10n_br_financial_payment_order/models/__init__.py index 73dec7e..65f75e6 100644 --- a/l10n_br_financial_payment_order/models/__init__.py +++ b/l10n_br_financial_payment_order/models/__init__.py @@ -14,4 +14,4 @@ # from . import inherited_payment_order from . import operacoes -from . import l10n_br_cnab +from . import financial_retorno_bancario diff --git a/l10n_br_financial_payment_order/models/l10n_br_cnab.py b/l10n_br_financial_payment_order/models/financial_retorno_bancario.py similarity index 59% rename from l10n_br_financial_payment_order/models/l10n_br_cnab.py rename to l10n_br_financial_payment_order/models/financial_retorno_bancario.py index 4a58353..a26a9bc 100644 --- a/l10n_br_financial_payment_order/models/l10n_br_cnab.py +++ b/l10n_br_financial_payment_order/models/financial_retorno_bancario.py @@ -1,7 +1,9 @@ # -*- coding: utf-8 -*- -# Copyright 2017 KMEE - Luiz Felipe do Divino Costa +# Copyright 2017 KMEE INFORMATICA LTDA # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). +from __future__ import division, print_function, unicode_literals + import base64 import codecs import logging @@ -14,6 +16,7 @@ try: from cnab240.bancos import bancodobrasil from cnab240.tipos import Arquivo + from pybrasil import data except ImportError as err: _logger.debug = (err) @@ -77,35 +80,119 @@ } -class L10nBrCnab(models.Model): - _name = "l10n.br.cnab" - _rec_name = "display_name" +class FinancialRetornoBancario(models.Model): + _name = b'financial.retorno.bancario' + _rec_name = 'name' + + name = fields.Char(string='Nome') + + data_arquivo = fields.Datetime(string='Data Criação no Banco') + + num_lotes = fields.Integer(string='Número de Lotes') + + num_eventos = fields.Integer(string='Número de Eventos') + codigo_convenio = fields.Char(string='Código Convenio') + + # data = fields.Date( + # string='Data CNAB', + # # required=True, + # # default=datetime.now(), + # ) + + arquivo_retorno = fields.Binary( + string='Arquivo Retorno', + required=True, + ) + + lote_id = fields.One2many( + string='Lotes', + comodel_name='financial.retorno.bancario.lote', + inverse_name='cnab_id', + ) + + evento_id = fields.One2many( + string='Eventos', + comodel_name='financial.retorno.bancario.evento', + inverse_name='cnab_id', + ) + + state = fields.Selection( + string=u"Estágio", + selection=STATE, + default="draft", + ) + + bank_account_id = fields.Many2one( + string="Conta cedente", + comodel_name="res.partner.bank", + ) + + payment_mode_id = fields.Many2one( + string='Integração Bancária', + comodel_name='payment.mode', + ) + @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('Este não é um arquivo de retorno!') + + self.codigo_convenio = arquivo_parser.header.cedente_convenio + # Buscar payment_mode + + payment_mode = self.env['payment.mode'].search([ + ('convenio', '=', self.codigo_convenio)] + ) + + if len(payment_mode) < 1: + raise exceptions.Warning( + 'Não encontrado nenhuma integração bancária com código de ' + 'Convênio %s ' % self.codigo_convenio) + + if len(payment_mode) > 1: raise exceptions.Warning( - u"Este não é um arquivo de retorno!" - ) + 'Código de Convênio em duplicidade nas integrações bancárias') + + if arquivo_parser.header.cedente_conta != \ + int(payment_mode.bank_id.acc_number): + raise exceptions.Warning( + 'Conta do beneficiário não encontrado no payment_mode.') + + self.payment_mode_id = payment_mode + self.num_lotes = arquivo_parser.trailer.totais_quantidade_lotes + self.num_eventos = arquivo_parser.trailer.totais_quantidade_registros + 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] ) + + # Nome do arquivo + self.name = str(arquivo_parser.header.arquivo_sequencia) + \ + ' Retorno de ' + payment_mode.tipo_pagamento + ' ' + \ + data.formata_data(self.data_arquivo) + + # Busca o cedente/beneficiario do arquivo baseado no numero da conta 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: + # Busca o beneficiario do lote baseado no numero da conta 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': @@ -120,33 +207,44 @@ def processar_arquivo_retorno(self): 'total_valores': float(lote.trailer.somatoria_valores), 'cnab_id': self.id, } - lote_id = self.env['l10n.br.cnab.lote'].create(vals) + + lote_id = self.env['financial.retorno.bancario.lote'].create(vals) + for evento in lote.eventos: - data_evento = str( - evento.credito_data_real) + + 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) - ]) + + # Busca a conta do benefiario do evento baseado em sua conta + 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( + + account_bank_id_infos = \ + 'Agência: ' + str(evento.favorecido_agencia) +\ + '-' + str(evento.favorecido_agencia_dv) + \ + '\nConta: ' + str(evento.favorecido_conta) + \ + '-' + str(evento.favorecido_conta_dv) + + favorecido_partner_id = 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) - ] - ) + favorecido_partner_id = favorecido_partner_id[0].partner_id.id \ + if favorecido_partner_id else False + + # Busca o bank payment line relativo à remessa enviada + 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], @@ -158,8 +256,10 @@ def processar_arquivo_retorno(self): vals_evento = { 'data_real_pagamento': data_evento, 'segmento': evento.servico_segmento, - 'favorecido_nome': favorecido_partner, - 'favorecido_conta_bancaria': account_bank_id_lote, + 'favorecido_nome': evento.favorecido_nome, + 'favorecido_partner_id': favorecido_partner_id, + 'favorecido_conta_bancaria': account_bank_id_infos, + 'favorecido_conta_bancaria_id': account_bank_id_lote, 'nosso_numero': str(evento.credito_nosso_numero), 'seu_numero': evento.credito_seu_numero, 'tipo_moeda': evento.credito_moeda_tipo, @@ -177,8 +277,9 @@ def processar_arquivo_retorno(self): ocorrencias[4] else '', 'lote_id': lote_id.id, 'bank_payment_line_id': bank_payment_line_id.id, + 'cnab_id': self.id, } - self.env['l10n.br.cnab.evento'].create(vals_evento) + self.env['financial.retorno.bancario.evento'].create(vals_evento) if evento.ocorrencias and bank_payment_line_id: if '00' in ocorrencias: bank_payment_line_id.write({'state2': 'paid'}) @@ -187,60 +288,23 @@ def processar_arquivo_retorno(self): 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.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(FinancialRetornoBancario, self).create(vals) - @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 FinancialRetornoBancarioLote(models.Model): + _name = b'financial.retorno.bancario.lote' -class L10nBrCnabLote(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") @@ -248,15 +312,23 @@ class L10nBrCnabLote(models.Model): mensagem = fields.Char(string="Mensagem") qtd_registros = fields.Integer(string="Quantidade de Registros") total_valores = fields.Float(string="Valor Total") + + account_bank_id = fields.Many2one( + string=u"Conta Bancária", + comodel_name="res.partner.bank", + ) + evento_id = fields.One2many( string="Eventos", - comodel_name="l10n.br.cnab.evento", + comodel_name="financial.retorno.bancario.evento", inverse_name="lote_id", ) + cnab_id = fields.Many2one( string="CNAB", - comodel_name="l10n.br.cnab" + comodel_name="financial.retorno.bancario" ) + state = fields.Selection( string="State", related="cnab_id.state", @@ -265,40 +337,61 @@ class L10nBrCnabLote(models.Model): ) -class L10nBrCnabEvento(models.Model): - _name = "l10n.br.cnab.evento" +class FinancialRetornoBancarioEvento(models.Model): + _name = b'financial.retorno.bancario.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") + data_real_pagamento = fields.Datetime(string='Data Real do Pagamento') + + segmento = fields.Char(string='Segmento') + + 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') + + state = fields.Selection( + string='State', + related='lote_id.state', + selection=STATE, + default='draft', + ) + + favorecido_nome = fields.Char(string='Nome Favorecido') + + favorecido_partner_id = fields.Many2one( + string="Favorecido", + comodel_name="res.partner" + ) + + favorecido_conta_bancaria_id = fields.Many2one( + string='Conta Bancária', + comodel_name='res.partner.bank', + ) + + favorecido_conta_bancaria = fields.Char(string='Conta Bancária') + bank_payment_line_id = fields.Many2one( - string="Bank Payment Line", - comodel_name="bank.payment.line", + string='Bank Payment Line', + comodel_name='bank.payment.line', ) + lote_id = fields.Many2one( - string="Lote", - comodel_name="l10n.br.cnab.lote", + string='Lote', + comodel_name='financial.retorno.bancario.lote', ) - state = fields.Selection( - string="State", - related="lote_id.state", - selection=STATE, - default="draft", + + cnab_id = fields.Many2one( + string="CNAB", + comodel_name="financial.retorno.bancario" ) diff --git a/l10n_br_financial_payment_order/views/l10n_br_cnab.xml b/l10n_br_financial_payment_order/views/financial_retorno_bancario.xml similarity index 80% rename from l10n_br_financial_payment_order/views/l10n_br_cnab.xml rename to l10n_br_financial_payment_order/views/financial_retorno_bancario.xml index c71f9db..b5c8329 100644 --- a/l10n_br_financial_payment_order/views/l10n_br_cnab.xml +++ b/l10n_br_financial_payment_order/views/financial_retorno_bancario.xml @@ -2,15 +2,12 @@ - - cnab.retorno.tree - l10n.br.cnab + financial.retorno.bancario - @@ -22,7 +19,7 @@ cnab.lote.tree - l10n.br.cnab.lote + financial.retorno.bancario.lote @@ -40,12 +37,13 @@ cnab.evento.tree - l10n.br.cnab.evento + financial.retorno.bancario.evento + @@ -62,7 +60,7 @@ cnab.retorno.evento.form.view - l10n.br.cnab.evento + financial.retorno.bancario.evento
@@ -73,6 +71,7 @@ + @@ -123,7 +122,7 @@ cnab.retorno.form.view - l10n.br.cnab + financial.retorno.bancario
@@ -131,16 +130,19 @@
+

+ - + + - + @@ -151,9 +153,25 @@ - - - + + + + + + + + + + + + + + + + + + +
@@ -162,7 +180,7 @@ Retorno ir.actions.act_window - l10n.br.cnab + financial.retorno.bancario form tree,form From b9b4b3cd2df15a05f021c4c56bdcddb72d662465 Mon Sep 17 00:00:00 2001 From: Hendrix Costa Date: Sun, 23 Jul 2017 22:37:10 -0300 Subject: [PATCH 34/60] [FIX] Datas para fields.Date --- .../models/financial_retorno_bancario.py | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/l10n_br_financial_payment_order/models/financial_retorno_bancario.py b/l10n_br_financial_payment_order/models/financial_retorno_bancario.py index a26a9bc..7870a88 100644 --- a/l10n_br_financial_payment_order/models/financial_retorno_bancario.py +++ b/l10n_br_financial_payment_order/models/financial_retorno_bancario.py @@ -86,7 +86,7 @@ class FinancialRetornoBancario(models.Model): name = fields.Char(string='Nome') - data_arquivo = fields.Datetime(string='Data Criação no Banco') + data_arquivo = fields.Date(string='Data Criação no Banco') num_lotes = fields.Integer(string='Número de Lotes') @@ -94,12 +94,6 @@ class FinancialRetornoBancario(models.Model): codigo_convenio = fields.Char(string='Código Convenio') - # data = fields.Date( - # string='Data CNAB', - # # required=True, - # # default=datetime.now(), - # ) - arquivo_retorno = fields.Binary( string='Arquivo Retorno', required=True, @@ -229,7 +223,7 @@ def processar_arquivo_retorno(self): if account_bank_id_lote else False account_bank_id_infos = \ - 'Agência: ' + str(evento.favorecido_agencia) +\ + 'Agência: ' + str(evento.favorecido_agencia) + \ '-' + str(evento.favorecido_agencia_dv) + \ '\nConta: ' + str(evento.favorecido_conta) + \ '-' + str(evento.favorecido_conta_dv) @@ -340,7 +334,7 @@ class FinancialRetornoBancarioLote(models.Model): class FinancialRetornoBancarioEvento(models.Model): _name = b'financial.retorno.bancario.evento' - data_real_pagamento = fields.Datetime(string='Data Real do Pagamento') + data_real_pagamento = fields.Date(string='Data Real do Pagamento') segmento = fields.Char(string='Segmento') From 390b72ebf09681b89229e189fcdb47e65bcab8a7 Mon Sep 17 00:00:00 2001 From: Hendrix Costa Date: Sun, 23 Jul 2017 22:37:18 -0300 Subject: [PATCH 35/60] [FIX] Melhorias na view --- .../views/financial_retorno_bancario.xml | 30 +++++++++++-------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/l10n_br_financial_payment_order/views/financial_retorno_bancario.xml b/l10n_br_financial_payment_order/views/financial_retorno_bancario.xml index b5c8329..6f17f0e 100644 --- a/l10n_br_financial_payment_order/views/financial_retorno_bancario.xml +++ b/l10n_br_financial_payment_order/views/financial_retorno_bancario.xml @@ -67,25 +67,29 @@
- - + + /> - - + - + - - + + + + + + + @@ -157,16 +161,16 @@ - - - + + + - + - - + + From a85d240bc2377b02fe035f1af85801df72919ce4 Mon Sep 17 00:00:00 2001 From: Ari Caldeira Date: Sun, 23 Jul 2017 22:57:04 -0300 Subject: [PATCH 36/60] =?UTF-8?q?[FEA]=20Adicionando=20identifica=C3=A7?= =?UTF-8?q?=C3=A3o=20e=20valida=C3=A7=C3=A3o=20dos=20=20=20=20=20=20=20c?= =?UTF-8?q?=C3=B3digos=20de=20barras=20de=20contas?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../models/inherited_financial_move.py | 112 ++++++++---------- ...nherited_financial_move_debt_2pay_view.xml | 2 +- 2 files changed, 53 insertions(+), 61 deletions(-) diff --git a/l10n_br_financial_payment_order/models/inherited_financial_move.py b/l10n_br_financial_payment_order/models/inherited_financial_move.py index 85eaeb5..c97412b 100644 --- a/l10n_br_financial_payment_order/models/inherited_financial_move.py +++ b/l10n_br_financial_payment_order/models/inherited_financial_move.py @@ -6,7 +6,9 @@ from openerp import api, fields, models, _ -from pybrasil.base import modulo11, modulo10 +from pybrasil.febraban import (valida_codigo_barras, valida_linha_digitavel, + identifica_codigo_barras, monta_linha_digitavel, monta_codigo_barras, + formata_linha_digitavel) from ..febraban.boleto.document import Boleto from ..febraban.boleto.document import BoletoException @@ -44,74 +46,64 @@ class FinancialMove(models.Model): # boleto_linha_digitavel = fields.Char( string='Linha digitável', - size=54, + size=55, ) boleto_codigo_barras = fields.Char( string='Código de barras', size=44, ) - @api.multi - @api.depends('boleto_codigo_barras') - def compute_codigo_barras(self): - ''' - Posição # Conteúdo - 01 a 03 03 Número do banco - 04 01 Código da Moeda - 9 para Real - 05 01 Digito verificador do Código de Barras - 06 a 09 04 Data de vencimento em dias partis de 07/10/1997 - 10 a 19 10 Valor do boleto (8 inteiros e 2 decimais) - 20 a 44 25 Campo Livre definido por cada banco - Total 44 - ''' + def _trata_linha_digitavel(self): + self.ensure_one() + + if not self.boleto_linha_digitavel: + return + + # + # Foi informado o número via leitura do codigo de barras? + # + if valida_codigo_barras(self.boleto_linha_digitavel): + codigo_barras = self.boleto_linha_digitavel + linha_digitavel = monta_linha_digitavel(codigo_barras) + # + # Ou foi informado via digitação mesmo? + # + elif valida_linha_digitavel(self.boleto_linha_digitavel): + codigo_barras = monta_codigo_barras(self.boleto_linha_digitavel) + linha_digitavel = \ + formata_linha_digitavel(self.boleto_linha_digitavel) + + else: + return + #raise código inválido + + identificacao = identifica_codigo_barras(codigo_barras) + + if identificacao is None: + return + #raise código inválido + + self.boleto_linha_digitavel = linha_digitavel + self.boleto_codigo_barras = codigo_barras + if 'valor' in identificacao: + self.amount_document = identificacao['valor'] + + if 'vencimento' in identificacao and \ + identificacao['vencimento'] is not None: + self.date_maturity = str(identificacao['vencimento']) + + @api.multi + @api.onchange('boleto_linha_digitavel') + def _onchange_linha_digitavel(self): for move in self: - if not move.boleto_codigo_barras: - continue + move._trata_linha_digitavel() - if len(move.boleto_codigo_barras) != 44: - pass - # raise - - dv = move.boleto_codigo_barras[4] - codigo_barras = move.boleto_codigo_barras[0:4] + \ - move.boleto_codigo_barras[5:] - - dv_calculado = modulo11(codigo_barras, - mapa_digitos={0: 1, 1: 1, 10: 1, 11: 1}) - - if dv_calculado != dv: - pass - # raise - - # valor = move.boleto_codigo_barras[9:17] + '.' + \ - # move.boleto_codigo_barras[17:19] - # valor = float(valor) - # data_vencimento = move.boleto_codigo_barras[5:9] - - # - # Monta a linha digitável - # - campo_1 = move.boleto_codigo_barras[0:4] + \ - move.boleto_codigo_barras[19:24] - campo_2 = move.boleto_codigo_barras[24:34] - campo_3 = move.boleto_codigo_barras[34:44] - campo_4 = move.boleto_codigo_barras[4] - campo_5 = move.boleto_codigo_barras[5:19] - - # - # Dígitos verificadores - # - campo_1 += str(modulo10(campo_1, modulo=False)) - campo_2 += str(modulo10(campo_2, modulo=False)) - campo_3 += str(modulo10(campo_3, modulo=False)) - - campo_1 = campo_1[:5] + '.' + campo_1[5:] - campo_2 = campo_2[:5] + '.' + campo_2[5:] - campo_3 = campo_3[:5] + '.' + campo_3[5:] - - move.boleto_linha_digitavel = ' '.join([campo_1, campo_2, campo_3, - campo_4, campo_5]) + @api.multi + @api.depends('boleto_linha_digitavel') + def _depends_linha_digitavel(self): + for move in self: + move._trata_linha_digitavel() @api.multi def gera_boleto(self): diff --git a/l10n_br_financial_payment_order/views/inherited_financial_move_debt_2pay_view.xml b/l10n_br_financial_payment_order/views/inherited_financial_move_debt_2pay_view.xml index 3f4127b..7069efa 100644 --- a/l10n_br_financial_payment_order/views/inherited_financial_move_debt_2pay_view.xml +++ b/l10n_br_financial_payment_order/views/inherited_financial_move_debt_2pay_view.xml @@ -13,7 +13,7 @@ 2 - + From a6563b4f1f1b3ab57bdcd47266c93ff6f99d9e56 Mon Sep 17 00:00:00 2001 From: Luis Felipe Mileo Date: Mon, 24 Jul 2017 00:59:27 -0300 Subject: [PATCH 37/60] =?UTF-8?q?[NEW]=20Configura=C3=A7=C3=B5es=20por=20m?= =?UTF-8?q?odo=20de=20pagamento?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../models/payment_mode.py | 23 +++++++++++++++++++ .../payment_mode/payment_mode_base_view.xml | 19 ++++++++++++--- 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/l10n_br_financial_payment_order/models/payment_mode.py b/l10n_br_financial_payment_order/models/payment_mode.py index 7bf9a8d..6212461 100644 --- a/l10n_br_financial_payment_order/models/payment_mode.py +++ b/l10n_br_financial_payment_order/models/payment_mode.py @@ -170,6 +170,29 @@ class PaymentMode(models.Model): string='Entrega', default=BOLETO_DISTRIBUICAO_BENEFICIARIO, ) + nivel_aprovacao = fields.Selection( + selection=[ + ('0', 'Nenhuma / Aprovar e gerar o arquivo'), + ('1', 'Uma aprovação'), + ('2', 'Duas aprovações'), + ], + required=True, + default='0', + ) + aprovacao_grupo_1 = fields.Many2one( + comodel_name='res.groups', + string='Grupo primeira aprovação' + ) + aprovacao_grupo_2 = fields.Many2one( + comodel_name='res.groups', + string='Grupo segunda aprovação' + ) + gera_financeiro_remessa = fields.Boolean( + string='Gerar lançamento financeiro ao processar a remessa', + ) + gera_financeiro_retorno = fields.Boolean( + string='Gerar lançamento financeiro ao processar o retorno', + ) # boleto_type = fields.Selection( # boleto_selection, # string='Boleto' diff --git a/l10n_br_financial_payment_order/views/payment_mode/payment_mode_base_view.xml b/l10n_br_financial_payment_order/views/payment_mode/payment_mode_base_view.xml index 8c15662..dacb716 100644 --- a/l10n_br_financial_payment_order/views/payment_mode/payment_mode_base_view.xml +++ b/l10n_br_financial_payment_order/views/payment_mode/payment_mode_base_view.xml @@ -63,9 +63,22 @@ - - - + + + + + + + + + + + + + From 12db4b409ed326e0a66e582a6e1d16a565f327ab Mon Sep 17 00:00:00 2001 From: Luis Felipe Mileo Date: Mon, 24 Jul 2017 03:34:10 -0300 Subject: [PATCH 38/60] [NEW] Workflow --- .../__openerp__.py | 1 + .../models/inherited_payment_order.py | 70 +++++++++++-- .../payment_order/payment_order_base_view.xml | 9 +- .../workflows/hr_payroll_workflow.xml | 3 + .../workflows/payment_order_workflow.xml | 99 +++++++++++++++++++ 5 files changed, 172 insertions(+), 10 deletions(-) create mode 100644 l10n_br_financial_payment_order/workflows/payment_order_workflow.xml diff --git a/l10n_br_financial_payment_order/__openerp__.py b/l10n_br_financial_payment_order/__openerp__.py index 41de7b3..6fc8780 100644 --- a/l10n_br_financial_payment_order/__openerp__.py +++ b/l10n_br_financial_payment_order/__openerp__.py @@ -33,6 +33,7 @@ 'views/financial_retorno_bancario.xml', 'views/financial_move.xml', + 'workflows/payment_order_workflow.xml', # 'security/payment_mode.xml', # 'security/payment_mode_type.xml', # 'security/bank_payment_line.xml', diff --git a/l10n_br_financial_payment_order/models/inherited_payment_order.py b/l10n_br_financial_payment_order/models/inherited_payment_order.py index 092e57b..75d0d5d 100644 --- a/l10n_br_financial_payment_order/models/inherited_payment_order.py +++ b/l10n_br_financial_payment_order/models/inherited_payment_order.py @@ -4,7 +4,7 @@ from __future__ import division, print_function, unicode_literals -from openerp import api, fields, models, _ +from openerp import models, fields, api, exceptions, workflow, _ from openerp.exceptions import ValidationError # from openerp.addons.l10n_br_hr_payroll.models.hr_payslip import TIPO_DE_FOLHA from openerp.addons.financial.constants import ( @@ -23,6 +23,28 @@ class PaymentOrder(models.Model): _name = b'payment.order' _inherit = ['payment.order', 'mail.thread', 'ir.needaction_mixin'] + @api.multi + @api.depends('mode.nivel_aprovacao') + def _compute_nivel_aprovacao(self): + for record in self: + record.nivel_aprovacao = int(record.mode.nivel_aprovacao) + + state = fields.Selection( + selection=[ + ('draft', 'Rascunho'), + ('waiting', 'Aguardando aprovação'), + ('waiting2', 'Aguardando segunda aprovação'), + ('open', 'Confirmado'), + ('generated', 'Arquivo gerado'), + ('done', 'Arquivo enviado ao banco'), # v10: uploaded + ('cancel', 'Cancel'), + ], + string='Status', + readonly=True, + copy=False, + default='draft', + track_visibility='onchange', + ) tipo_pagamento = fields.Selection( string="Tipos de Ordem de Pagamento", selection=TIPO_ORDEM_PAGAMENTO, @@ -47,11 +69,10 @@ class PaymentOrder(models.Model): string="Data", states={'draft': [('readonly', False)]}, ) - # tipo_de_folha = fields.Selection( - # selection=TIPO_DE_FOLHA, - # string=u'Tipo de folha', - # default='normal', - # states={'done': [('readonly', True)]}, + nivel_aprovacao = fields.Integer( + compute='_compute_nivel_aprovacao', + + ) @api.multi def action_open(self): @@ -229,6 +250,43 @@ def financial_payment_import(self): return + @api.multi + def launch_wizard(self): + """Search for a wizard to launch according to the type. + If type is manual. just confirm the order. + Previously (pre-v6) in account_payment/wizard/wizard_pay.py + """ + context = self.env.context.copy() + order = self[0] + # check if a wizard is defined for the first order + if order.mode.type and order.mode.type.ir_model_id: + context['active_ids'] = self.ids + wizard_model = order.mode.type.ir_model_id.model + wizard_obj = self.env[wizard_model] + return { + 'name': wizard_obj._description or _('Payment Order Export'), + 'view_type': 'form', + 'view_mode': 'form', + 'res_model': wizard_model, + 'domain': [], + 'context': context, + 'type': 'ir.actions.act_window', + 'target': 'new', + 'nodestroy': True, + } + else: + # should all be manual orders without type or wizard model + for order in self[1:]: + if order.mode.type and order.mode.type.ir_model_id: + raise exceptions.Warning( + _('Error'), + _('You can only combine payment orders of the same ' + 'type')) + # process manual payments + for order_id in self.ids: + workflow.trg_validate(self.env.uid, 'payment.order', + order_id, 'generated', self.env.cr) + return {} @api.multi def buscar_holerites_wizard(self): diff --git a/l10n_br_financial_payment_order/views/payment_order/payment_order_base_view.xml b/l10n_br_financial_payment_order/views/payment_order/payment_order_base_view.xml index 6cb5268..43bfcdc 100644 --- a/l10n_br_financial_payment_order/views/payment_order/payment_order_base_view.xml +++ b/l10n_br_financial_payment_order/views/payment_order/payment_order_base_view.xml @@ -33,11 +33,12 @@
-
diff --git a/l10n_br_financial_payment_order/workflows/hr_payroll_workflow.xml b/l10n_br_financial_payment_order/workflows/hr_payroll_workflow.xml index 6e6ccd3..0e64b7e 100644 --- a/l10n_br_financial_payment_order/workflows/hr_payroll_workflow.xml +++ b/l10n_br_financial_payment_order/workflows/hr_payroll_workflow.xml @@ -3,6 +3,9 @@ License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). --> + + + diff --git a/l10n_br_financial_payment_order/workflows/payment_order_workflow.xml b/l10n_br_financial_payment_order/workflows/payment_order_workflow.xml new file mode 100644 index 0000000..ddc5f59 --- /dev/null +++ b/l10n_br_financial_payment_order/workflows/payment_order_workflow.xml @@ -0,0 +1,99 @@ + + + + + + + waiting + + action_open() +write({'state':'waiting'}) + function + + + + waiting2 + + action_open() +write({'state':'waiting2'}) + function + + + + generated + + action_open() +write({'state':'generated'}) + function + + + + + + + open + nivel_aprovacao==0 + + + + + + + open + nivel_aprovacao>0 + + + + + + open + nivel_aprovacao>1 + + + + + + open + nivel_aprovacao==1 + + + + + + open + nivel_aprovacao==2 + + + + + + generated + + + + + + done + + + + + + cancel + + + + + + cancel + + + + + + cancel + + + + From b70f08f33b7a68ac128b7fc83b7b102fd31ab735 Mon Sep 17 00:00:00 2001 From: Luis Felipe Mileo Date: Mon, 24 Jul 2017 03:36:15 -0300 Subject: [PATCH 39/60] [NEW] Payment export wizard --- .../__openerp__.py | 1 + .../wizards/__init__.py | 2 + .../wizards/bank_payment_manual.py | 42 +++++++ .../wizards/l10n_bank_payment_cnab_export.py | 105 ++++++++++++++++++ .../wizards/l10n_br_payment_cnab.xml | 32 ++++++ 5 files changed, 182 insertions(+) create mode 100644 l10n_br_financial_payment_order/wizards/bank_payment_manual.py create mode 100644 l10n_br_financial_payment_order/wizards/l10n_bank_payment_cnab_export.py create mode 100644 l10n_br_financial_payment_order/wizards/l10n_br_payment_cnab.xml diff --git a/l10n_br_financial_payment_order/__openerp__.py b/l10n_br_financial_payment_order/__openerp__.py index 6fc8780..b429c76 100644 --- a/l10n_br_financial_payment_order/__openerp__.py +++ b/l10n_br_financial_payment_order/__openerp__.py @@ -17,6 +17,7 @@ ], 'data': [ 'wizards/ordem_pagamento_holerite_wizard.xml', + 'wizards/l10n_br_payment_cnab.xml', 'views/payment_menu.xml', 'views/bank_payment_line.xml', diff --git a/l10n_br_financial_payment_order/wizards/__init__.py b/l10n_br_financial_payment_order/wizards/__init__.py index 121c0da..b9f6613 100644 --- a/l10n_br_financial_payment_order/wizards/__init__.py +++ b/l10n_br_financial_payment_order/wizards/__init__.py @@ -1 +1,3 @@ from . import ordem_pagamento_holerite +from . import bank_payment_manual +from . import l10n_bank_payment_cnab_export \ No newline at end of file diff --git a/l10n_br_financial_payment_order/wizards/bank_payment_manual.py b/l10n_br_financial_payment_order/wizards/bank_payment_manual.py new file mode 100644 index 0000000..2f325a3 --- /dev/null +++ b/l10n_br_financial_payment_order/wizards/bank_payment_manual.py @@ -0,0 +1,42 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Copyright (C) 2009 EduSense BV (). +# (C) 2011 - 2013 Therp BV (). +# +# All other contributions are (C) by their respective contributors +# +# All Rights Reserved +# +# 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 . +# +############################################################################## + +"""This module contains a single "wizard" for confirming manual +bank transfers. +""" + +from openerp import models, api, workflow + + +class PaymentManual(models.TransientModel): + _inherit = 'payment.manual' + _description = 'Send payment order(s) manually' + + @api.multi + def button_ok(self): + for order_id in self.env.context.get('active_ids', []): + workflow.trg_validate(self.env.uid, 'payment.order', order_id, + 'generated', self.env.cr) + return {'type': 'ir.actions.act_window_close'} diff --git a/l10n_br_financial_payment_order/wizards/l10n_bank_payment_cnab_export.py b/l10n_br_financial_payment_order/wizards/l10n_bank_payment_cnab_export.py new file mode 100644 index 0000000..ea0f49a --- /dev/null +++ b/l10n_br_financial_payment_order/wizards/l10n_bank_payment_cnab_export.py @@ -0,0 +1,105 @@ +# coding: utf-8 +# ########################################################################### +# +# Author: Luis Felipe Mileo +# Fernando Marcato Rodrigues +# Daniel Sadamo Hirayama +# Copyright 2015 KMEE - www.kmee.com.br +# +# 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 . +# +############################################################################## + +import base64 +import time + +from openerp import models, api, workflow, fields, _ +from openerp.exceptions import Warning as UserError +from ..febraban.cnab import Cnab + +import logging + +_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(string=u'Nome', size=255) + + cnab_file = fields.Binary(string='CNAB File', readonly=True) + + state = fields.Selection( + string='state', + selection=[('init', 'init'), ('done', 'done')], + default='init', + 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) + 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 == '500': + self.name = 'PG%s%s.REM' % ( + time.strftime('%d%m'), str(order.file_number)) + self.state = 'done' + self.cnab_file = base64.b64encode(remessa) + order.cnab_file = base64.b64encode(remessa) + order.cnab_filename = self.name + + workflow.trg_validate( + self.env.uid, 'payment.order', order_id, 'generated', self.env.cr) + + return { + 'type': 'ir.actions.act_window', + 'res_model': self._name, + 'view_mode': 'form', + 'view_type': 'form', + 'res_id': self.id, + 'target': 'new', + } + + @api.multi + def done(self): + return {'type': 'ir.actions.act_window_close'} diff --git a/l10n_br_financial_payment_order/wizards/l10n_br_payment_cnab.xml b/l10n_br_financial_payment_order/wizards/l10n_br_payment_cnab.xml new file mode 100644 index 0000000..ae19e1e --- /dev/null +++ b/l10n_br_financial_payment_order/wizards/l10n_br_payment_cnab.xml @@ -0,0 +1,32 @@ + + + + + payment.cnab.form + payment.cnab + + + + + + + + + + + +
+
+
+
+ +
+
+
+
From fc2bf142f63a23bd760c17394f12742a234883da Mon Sep 17 00:00:00 2001 From: Daniel Sadamo Hirayama Date: Mon, 24 Jul 2017 05:51:11 -0300 Subject: [PATCH 40/60] =?UTF-8?q?[ADD]remove=20valida=C3=A7=C3=B5es=20de?= =?UTF-8?q?=20conta=20bancaria=20do=20core?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../models/__init__.py | 2 ++ .../models/res_bank.py | 18 ++++++++++++++++++ .../models/res_partner_bank.py | 18 ++++++++++++++++++ 3 files changed, 38 insertions(+) create mode 100644 l10n_br_financial_payment_order/models/res_bank.py create mode 100644 l10n_br_financial_payment_order/models/res_partner_bank.py diff --git a/l10n_br_financial_payment_order/models/__init__.py b/l10n_br_financial_payment_order/models/__init__.py index 65f75e6..acd67d7 100644 --- a/l10n_br_financial_payment_order/models/__init__.py +++ b/l10n_br_financial_payment_order/models/__init__.py @@ -15,3 +15,5 @@ from . import inherited_payment_order from . import operacoes from . import financial_retorno_bancario +from . import res_bank +from . import res_partner_bank diff --git a/l10n_br_financial_payment_order/models/res_bank.py b/l10n_br_financial_payment_order/models/res_bank.py new file mode 100644 index 0000000..4cd58a3 --- /dev/null +++ b/l10n_br_financial_payment_order/models/res_bank.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2017 KMEE +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from openerp import api, models + + +class ResBank(models.Model): + _inherit = 'res.bank' + + @api.multi + @api.constrains('bic') + def check_bic_length(self): + ''' + sobrescrever constrains do core que nao leva em consideração bancos + que nao são intenacionais. + ''' + return True diff --git a/l10n_br_financial_payment_order/models/res_partner_bank.py b/l10n_br_financial_payment_order/models/res_partner_bank.py new file mode 100644 index 0000000..2f7c685 --- /dev/null +++ b/l10n_br_financial_payment_order/models/res_partner_bank.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +# Copyright 2017 KMEE +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from openerp import api, models + + +class ResPartnerBank(models.Model): + _inherit = 'res.partner.bank' + + @api.multi + @api.constrains('bank_bic') + def check_bic_length(self): + ''' + sobrescrever constrains do core que não leva em consideração bancos + que nao são internacionais. + ''' + return True From 0f5071e49d88d500bcb13fd37a986835b872e4ae Mon Sep 17 00:00:00 2001 From: Daniel Sadamo Hirayama Date: Mon, 24 Jul 2017 05:52:36 -0300 Subject: [PATCH 41/60] =?UTF-8?q?[FIX]Boleto=20esp=C3=A9cie=20de=20acordo?= =?UTF-8?q?=20com=20febraban?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- l10n_br_financial_payment_order/constantes.py | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/l10n_br_financial_payment_order/constantes.py b/l10n_br_financial_payment_order/constantes.py index 42d70a5..0c2ce7d 100644 --- a/l10n_br_financial_payment_order/constantes.py +++ b/l10n_br_financial_payment_order/constantes.py @@ -487,6 +487,41 @@ BOLETO_ESPECIE = [ + ('01', 'CH Cheque'), + ('02', 'DM Duplicata Mercantil'), + ('03', 'DMI Duplicata Mercantil p/ Indicação'), + ('04', 'DS Duplicata de Serviço'), + ('05', 'DSI Duplicata de Serviço p/ Indicação'), + ('06', 'DR Duplicata Rural'), + ('07', 'LC Letra de Câmbio'), + ('08', 'NCC Nota de Crédito Comercial'), + ('09', 'NCE Nota de Crédito a Exportação'), + ('10', 'NCI Nota de Crédito Industrial'), + ('11', 'NCR Nota de Crédito Rural'), + ('12', 'NP Nota Promissória'), + ('13', 'NPR Nota Promissória Rural'), + ('14', 'TM Triplicata Mercantil'), + ('15', 'TS Triplicata de Serviço'), + ('16', 'NS Nota de Seguro'), + ('17', 'RC Recibo'), + ('18', 'FAT Fatura'), + ('19', 'ND Nota de Débito'), + ('20', 'AP Apólice de Seguro'), + ('21', 'ME Mensalidade Escolar'), + ('22', 'PC Parcela de Consórcio'), + ('23', 'NF Nota Fiscal'), + ('24', 'DD Documento de Dívida'), + ('25', 'Cédula de Produto Rural'), + ('26', 'Warrant'), + ('27', 'Dívida Ativa de Estado'), + ('28', 'Dívida Ativa de Município'), + ('29', 'Dívida Ativa da União'), + ('30', 'Encargos Condominiais'), + ('31', 'CC Cartão de Crédito'), + ('32', 'BDP Boleto de Proposta'), + ('99', 'Outros'), + + ('01', 'Duplicata Mercantil'), ('02', 'Nota Promissória'), ('03', 'Nota de Seguro'), From 3b6115eba1bd946e5d038bd323b75af0212e2a6b Mon Sep 17 00:00:00 2001 From: Daniel Sadamo Hirayama Date: Mon, 24 Jul 2017 05:55:17 -0300 Subject: [PATCH 42/60] [REF]Class Boleto funciona com financial_move --- .../febraban/boleto/document.py | 303 ++++++++++-------- 1 file changed, 164 insertions(+), 139 deletions(-) diff --git a/l10n_br_financial_payment_order/febraban/boleto/document.py b/l10n_br_financial_payment_order/febraban/boleto/document.py index 48c1f51..eeed59e 100644 --- a/l10n_br_financial_payment_order/febraban/boleto/document.py +++ b/l10n_br_financial_payment_order/febraban/boleto/document.py @@ -22,6 +22,10 @@ from datetime import datetime, date import logging +from openerp.addons.financial.constants import ( +FINANCIAL_DEBT_2RECEIVE, +FINANCIAL_DEBT_2PAY +) _logger = logging.getLogger(__name__) @@ -48,26 +52,59 @@ class Boleto(object): nosso_numero = '' @staticmethod - def getBoleto(move_line, nosso_numero): - # boleto_type = move_line.payment_mode_id.boleto_type - # Banco Do Brasil - boleto_type = '1' - if boleto_type: - return dict_boleto[boleto_type][0](move_line, nosso_numero) - raise BoletoException(u'Configure o tipo de boleto no modo de ' - u'pagamento') + def getBoleto(financial_move, nosso_numero): + payment_mode = financial_move.payment_mode_id + carteira = payment_mode.boleto_carteira + banco = payment_mode.bank_id.bank.bic + + result = False + + if banco == '001': + result = BoletoBB + elif banco == '041': + result = BoletoBarisul + elif banco == '237': + result = BoletoBradesco + elif banco == '104': + if carteira == 'Sigcb': + result = BoletoCaixaSigcb + elif carteira in ['SR']: + result = BoletoCaixa + elif banco == '399': + result = BoletoHsbc + elif banco == '341': + if carteira == '157': + result = BoletoItau157 + elif carteira in ['175', '174', '178', '104', '109']: + result = BoletoItau + elif banco == '356': + result = BoletoReal + elif banco == '033': + if carteira == '102': + result = BoletoSantander102 + elif carteira in ['101', '201']: + result = BoletoStatander101201 + + if result: + return result(financial_move, nosso_numero) + else: + raise (BoletoException('Este banco não é suportado.')) @staticmethod - def getBoletoClass(move_line): - bank_code = move_line.payment_mode_id.bank_id.bank.bic - bank_code = '001' + def getBoletoClass(financial_move): + bank_code = financial_move.payment_mode_id.bank_id.bank.bic return bank.get_class_for_codigo(bank_code) - def __init__(self, move_line, nosso_numero): - self._cedente(move_line.company_id) - self._sacado(move_line.partner_id) - self._move_line(move_line) - self.nosso_numero = nosso_numero + def __init__(self, financial_move): + cedente = financial_move.payment_mode_id.bank_id.partner_id + if financial_move.type == FINANCIAL_DEBT_2RECEIVE: + sacado = financial_move.partner_id + elif financial_move.type == FINANCIAL_DEBT_2PAY: + sacado = financial_move.company_id + self._cedente(cedente) + self._sacado(sacado) + self._financial_move(financial_move) + # self.nosso_numero = '' def getAccountNumber(self): if self.account_digit: @@ -81,43 +118,49 @@ def getBranchNumber(self): self.branch_digit).encode('utf-8') return self.branch_number.encode('utf-8') - def _move_line(self, move_line): - self._payment_mode(move_line.payment_mode_id) + def _financial_move(self, financial_move): + self._payment_mode(financial_move) self.boleto.data_vencimento = datetime.date(datetime.strptime( - move_line.date_maturity, '%Y-%m-%d')) + financial_move.date_business_maturity, '%Y-%m-%d')) self.boleto.data_documento = datetime.date(datetime.strptime( - move_line.invoice.date_invoice, '%Y-%m-%d')) + financial_move.date_document, '%Y-%m-%d')) self.boleto.data_processamento = date.today() - self.boleto.valor = str("%.2f" % move_line.debit or move_line.credit) - self.boleto.valor_documento = str("%.2f" % move_line.debit or - move_line.credit) - self.boleto.especie = \ - move_line.currency_id and move_line.currency_id.symbol or 'R$' - self.boleto.quantidade = '' # str("%.2f" % move_line.amount_currency) - self.boleto.numero_documento = move_line.name.encode('utf-8') - - def _payment_mode(self, payment_mode_id): + self.boleto.valor = str("%.2f" % financial_move.amount_document) + self.boleto.valor_documento = str("%.2f" % + financial_move.amount_document) + self.boleto.especie = ( + financial_move.currency_id and + financial_move.currency_id.symbol or 'R$') + self.boleto.quantidade = '' + # str("%.2f" % financial_move.amount_currency) + self.boleto.numero_documento = \ + financial_move.document_number.encode('utf-8') + + def _payment_mode(self, financial_move): """ :param payment_mode: :return: """ - self.boleto.convenio = payment_mode_id.boleto_convenio - self.boleto.especie_documento = payment_mode_id.boleto_modalidade + payment_mode_id = financial_move.payment_mode_id + self.boleto.convenio = payment_mode_id.convenio + self.boleto.especie_documento = \ + financial_move.document_type_id.boleto_especie self.boleto.aceite = payment_mode_id.boleto_aceite self.boleto.carteira = payment_mode_id.boleto_carteira - def _cedente(self, company): + def _cedente(self, partner_id): """ :param company: :return: """ - self.boleto.cedente = company.partner_id.legal_name.encode('utf-8') - self.boleto.cedente_documento = company.cnpj_cpf.encode('utf-8') - self.boleto.cedente_bairro = company.district - self.boleto.cedente_cep = company.zip - self.boleto.cedente_cidade = company.city - self.boleto.cedente_logradouro = company.street + ', ' + company.number - self.boleto.cedente_uf = company.state_id.code + self.boleto.cedente = partner_id.legal_name.encode('utf-8') + self.boleto.cedente_documento = partner_id.cnpj_cpf.encode('utf-8') + self.boleto.cedente_bairro = partner_id.district + self.boleto.cedente_cep = partner_id.zip + self.boleto.cedente_cidade = partner_id.city + self.boleto.cedente_logradouro = partner_id.street + \ + ', ' + (partner_id.number or 'SN') + self.boleto.cedente_uf = partner_id.state_id.code self.boleto.agencia_cedente = self.getBranchNumber() self.boleto.conta_cedente = self.getAccountNumber() @@ -127,7 +170,8 @@ def _sacado(self, partner): :param partner: :return: """ - self.boleto.sacado_endereco = partner.street + ', ' + partner.number + self.boleto.sacado_endereco = partner.street + ', ' + ( + partner.number or 'SN') self.boleto.sacado_cidade = partner.city self.boleto.sacado_bairro = partner.district self.boleto.sacado_uf = partner.state_id.code @@ -160,161 +204,142 @@ def get_pdfs(cls, boleto_list): class BoletoBB(Boleto): - def __init__(self, move_line, nosso_numero): + def __init__(self, financial_move, nosso_numero): # TODO: size o convenio and nosso numero, replace (7,2) # Size of convenio 4, 6, 7 or 8 # Nosso Numero format. 1 or 2 # Used only for convenio=6 # 1: Nosso Numero with 5 positions # 2: Nosso Numero with 17 positions - self.boleto = Boleto.getBoletoClass(move_line)(7, 2) - self.account_number = move_line.payment_mode_id.bank_id.acc_number - self.branch_number = move_line.payment_mode_id.bank_id.bra_number - Boleto.__init__(self, move_line, nosso_numero) - self.boleto.nosso_numero = self.nosso_numero + self.boleto = Boleto.getBoletoClass(financial_move)(7, 2) + self.account_number = financial_move.payment_mode_id.bank_id.acc_number + self.branch_number = financial_move.payment_mode_id.bank_id.bra_number + Boleto.__init__(self, financial_move) + self.boleto.nosso_numero = nosso_numero class BoletoBarisul(Boleto): - def __init__(self, move_line, nosso_numero): - self.boleto = Boleto.getBoletoClass(move_line)() - self.account_number = move_line.payment_mode_id.bank_id.acc_number - self.branch_number = move_line.payment_mode_id.bank_id.bra_number - Boleto.__init__(self, move_line, nosso_numero) - self.boleto.nosso_numero = self.nosso_numero + def __init__(self, financial_move, nosso_numero): + self.boleto = Boleto.getBoletoClass(financial_move)() + self.account_number = financial_move.payment_mode_id.bank_id.acc_number + self.branch_number = financial_move.payment_mode_id.bank_id.bra_number + Boleto.__init__(self, financial_move) + self.boleto.nosso_numero = nosso_numero class BoletoBradesco(Boleto): - def __init__(self, move_line, nosso_numero): - self.boleto = Boleto.getBoletoClass(move_line)() - self.account_number = move_line.payment_mode_id.bank_id.acc_number - self.branch_number = move_line.payment_mode_id.bank_id.bra_number + def __init__(self, financial_move, nosso_numero): + self.boleto = Boleto.getBoletoClass(financial_move)() + self.account_number = financial_move.payment_mode_id.bank_id.acc_number + self.branch_number = financial_move.payment_mode_id.bank_id.bra_number # bank specific - self.account_digit = move_line.payment_mode_id.bank_id.acc_number_dig - self.branch_digit = move_line.payment_mode_id.bank_id.bra_number_dig + self.account_digit = \ + financial_move.payment_mode_id.bank_id.acc_number_dig + self.branch_digit = \ + financial_move.payment_mode_id.bank_id.bra_number_dig # end bank specific - Boleto.__init__(self, move_line, nosso_numero) - self.boleto.nosso_numero = self.nosso_numero + Boleto.__init__(self, financial_move) + self.boleto.nosso_numero = nosso_numero class BoletoCaixa(Boleto): - def __init__(self, move_line, nosso_numero): - self.boleto = Boleto.getBoletoClass(move_line)() - self.account_number = move_line.payment_mode_id.bank_id.acc_number - self.branch_number = move_line.payment_mode_id.bank_id.bra_number + def __init__(self, financial_move, nosso_numero): + self.boleto = Boleto.getBoletoClass(financial_move)() + self.account_number = financial_move.payment_mode_id.bank_id.acc_number + self.branch_number = financial_move.payment_mode_id.bank_id.bra_number # bank specific - self.account_digit = move_line.payment_mode_id.bank_id.acc_number_dig + self.account_digit = \ + financial_move.payment_mode_id.bank_id.acc_number_dig # end bank specific - Boleto.__init__(self, move_line, nosso_numero) - self.boleto.nosso_numero = self.nosso_numero + Boleto.__init__(self, financial_move) + self.boleto.nosso_numero = nosso_numero class BoletoHsbc(Boleto): - def __init__(self, move_line, nosso_numero): - self.boleto = Boleto.getBoletoClass(move_line)() - self.account_number = move_line.payment_mode_id.bank_id.acc_number - self.branch_number = move_line.payment_mode_id.bank_id.bra_number - Boleto.__init__(self, move_line, nosso_numero) - self.boleto.nosso_numero = self.nosso_numero + def __init__(self, financial_move, nosso_numero): + self.boleto = Boleto.getBoletoClass(financial_move)() + self.account_number = financial_move.payment_mode_id.bank_id.acc_number + self.branch_number = financial_move.payment_mode_id.bank_id.bra_number + Boleto.__init__(self, financial_move) + self.boleto.nosso_numero = nosso_numero class BoletoItau157(Boleto): - def __init__(self, move_line, nosso_numero): - self.boleto = Boleto.getBoletoClass(move_line)() - self.account_number = move_line.payment_mode_id.bank_id.acc_number - self.branch_number = move_line.payment_mode_id.bank_id.bra_number - Boleto.__init__(self, move_line, nosso_numero) - self.boleto.nosso_numero = self.nosso_numero + def __init__(self, financial_move, nosso_numero): + self.boleto = Boleto.getBoletoClass(financial_move)() + self.account_number = financial_move.payment_mode_id.bank_id.acc_number + self.branch_number = financial_move.payment_mode_id.bank_id.bra_number + Boleto.__init__(self, financial_move) + self.boleto.nosso_numero = nosso_numero class BoletoItau(Boleto): - def __init__(self, move_line, nosso_numero): - self.boleto = Boleto.getBoletoClass(move_line)() - self.account_number = move_line.payment_mode_id.bank_id.acc_number - self.branch_number = move_line.payment_mode_id.bank_id.bra_number - Boleto.__init__(self, move_line, nosso_numero) - self.boleto.nosso_numero = self.nosso_numero + def __init__(self, financial_move, nosso_numero): + self.boleto = Boleto.getBoletoClass(financial_move)() + self.account_number = financial_move.payment_mode_id.bank_id.acc_number + self.branch_number = financial_move.payment_mode_id.bank_id.bra_number + Boleto.__init__(self, financial_move) + self.boleto.nosso_numero = nosso_numero class BoletoReal(Boleto): - def __init__(self, move_line, nosso_numero): - self.boleto = Boleto.getBoletoClass(move_line)() - self.account_number = move_line.payment_mode_id.bank_id.acc_number - self.branch_number = move_line.payment_mode_id.bank_id.bra_number - Boleto.__init__(self, move_line, nosso_numero) - self.boleto.nosso_numero = self.nosso_numero + def __init__(self, financial_move, nosso_numero): + self.boleto = Boleto.getBoletoClass(financial_move)() + self.account_number = financial_move.payment_mode_id.bank_id.acc_number + self.branch_number = financial_move.payment_mode_id.bank_id.bra_number + Boleto.__init__(self, financial_move) + self.boleto.nosso_numero = nosso_numero -class BoletoSantander101(Boleto): +class BoletoSantander102(Boleto): - def __init__(self, move_line, nosso_numero): - self.boleto = Boleto.getBoletoClass(move_line)() - self.account_number = move_line.payment_mode_id.bank_id.acc_number - self.branch_number = move_line.payment_mode_id.bank_id.bra_number - Boleto.__init__(self, move_line, nosso_numero) + def __init__(self, financial_move, nosso_numero): + self.boleto = Boleto.getBoletoClass(financial_move)() + self.account_number = financial_move.payment_mode_id.bank_id.acc_number + self.branch_number = financial_move.payment_mode_id.bank_id.bra_number + Boleto.__init__(self, financial_move) self.boleto.ios = '0' - self.boleto.nosso_numero = self.nosso_numero + self.boleto.nosso_numero = nosso_numero class BoletoStatander101201(Boleto): - def __init__(self, move_line, nosso_numero): - self.boleto = Boleto.getBoletoClass(move_line)() - self.account_number = move_line.payment_mode_id.bank_id.acc_number - self.branch_number = move_line.payment_mode_id.bank_id.bra_number - Boleto.__init__(self, move_line, nosso_numero) + def __init__(self, financial_move, nosso_numero): + self.boleto = Boleto.getBoletoClass(financial_move)() + self.account_number = financial_move.payment_mode_id.bank_id.acc_number + self.branch_number = financial_move.payment_mode_id.bank_id.bra_number + Boleto.__init__(self, financial_move) self.boleto.ios = '0' - self.boleto.nosso_numero = self.nosso_numero + self.boleto.nosso_numero = nosso_numero class BoletoCaixaSigcb(Boleto): - def __init__(self, move_line, nosso_numero): + def __init__(self, financial_move, nosso_numero): from pyboleto.bank.caixa_sigcb import BoletoCaixaSigcb self.boleto = BoletoCaixaSigcb() - self.account_number = move_line.payment_mode_id.bank_id.acc_number - self.branch_number = move_line.payment_mode_id.bank_id.bra_number + self.account_number = financial_move.payment_mode_id.bank_id.acc_number + self.branch_number = financial_move.payment_mode_id.bank_id.bra_number # bank specific - self.account_digit = move_line.payment_mode_id.bank_id.acc_number_dig + self.account_digit = \ + financial_move.payment_mode_id.bank_id.acc_number_dig # end bank specific - Boleto.__init__(self, move_line, nosso_numero) - self.boleto.nosso_numero = self.nosso_numero + Boleto.__init__(self, financial_move) + self.boleto.nosso_numero = nosso_numero class BoletoSicredi(Boleto): - def __init__(self, move_line, nosso_numero): - self.boleto = Boleto.getBoletoClass(move_line)() - self.account_number = move_line.payment_mode_id.bank_id.acc_number - self.branch_number = move_line.payment_mode_id.bank_id.bra_number - Boleto.__init__(self, move_line, nosso_numero) - self.boleto.nosso_numero = self.nosso_numero - - -dict_boleto = { - '1': (BoletoBB, 'Banco do Brasil 18'), - '2': (BoletoBarisul, 'Barisul x'), - '3': (BoletoBradesco, 'Bradesco 06, 03'), - '4': (BoletoCaixa, 'Caixa Economica SR'), - '5': (BoletoHsbc, 'HSBC CNR CSB'), - '6': (BoletoItau157, 'Itau 157'), - '7': (BoletoItau, 'Itau 175, 174, 178, 104, 109'), - '8': (BoletoReal, 'Real 57'), - '9': (BoletoSantander101, 'Santander 102'), - '10': (BoletoStatander101201, 'Santander 101, 201'), - '11': (BoletoCaixaSigcb, 'Caixa Sigcb'), - '12': (BoletoSicredi, 'Sicredi'), -} - - -def getBoletoSelection(): - list = [] - for i in dict_boleto: - list.append((i, dict_boleto[i][1])) - return list + def __init__(self, financial_move, nosso_numero): + self.boleto = Boleto.getBoletoClass(financial_move)() + self.account_number = financial_move.payment_mode_id.bank_id.acc_number + self.branch_number = financial_move.payment_mode_id.bank_id.bra_number + Boleto.__init__(self, financial_move) + self.boleto.nosso_numero = nosso_numero From 7ee9f5195ee542f486ffee59a13bf753f494238b Mon Sep 17 00:00:00 2001 From: Daniel Sadamo Hirayama Date: Mon, 24 Jul 2017 05:56:51 -0300 Subject: [PATCH 43/60] [ADD]dependencia do egg pyboleto --- l10n_br_financial_payment_order/__openerp__.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/l10n_br_financial_payment_order/__openerp__.py b/l10n_br_financial_payment_order/__openerp__.py index b429c76..11e45a8 100644 --- a/l10n_br_financial_payment_order/__openerp__.py +++ b/l10n_br_financial_payment_order/__openerp__.py @@ -10,6 +10,11 @@ 'license': 'AGPL-3', 'author': 'KMEE,Odoo Community Association (OCA)', 'website': 'www.kmee.com.br', + 'external_dependencies': { + 'python': [ + 'pyboleto', + ], + }, 'depends': [ 'account_banking_payment_export', 'l10n_br_account_product', From 0369bc50e432d8f5c86a27f26baa59ab89082a1d Mon Sep 17 00:00:00 2001 From: Daniel Sadamo Hirayama Date: Mon, 24 Jul 2017 05:57:13 -0300 Subject: [PATCH 44/60] [FIX]dependencia de financial_account para financial --- l10n_br_financial_payment_order/__openerp__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/l10n_br_financial_payment_order/__openerp__.py b/l10n_br_financial_payment_order/__openerp__.py index 11e45a8..3411ba6 100644 --- a/l10n_br_financial_payment_order/__openerp__.py +++ b/l10n_br_financial_payment_order/__openerp__.py @@ -18,7 +18,7 @@ 'depends': [ 'account_banking_payment_export', 'l10n_br_account_product', - 'financial_account', + 'financial', ], 'data': [ 'wizards/ordem_pagamento_holerite_wizard.xml', From d42a99b485e8b75f472838714cf25937f94ec935 Mon Sep 17 00:00:00 2001 From: Daniel Sadamo Hirayama Date: Mon, 24 Jul 2017 06:01:32 -0300 Subject: [PATCH 45/60] fixup! [REF]Class Boleto funciona com financial_move --- l10n_br_financial_payment_order/models/payment_mode.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/l10n_br_financial_payment_order/models/payment_mode.py b/l10n_br_financial_payment_order/models/payment_mode.py index 6212461..3785c8d 100644 --- a/l10n_br_financial_payment_order/models/payment_mode.py +++ b/l10n_br_financial_payment_order/models/payment_mode.py @@ -13,9 +13,6 @@ # BOLETO_EMISSAO, BOLETO_EMISSAO_BENEFICIARIO, \ # BOLETO_ENTREGA, BOLETO_ENTREGA_BENEFICIARIO from ..constantes import * -from ..febraban.boleto.document import getBoletoSelection - -boleto_selection = getBoletoSelection() class PaymentMode(models.Model): From 13a259d80dde3fd92466f32cf91a27719f29b2fc Mon Sep 17 00:00:00 2001 From: Daniel Sadamo Hirayama Date: Mon, 24 Jul 2017 06:02:13 -0300 Subject: [PATCH 46/60] [ADD]Na visao campos para geracao de boleto --- .../views/payment_mode/payment_mode_cobranca_view.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/l10n_br_financial_payment_order/views/payment_mode/payment_mode_cobranca_view.xml b/l10n_br_financial_payment_order/views/payment_mode/payment_mode_cobranca_view.xml index 20b8329..44c6c3e 100644 --- a/l10n_br_financial_payment_order/views/payment_mode/payment_mode_cobranca_view.xml +++ b/l10n_br_financial_payment_order/views/payment_mode/payment_mode_cobranca_view.xml @@ -14,6 +14,10 @@ + + + +
From fd00c78b5dd8a85935728a8c9f9edd25469a9fd3 Mon Sep 17 00:00:00 2001 From: Daniel Sadamo Hirayama Date: Mon, 24 Jul 2017 06:03:54 -0300 Subject: [PATCH 47/60] [REF]Financial move para gerar boleto --- .../__openerp__.py | 1 + .../models/inherited_financial_move.py | 53 ++++++++++++------- .../views/financial_move.xml | 7 ++- 3 files changed, 41 insertions(+), 20 deletions(-) diff --git a/l10n_br_financial_payment_order/__openerp__.py b/l10n_br_financial_payment_order/__openerp__.py index 3411ba6..1f78494 100644 --- a/l10n_br_financial_payment_order/__openerp__.py +++ b/l10n_br_financial_payment_order/__openerp__.py @@ -25,6 +25,7 @@ 'wizards/l10n_br_payment_cnab.xml', 'views/payment_menu.xml', 'views/bank_payment_line.xml', + 'views/financial_move.xml', 'views/inherited_financial_document_type_view.xml', 'views/inherited_financial_move_debt_2pay_view.xml', diff --git a/l10n_br_financial_payment_order/models/inherited_financial_move.py b/l10n_br_financial_payment_order/models/inherited_financial_move.py index c97412b..19a661e 100644 --- a/l10n_br_financial_payment_order/models/inherited_financial_move.py +++ b/l10n_br_financial_payment_order/models/inherited_financial_move.py @@ -10,6 +10,8 @@ identifica_codigo_barras, monta_linha_digitavel, monta_codigo_barras, formata_linha_digitavel) +import base64 + from ..febraban.boleto.document import Boleto from ..febraban.boleto.document import BoletoException @@ -33,6 +35,10 @@ class FinancialMove(models.Model): string='Carteira de cobrança', ondelete='restrict', ) + tipo_pagamento = fields.Selection( + related='payment_mode_id.tipo_pagamento', + store=True + ) # # Implementa o nosso número como NUMERIC no Postgres, pois alguns # bancos têm números bem grandes, que não dão certo com integers @@ -106,41 +112,50 @@ def _depends_linha_digitavel(self): move._trata_linha_digitavel() @api.multi - def gera_boleto(self): + def button_boleto(self): + self.ensure_one() + return self.env['report'].get_action( + self, b'l10n_br_financial_payment_order.report') - print ('Chegou AQUI!') + @api.multi + def gera_boleto(self): boleto_list = [] - for move_line in self: + for financial_move in self: try: - if True: - # if move_line.payment_mode_id.type_payment == '00': - # number_type = move_line.company_id.own_number_type - # if not move_line.boleto_own_number: + # if True: + # if financial_move.payment_mode_id.type_payment == '00': + # number_type = financial_move.company_id.own_number_type + # if not financial_move.boleto_own_number: # if number_type == '0': # nosso_numero = self.env['ir.sequence'].next_by_id( - # move_line.company_id.own_number_sequence.id) + # financial_move.company_id.own_number_sequence.id) # elif number_type == '1': # nosso_numero = \ - # move_line.transaction_ref.replace('/', '') + # financial_move.transaction_ref.replace('/', '') # else: # nosso_numero = self.env['ir.sequence'].next_by_id( - # move_line.payment_mode_id. + # financial_move.payment_mode_id. # internal_sequence_id.id) # else: - # nosso_numero = move_line.boleto_own_number - nosso_numero = move_line.nosso_numero - nosso_numero = 3751 + # nosso_numero = financial_move.boleto_own_number + + seq_id = \ + financial_move.payment_mode_id.\ + sequence_nosso_numero_id.id + nosso_numero = str(int(self.nosso_numero)) or \ + self.env['ir.sequence'].next_by_id(seq_id) + - boleto = Boleto.getBoleto(move_line, nosso_numero) + boleto = Boleto.getBoleto(financial_move, nosso_numero) if boleto: - move_line.date_payment_created = date.today() - move_line.transaction_ref = \ - boleto.boleto.format_nosso_numero() - move_line.boleto_own_number = nosso_numero + # financial_move.date_payment_created = date.today() + # financial_move.transaction_ref = \ + # boleto.boleto.format_nosso_numero() + financial_move.nosso_numero = nosso_numero boleto_list.append(boleto.boleto) except BoletoException as be: @@ -149,4 +164,4 @@ def gera_boleto(self): except Exception as e: _logger.error(e.message or e.value, exc_info=True) continue - return boleto_list \ No newline at end of file + return boleto_list diff --git a/l10n_br_financial_payment_order/views/financial_move.xml b/l10n_br_financial_payment_order/views/financial_move.xml index 49fcbbc..d5231ba 100644 --- a/l10n_br_financial_payment_order/views/financial_move.xml +++ b/l10n_br_financial_payment_order/views/financial_move.xml @@ -1,3 +1,7 @@ + + + @@ -7,7 +11,8 @@ From 6d17300805d2de459cd0af2ef5c0a4e3c5a446fd Mon Sep 17 00:00:00 2001 From: Daniel Sadamo Hirayama Date: Mon, 24 Jul 2017 06:06:16 -0300 Subject: [PATCH 48/60] [ADD]Report boleto para financial_move --- l10n_br_financial_payment_order/__init__.py | 1 + .../__openerp__.py | 1 + .../reports/__init__.py | 5 ++ .../reports/report_boleto.py | 62 +++++++++++++++++++ .../reports/report_boleto.xml | 17 +++++ 5 files changed, 86 insertions(+) create mode 100644 l10n_br_financial_payment_order/reports/__init__.py create mode 100644 l10n_br_financial_payment_order/reports/report_boleto.py create mode 100644 l10n_br_financial_payment_order/reports/report_boleto.xml diff --git a/l10n_br_financial_payment_order/__init__.py b/l10n_br_financial_payment_order/__init__.py index aee8895..b83f59e 100644 --- a/l10n_br_financial_payment_order/__init__.py +++ b/l10n_br_financial_payment_order/__init__.py @@ -1,2 +1,3 @@ from . import models from . import wizards +from . import reports diff --git a/l10n_br_financial_payment_order/__openerp__.py b/l10n_br_financial_payment_order/__openerp__.py index 1f78494..beaa6a0 100644 --- a/l10n_br_financial_payment_order/__openerp__.py +++ b/l10n_br_financial_payment_order/__openerp__.py @@ -41,6 +41,7 @@ 'views/financial_retorno_bancario.xml', 'views/financial_move.xml', 'workflows/payment_order_workflow.xml', + 'reports/report_boleto.xml', # 'security/payment_mode.xml', # 'security/payment_mode_type.xml', # 'security/bank_payment_line.xml', diff --git a/l10n_br_financial_payment_order/reports/__init__.py b/l10n_br_financial_payment_order/reports/__init__.py new file mode 100644 index 0000000..7203ec3 --- /dev/null +++ b/l10n_br_financial_payment_order/reports/__init__.py @@ -0,0 +1,5 @@ +# -*- coding: utf-8 -*- +# Copyright 2017 KMEE +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from . import report_boleto diff --git a/l10n_br_financial_payment_order/reports/report_boleto.py b/l10n_br_financial_payment_order/reports/report_boleto.py new file mode 100644 index 0000000..2c8d035 --- /dev/null +++ b/l10n_br_financial_payment_order/reports/report_boleto.py @@ -0,0 +1,62 @@ +# -*- coding: utf-8 -*- +# Copyright 2017 KMEE INFORMATICA LTDA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from __future__ import with_statement, unicode_literals + +from openerp import pooler +from openerp.osv import osv +from openerp.report.interface import report_int +from openerp.report.render import render + +from ..febraban.boleto.document import Boleto + +class ExternalPdf(render): + + def __init__(self, pdf): + render.__init__(self) + self.pdf = pdf + self.output_type = 'pdf' + + def _render(self): + return self.pdf + + +class ReportCustom(report_int): + """ + Custom report for return boletos + """ + + def create(self, cr, uid, ids, datas, context=False): + if not context: + context = {} + active_ids = context.get('active_ids') + active_model = context.get('active_model') + pool = pooler.get_pool(cr.dbname) + ids_financial_lines = [] + + financial_obj = pool.get('financial.move') + + if active_model == 'account.invoice': + ai_obj = pool.get('account.invoice') + for account_invoice in ai_obj.browse(cr, uid, active_ids): + for move_line in account_invoice.financial_ids: + ids_financial_lines.append(move_line.id) + elif active_model == 'financial.move': + ids_financial_lines = active_ids + else: + return False + + boleto_list = financial_obj.gera_boleto(cr, uid, ids_financial_lines) + if not boleto_list: + raise osv.except_osv( + 'Error !', ('Não é possível gerar os boletos\n' + 'Certifique-se que a fatura esteja confirmada e o ' + 'forma de pagamento seja duplicatas')) + pdf_string = Boleto.get_pdfs(boleto_list) + self.obj = ExternalPdf(pdf_string) + self.obj.render() + return self.obj.pdf, 'pdf' + + +ReportCustom('report.l10n_br_financial_payment_order.report') diff --git a/l10n_br_financial_payment_order/reports/report_boleto.xml b/l10n_br_financial_payment_order/reports/report_boleto.xml new file mode 100644 index 0000000..548ff13 --- /dev/null +++ b/l10n_br_financial_payment_order/reports/report_boleto.xml @@ -0,0 +1,17 @@ + + + + + + + + + \ No newline at end of file From 0659be58260541da34dff387b93e7cdda0c87c33 Mon Sep 17 00:00:00 2001 From: Daniel Sadamo Hirayama Date: Mon, 24 Jul 2017 06:15:22 -0300 Subject: [PATCH 49/60] =?UTF-8?q?fixup!=20[FIX]Boleto=20esp=C3=A9cie=20de?= =?UTF-8?q?=20acordo=20com=20febraban?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- l10n_br_financial_payment_order/constantes.py | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/l10n_br_financial_payment_order/constantes.py b/l10n_br_financial_payment_order/constantes.py index 0c2ce7d..1ce3b44 100644 --- a/l10n_br_financial_payment_order/constantes.py +++ b/l10n_br_financial_payment_order/constantes.py @@ -519,23 +519,7 @@ ('30', 'Encargos Condominiais'), ('31', 'CC Cartão de Crédito'), ('32', 'BDP Boleto de Proposta'), - ('99', 'Outros'), - - - ('01', 'Duplicata Mercantil'), - ('02', 'Nota Promissória'), - ('03', 'Nota de Seguro'), - ('04', 'Mensalidade Escolar'), - ('05', 'Recibo'), - ('06', 'Contrato'), - ('07', 'Cosseguros'), - ('08', 'Duplicata de Serviço'), - ('09', 'Letra de Câmbio'), - ('13', 'Nota de Débitos'), - ('15', 'Documento de Dívida'), - ('16', 'Encargos Condominiais'), - ('17', 'Conta de Prestação de Serviços'), - ('99', 'Diversos'), + ('99', 'Outros') ] BOLETO_ESPECIE_DUPLICATA_MERCANTIL = '01' From 14eeeee85b77159631907a91fdeabd0db646251d Mon Sep 17 00:00:00 2001 From: Hendrix Costa Date: Mon, 24 Jul 2017 06:33:20 -0300 Subject: [PATCH 50/60] =?UTF-8?q?[FIX]=20Alternativas=20para=20evitar=20er?= =?UTF-8?q?ro=20na=20gera=C3=A7=C3=A3o=20do=20CNAB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../febraban/cnab_240/cnab_240.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) 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 b67d6b8..e9e9146 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 @@ -114,7 +114,8 @@ def _prepare_header(self): # 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), + 'cedente_conta': + int(punctuation_rm(self.order.mode.bank_id.acc_number)), # 11.0 'cedente_conta_dv': self.order.mode.bank_id.acc_number_dig[0], # 12.0 @@ -123,7 +124,9 @@ def _prepare_header(self): 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], + self.order.mode.bank_id.partner_id.legal_name[:30] + if self.order.mode.bank_id.partner_id.legal_name + else self.order.mode.bank_id.partner_id.name[:30], # 14.0 'nome_banco': self.order.mode.bank_id.bank_name, # 15.0 @@ -195,7 +198,8 @@ def _prepare_header_lote(self): # 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), + 'cedente_conta': + int(punctuation_rm(self.order.mode.bank_id.acc_number)), # 15.1 'cedente_conta_dv': self.order.mode.bank_id.acc_number_dig[0], # 16.1 @@ -204,7 +208,9 @@ def _prepare_header_lote(self): 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], + self.order.mode.bank_id.partner_id.legal_name[:30] + if self.order.mode.bank_id.partner_id.legal_name + else self.order.mode.bank_id.partner_id.name[:30], # 18.1 'mensagem1': '', From ad4a62d9df137f48b472642ed3280a3efb9046df Mon Sep 17 00:00:00 2001 From: Hendrix Costa Date: Mon, 24 Jul 2017 06:33:33 -0300 Subject: [PATCH 51/60] [FIX] Tabela readonly --- .../views/payment_order/payment_order_base_view.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/l10n_br_financial_payment_order/views/payment_order/payment_order_base_view.xml b/l10n_br_financial_payment_order/views/payment_order/payment_order_base_view.xml index 43bfcdc..c9e9d0f 100644 --- a/l10n_br_financial_payment_order/views/payment_order/payment_order_base_view.xml +++ b/l10n_br_financial_payment_order/views/payment_order/payment_order_base_view.xml @@ -68,7 +68,7 @@ - +
From 84832150075d666382d355eda3f8c4a15ccfdf16 Mon Sep 17 00:00:00 2001 From: Luis Felipe Mileo Date: Mon, 24 Jul 2017 06:47:46 -0300 Subject: [PATCH 52/60] =?UTF-8?q?[NEW]=20Configura=C3=A7=C3=B5es=20de=20ge?= =?UTF-8?q?ra=C3=A7=C3=A3o=20de=20financeiro=20nos=20modos=20de=20pagament?= =?UTF-8?q?o?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../models/payment_mode.py | 22 +++++++++++++---- .../payment_mode/payment_mode_base_view.xml | 24 +++++++++++++++---- 2 files changed, 37 insertions(+), 9 deletions(-) diff --git a/l10n_br_financial_payment_order/models/payment_mode.py b/l10n_br_financial_payment_order/models/payment_mode.py index 3785c8d..1ed1654 100644 --- a/l10n_br_financial_payment_order/models/payment_mode.py +++ b/l10n_br_financial_payment_order/models/payment_mode.py @@ -187,13 +187,27 @@ class PaymentMode(models.Model): gera_financeiro_remessa = fields.Boolean( string='Gerar lançamento financeiro ao processar a remessa', ) + remessa_financial_account_id = fields.Many2one( + comodel_name='financial.account', + string='Conta financeira', + domain=[('type', '=', 'A')], + ) + remessa_document_type_id = fields.Many2one( + comodel_name='financial.document.type', + string='Tipo de documento', + ) gera_financeiro_retorno = fields.Boolean( string='Gerar lançamento financeiro ao processar o retorno', ) - # boleto_type = fields.Selection( - # boleto_selection, - # string='Boleto' - # ) + retorno_financial_account_id = fields.Many2one( + comodel_name='financial.account', + string='Conta financeira', + domain=[('type', '=', 'A')], + ) + retorno_document_type_id = fields.Many2one( + comodel_name='financial.document.type', + string='Tipo de documento', + ) @api.depends('tipo_servico') def _compute_sale_purchase_ok(self): diff --git a/l10n_br_financial_payment_order/views/payment_mode/payment_mode_base_view.xml b/l10n_br_financial_payment_order/views/payment_mode/payment_mode_base_view.xml index dacb716..4e9d47d 100644 --- a/l10n_br_financial_payment_order/views/payment_mode/payment_mode_base_view.xml +++ b/l10n_br_financial_payment_order/views/payment_mode/payment_mode_base_view.xml @@ -64,10 +64,10 @@ - + - + @@ -75,9 +75,23 @@ attrs="{'invisible':[('nivel_aprovacao','!=','2')],'required':[('nivel_aprovacao','=','2')]}" /> - - - + + + + + + + + + + + From 88794dff83c6655927b427bea884ae99d6d92e0e Mon Sep 17 00:00:00 2001 From: Luis Felipe Mileo Date: Mon, 24 Jul 2017 06:48:26 -0300 Subject: [PATCH 53/60] [FIX] Typo --- l10n_br_financial_payment_order/views/bank_payment_line.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/l10n_br_financial_payment_order/views/bank_payment_line.xml b/l10n_br_financial_payment_order/views/bank_payment_line.xml index 6a94875..4a47644 100644 --- a/l10n_br_financial_payment_order/views/bank_payment_line.xml +++ b/l10n_br_financial_payment_order/views/bank_payment_line.xml @@ -12,7 +12,7 @@
-
From 6ec4dcce3b546e1b9c67d03cedcd6ee185ac1fea Mon Sep 17 00:00:00 2001 From: Luis Felipe Mileo Date: Mon, 24 Jul 2017 06:50:12 -0300 Subject: [PATCH 54/60] =?UTF-8?q?[NEW]=20Gera=C3=A7=C3=A3o=20de=20lan?= =?UTF-8?q?=C3=A7amentos=20financeiros=20a=20partir=20da=20ordem=20de=20pa?= =?UTF-8?q?gamento?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../models/inherited_payment_order.py | 58 +++++++++++++++++++ .../payment_order/payment_order_base_view.xml | 5 +- 2 files changed, 62 insertions(+), 1 deletion(-) diff --git a/l10n_br_financial_payment_order/models/inherited_payment_order.py b/l10n_br_financial_payment_order/models/inherited_payment_order.py index 75d0d5d..b6fcfac 100644 --- a/l10n_br_financial_payment_order/models/inherited_payment_order.py +++ b/l10n_br_financial_payment_order/models/inherited_payment_order.py @@ -29,6 +29,15 @@ def _compute_nivel_aprovacao(self): for record in self: record.nivel_aprovacao = int(record.mode.nivel_aprovacao) + @api.multi + @api.depends('mode.tipo_pagamento') + def _compute_financial_type(self): + for record in self: + if record.mode.tipo_pagamento == 'boleto': + record.financial_type = FINANCIAL_DEBT_2RECEIVE + else: + record.financial_type = FINANCIAL_DEBT_2PAY + state = fields.Selection( selection=[ ('draft', 'Rascunho'), @@ -73,6 +82,13 @@ def _compute_nivel_aprovacao(self): compute='_compute_nivel_aprovacao', ) + financial_type = fields.Selection( + selection=[ + (FINANCIAL_DEBT_2RECEIVE,'A receber'), + (FINANCIAL_DEBT_2PAY, 'A pagar'), + ], + compute='_compute_financial_type', + ) @api.multi def action_open(self): @@ -250,6 +266,48 @@ def financial_payment_import(self): return + @api.multi + def gera_financeiro_remessa(self): + for record in self: + if len(record.line_ids) == 1: + partner = record.line_ids[0].partner_id + else: + partner = record.company_id.partner_id + + date = record.date_scheduled + + dados = { + 'date_document': record.date_done, + 'partner_id': partner.id, + 'company_id': record.company_id.id, + 'doc_source_id': 'payment.order,' + str(record.id), + 'currency_id': record.company_id.currency_id.id, + # 'payment_order_id': record.id, + 'document_type_id': + record.mode.remessa_document_type_id.id, + 'account_id': record.mode.remessa_financial_account_id.id, + 'date_maturity': date, + 'amount_document': record.total, + 'document_number': + '{0.name}-{1.reference}-({2})'.format( + record.mode, record, + unicode(len(record.line_ids))), + 'payment_mode_id': record.mode.id, + 'type': record.financial_type, + } + + finacial_move_id = self.env['financial.move'].create(dados) + # TODO: Melhorar este metodo! + + @api.multi + def action_done(self): + result = super(PaymentOrder, self).action_done() + + # for record in self: + # if record.state == 'done' and record.mode.gera_financeiro_remessa: + # record.gera_financeiro_remessa() + return True + @api.multi def launch_wizard(self): """Search for a wizard to launch according to the type. diff --git a/l10n_br_financial_payment_order/views/payment_order/payment_order_base_view.xml b/l10n_br_financial_payment_order/views/payment_order/payment_order_base_view.xml index c9e9d0f..739ea4e 100644 --- a/l10n_br_financial_payment_order/views/payment_order/payment_order_base_view.xml +++ b/l10n_br_financial_payment_order/views/payment_order/payment_order_base_view.xml @@ -36,9 +36,12 @@