diff --git a/l10n_br_account/tests/common.py b/l10n_br_account/tests/common.py index 7f477b4ab800..beab652ba78c 100644 --- a/l10n_br_account/tests/common.py +++ b/l10n_br_account/tests/common.py @@ -72,6 +72,7 @@ def setUpClass(cls, chart_template_ref=None): "taxes_id": False, "tax_icms_or_issqn": "icms", "uoe_id": cls.env.ref("uom.product_uom_kgm").id, + "default_code": "PRODUCT_B", } ) cls.fiscal_type_product_product_b = cls.env["ir.property"].create( diff --git a/l10n_br_account_nfe/README.rst b/l10n_br_account_nfe/README.rst new file mode 100644 index 000000000000..fcdb33c190c1 --- /dev/null +++ b/l10n_br_account_nfe/README.rst @@ -0,0 +1,139 @@ +============================= +Account NFe/NFC-e Integration +============================= + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:e13f8f0153ea0f7311fe4f10f09547648467a34650d59726ad92e3753ebd8bfe + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fl10n--brazil-lightgray.png?logo=github + :target: https://github.com/OCA/l10n-brazil/tree/14.0/l10n_br_account_nfe + :alt: OCA/l10n-brazil +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/l10n-brazil-14-0/l10n-brazil-14-0-l10n_br_account_nfe + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/l10n-brazil&target_branch=14.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +**Português** +Este módulo integra os módulos l10n_br_account e l10n_br_nfe. + +* Adicionando as informações de Pagamento e Duplicatas da Fatura, TAGs cobr, pag e dup da NF-e/NFC-e. + +**English** +This module integrates the l10n_br_account and l10n_br_nfe modules. + +* Adding Payment Information and Invoice Duplicates, TAGs cobr, pag and dup of NF-e/NFC-e. + +**Table of contents** + +.. contents:: + :local: + +Configuration +============= + +**Português** +Crie o Modo de Pagamento e informe o campo Meio de Pagamento da NF: +Faturamento > Configuração > Administração > Modos de Pagamento + +**English** +Create the Payment Mode and inform the field Meio de Pagamento da NF: +Invoicing > Configuration > Management > Payment Modes + +Usage +===== + +**Português** +Ao Confirmar um Documento Fiscal do tipo NFe ou NFCe, os dados das Tags de Pagamento e Duplicatas serão criados automaticamente. + +**English** +When Confirming a NFe or NFCe Fiscal Document, the Payment Tags and Duplicates data will be created automatically. + +Known issues / Roadmap +====================== + +* Existe a possibilidade de criar uma Nota Fiscal com múltiplos Modos/Meio de Pagamentos RFC https://github.com/OCA/l10n-brazil/issues/1850 + +Changelog +========= + +12.0.1.0.0 (2022-03-30) +~~~~~~~~~~~~~~~~~~~~~~~ + +* [NEW] Primeira versão + +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 to smash it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +~~~~~~~ + +* Engenere +* Akretion + +Contributors +~~~~~~~~~~~~ + +* `Engenere `_: + + * Felipe Motter Pereira + * Antônio S. Pereira Neto + +* `Akretion `_: + + * Magno Barcelo da Costa + +Maintainers +~~~~~~~~~~~ + +This module is maintained by the OCA. + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +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. + +.. |maintainer-antoniospneto| image:: https://github.com/antoniospneto.png?size=40px + :target: https://github.com/antoniospneto + :alt: antoniospneto +.. |maintainer-felipemotter| image:: https://github.com/felipemotter.png?size=40px + :target: https://github.com/felipemotter + :alt: felipemotter +.. |maintainer-mbcosta| image:: https://github.com/mbcosta.png?size=40px + :target: https://github.com/mbcosta + :alt: mbcosta + +Current `maintainers `__: + +|maintainer-antoniospneto| |maintainer-felipemotter| |maintainer-mbcosta| + +This module is part of the `OCA/l10n-brazil `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/l10n_br_account_nfe/__init__.py b/l10n_br_account_nfe/__init__.py new file mode 100644 index 000000000000..2bff2401c53e --- /dev/null +++ b/l10n_br_account_nfe/__init__.py @@ -0,0 +1,4 @@ +from .hooks import post_init_hook + +from . import models +from . import report diff --git a/l10n_br_account_nfe/__manifest__.py b/l10n_br_account_nfe/__manifest__.py new file mode 100644 index 000000000000..da00e30d52de --- /dev/null +++ b/l10n_br_account_nfe/__manifest__.py @@ -0,0 +1,30 @@ +# Copyright (C) 2022-Today - Engenere (). +# @author Antônio S. Pereira Neto +# @author Felipe Motter Pereira +# Copyright (C) 2022-Today - Akretion (). +# @author Magno Costa +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +{ + "name": "Account NFe/NFC-e Integration", + "summary": "Integration between l10n_br_account and l10n_br_nfe", + "category": "Localisation", + "license": "AGPL-3", + "author": "Engenere," "Akretion," "Odoo Community Association (OCA)", + "maintainers": ["antoniospneto", "felipemotter", "mbcosta"], + "website": "https://github.com/OCA/l10n-brazil", + "version": "15.0.1.0.0", + "development_status": "Beta", + "depends": [ + "l10n_br_nfe", + "l10n_br_account", + "account_payment_partner", + ], + "data": [ + "views/account_payment_mode.xml", + "report/danfe_report.xml", + ], + "post_init_hook": "post_init_hook", + "installable": True, + "auto_install": True, +} diff --git a/l10n_br_account_nfe/demo/account_invoice_sn_demo.xml b/l10n_br_account_nfe/demo/account_invoice_sn_demo.xml new file mode 100644 index 000000000000..ce4e36f554b2 --- /dev/null +++ b/l10n_br_account_nfe/demo/account_invoice_sn_demo.xml @@ -0,0 +1,113 @@ + + + + + + 30/60/90 + Payment terms: 30/60/90 + + + + + + + Diário de Boleto - Simples Nacional + TPO + bank + + + + + + Boleto + + + 15 + fixed + + + + + + Teste NFe Dados de Cobrança + + + + out_invoice + + + + + + 1 + + + + + + Teste NFe Sem Dados de Cobrança + + + out_invoice + + + + + 1 + out + + + + diff --git a/l10n_br_account_nfe/hooks.py b/l10n_br_account_nfe/hooks.py new file mode 100644 index 000000000000..351792dcf3ff --- /dev/null +++ b/l10n_br_account_nfe/hooks.py @@ -0,0 +1,55 @@ +# Copyright (C) 2022-Today - Engenere (). +# @author Antônio S. Pereira Neto +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import SUPERUSER_ID, api, tools + + +def post_init_hook(cr, registry): + env = api.Environment(cr, SUPERUSER_ID, {}) + load_simples_nacional_demo(env, registry) + + +def load_simples_nacional_demo(env, registry): + """ + Load demo data for company 'Simples Nacional' with + default user company set to this company. + """ + + # Load XML file with demo data. + company_sn = env.ref( + "l10n_br_base.empresa_simples_nacional", raise_if_not_found=False + ) + if company_sn: + # Allow all companies for OdooBot user and set default user company + companies = env["res.company"].search([]) + env.user.company_ids = [(6, 0, companies.ids)] + env.user.company_id = company_sn + + tools.convert_file( + env.cr, + "l10n_br_account_nfe", + "demo/account_invoice_sn_demo.xml", + None, + mode="init", + noupdate=True, + kind="demo", + ) + + # É necessário rodar os onchanges fiscais para + # preencher os campos referentes aos Impostos + invoice_tag_cobranca = env.ref("l10n_br_account_nfe.demo_nfe_dados_de_cobranca") + for line in invoice_tag_cobranca.invoice_line_ids: + line._onchange_fiscal_operation_line_id() + line._onchange_fiscal_tax_ids() + + invoice_sem_tag_cobranca = env.ref( + "l10n_br_account_nfe.demo_nfe_sem_dados_de_cobranca" + ) + for line in invoice_sem_tag_cobranca.invoice_line_ids: + line._onchange_fiscal_operation_line_id() + line._onchange_fiscal_tax_ids() + + # back to the main company as the next modules to be installed + # expect this to be the default company. + env.user.company_id = env.ref("base.main_company") diff --git a/l10n_br_account_nfe/i18n/l10n_br_account_nfe.pot b/l10n_br_account_nfe/i18n/l10n_br_account_nfe.pot new file mode 100644 index 000000000000..ae2077d3bb78 --- /dev/null +++ b/l10n_br_account_nfe/i18n/l10n_br_account_nfe.pot @@ -0,0 +1,227 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * l10n_br_account_nfe +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 14.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: l10n_br_account_nfe +#: model:ir.actions.report,print_report_name:l10n_br_account_nfe.report_danfe_account +msgid "'%s' % (object.document_key)" +msgstr "" + +#. module: l10n_br_account_nfe +#: model:ir.model.fields.selection,name:l10n_br_account_nfe.selection__account_payment_mode__fiscal_payment_mode__01 +msgid "01 - Dinheiro" +msgstr "" + +#. module: l10n_br_account_nfe +#: model:ir.model.fields.selection,name:l10n_br_account_nfe.selection__account_payment_mode__fiscal_payment_mode__02 +msgid "02 - Cheque" +msgstr "" + +#. module: l10n_br_account_nfe +#: model:ir.model.fields.selection,name:l10n_br_account_nfe.selection__account_payment_mode__fiscal_payment_mode__03 +msgid "03 - Cartão de Crédito" +msgstr "" + +#. module: l10n_br_account_nfe +#: model:ir.model.fields.selection,name:l10n_br_account_nfe.selection__account_payment_mode__fiscal_payment_mode__04 +msgid "04 - Cartão de Débito" +msgstr "" + +#. module: l10n_br_account_nfe +#: model:ir.model.fields.selection,name:l10n_br_account_nfe.selection__account_payment_mode__fiscal_payment_mode__05 +msgid "05 - Crédito de Loja" +msgstr "" + +#. module: l10n_br_account_nfe +#: model:ir.model.fields.selection,name:l10n_br_account_nfe.selection__account_payment_mode__fiscal_payment_mode__10 +msgid "10 - Vale Alimentação" +msgstr "" + +#. module: l10n_br_account_nfe +#: model:ir.model.fields.selection,name:l10n_br_account_nfe.selection__account_payment_mode__fiscal_payment_mode__11 +msgid "11 - Vale Refeição" +msgstr "" + +#. module: l10n_br_account_nfe +#: model:ir.model.fields.selection,name:l10n_br_account_nfe.selection__account_payment_mode__fiscal_payment_mode__12 +msgid "12 - Vale Presente" +msgstr "" + +#. module: l10n_br_account_nfe +#: model:ir.model.fields.selection,name:l10n_br_account_nfe.selection__account_payment_mode__fiscal_payment_mode__13 +msgid "13 - Vale Combustível" +msgstr "" + +#. module: l10n_br_account_nfe +#: model:ir.model.fields.selection,name:l10n_br_account_nfe.selection__account_payment_mode__fiscal_payment_mode__14 +msgid "14 - Duplicata Mercanti" +msgstr "" + +#. module: l10n_br_account_nfe +#: model:ir.model.fields.selection,name:l10n_br_account_nfe.selection__account_payment_mode__fiscal_payment_mode__15 +msgid "15 - Boleto Bancário" +msgstr "" + +#. module: l10n_br_account_nfe +#: model:ir.model.fields.selection,name:l10n_br_account_nfe.selection__account_payment_mode__fiscal_payment_mode__16 +msgid "16 - Depósito Bancário" +msgstr "" + +#. module: l10n_br_account_nfe +#: model:ir.model.fields.selection,name:l10n_br_account_nfe.selection__account_payment_mode__fiscal_payment_mode__17 +msgid "17 - Pagamento Instantâneo (PIX)" +msgstr "" + +#. module: l10n_br_account_nfe +#: model:ir.model.fields.selection,name:l10n_br_account_nfe.selection__account_payment_mode__fiscal_payment_mode__18 +msgid "18 - Transferência bancária, Carteira Digital" +msgstr "" + +#. module: l10n_br_account_nfe +#: model:ir.model.fields.selection,name:l10n_br_account_nfe.selection__account_payment_mode__fiscal_payment_mode__19 +msgid "19 - Programa de fidelidade, Cashback, Crédito Virtual" +msgstr "" + +#. module: l10n_br_account_nfe +#: model:account.payment.term,name:l10n_br_account_nfe.account_payment_term_30_60_90 +msgid "30/60/90" +msgstr "" + +#. module: l10n_br_account_nfe +#: model:ir.model.fields.selection,name:l10n_br_account_nfe.selection__account_payment_mode__fiscal_payment_mode__90 +msgid "90 - Sem Pagamento" +msgstr "" + +#. module: l10n_br_account_nfe +#: model:ir.model.fields.selection,name:l10n_br_account_nfe.selection__account_payment_mode__fiscal_payment_mode__99 +msgid "99 - Outros" +msgstr "" + +#. module: l10n_br_account_nfe +#: model:account.payment.mode,name:l10n_br_account_nfe.demo_payment_mode_boleto +msgid "Boleto" +msgstr "" + +#. module: l10n_br_account_nfe +#: model:ir.actions.report,name:l10n_br_account_nfe.report_danfe_account +msgid "DANFE" +msgstr "" + +#. module: l10n_br_account_nfe +#: model:ir.model.fields,field_description:l10n_br_account_nfe.field_account_bank_statement_line__nfe40_dup +#: model:ir.model.fields,field_description:l10n_br_account_nfe.field_account_move__nfe40_dup +#: model:ir.model.fields,field_description:l10n_br_account_nfe.field_account_payment__nfe40_dup +#: model:ir.model.fields,field_description:l10n_br_account_nfe.field_l10n_br_fiscal_document__nfe40_dup +msgid "Dados das duplicatas NT 2011/004" +msgstr "" + +#. module: l10n_br_account_nfe +#: model:ir.model.fields,field_description:l10n_br_account_nfe.field_account_payment_mode__display_name +#: model:ir.model.fields,field_description:l10n_br_account_nfe.field_ir_actions_report__display_name +#: model:ir.model.fields,field_description:l10n_br_account_nfe.field_l10n_br_fiscal_document__display_name +#: model:ir.model.fields,field_description:l10n_br_account_nfe.field_nfe_40_detpag__display_name +msgid "Display Name" +msgstr "" + +#. module: l10n_br_account_nfe +#: model:ir.model,name:l10n_br_account_nfe.model_l10n_br_fiscal_document +msgid "Fiscal Document" +msgstr "" + +#. module: l10n_br_account_nfe +#: model:ir.model.fields,field_description:l10n_br_account_nfe.field_nfe_40_detpag__nfe40_indPag +msgid "Forma de Pagamento" +msgstr "" + +#. module: l10n_br_account_nfe +#: model:ir.model.fields,field_description:l10n_br_account_nfe.field_account_bank_statement_line__nfe40_detPag +#: model:ir.model.fields,field_description:l10n_br_account_nfe.field_account_move__nfe40_detPag +#: model:ir.model.fields,field_description:l10n_br_account_nfe.field_account_payment__nfe40_detPag +#: model:ir.model.fields,field_description:l10n_br_account_nfe.field_l10n_br_fiscal_document__nfe40_detPag +msgid "Grupo de detalhamento da forma" +msgstr "" + +#. module: l10n_br_account_nfe +#: model:ir.model,name:l10n_br_account_nfe.model_nfe_40_detpag +#: model:ir.model.fields,help:l10n_br_account_nfe.field_account_bank_statement_line__nfe40_detPag +#: model:ir.model.fields,help:l10n_br_account_nfe.field_account_move__nfe40_detPag +#: model:ir.model.fields,help:l10n_br_account_nfe.field_account_payment__nfe40_detPag +#: model:ir.model.fields,help:l10n_br_account_nfe.field_l10n_br_fiscal_document__nfe40_detPag +msgid "Grupo de detalhamento da forma de pagamento." +msgstr "" + +#. module: l10n_br_account_nfe +#: model:ir.model.fields,field_description:l10n_br_account_nfe.field_account_payment_mode__id +#: model:ir.model.fields,field_description:l10n_br_account_nfe.field_ir_actions_report__id +#: model:ir.model.fields,field_description:l10n_br_account_nfe.field_l10n_br_fiscal_document__id +#: model:ir.model.fields,field_description:l10n_br_account_nfe.field_nfe_40_detpag__id +msgid "ID" +msgstr "" + +#. module: l10n_br_account_nfe +#: model:ir.model.fields,help:l10n_br_account_nfe.field_nfe_40_detpag__nfe40_indPag +msgid "Indicador da Forma de Pagamento" +msgstr "" + +#. module: l10n_br_account_nfe +#: model:ir.model.fields,field_description:l10n_br_account_nfe.field_account_payment_mode____last_update +#: model:ir.model.fields,field_description:l10n_br_account_nfe.field_ir_actions_report____last_update +#: model:ir.model.fields,field_description:l10n_br_account_nfe.field_l10n_br_fiscal_document____last_update +#: model:ir.model.fields,field_description:l10n_br_account_nfe.field_nfe_40_detpag____last_update +msgid "Last Modified on" +msgstr "" + +#. module: l10n_br_account_nfe +#: model:ir.model.fields,field_description:l10n_br_account_nfe.field_account_payment_mode__fiscal_payment_mode +msgid "Meio de Pagamento da NF" +msgstr "" + +#. module: l10n_br_account_nfe +#: model:ir.model.fields,help:l10n_br_account_nfe.field_account_payment_mode__fiscal_payment_mode +msgid "" +"Obrigatório o preenchimento do Grupo Informações de Pagamento para NF-e e " +"NFC-e. Para as notas com finalidade de Ajuste ou Devolução o campo Forma de " +"Pagamento deve ser preenchido com 90 - Sem Pagamento." +msgstr "" + +#. module: l10n_br_account_nfe +#: model:ir.model.fields.selection,name:l10n_br_account_nfe.selection__nfe_40_detpag__nfe40_indPag__1 +msgid "Pagamento à Prazo" +msgstr "" + +#. module: l10n_br_account_nfe +#: model:ir.model.fields.selection,name:l10n_br_account_nfe.selection__nfe_40_detpag__nfe40_indPag__0 +msgid "Pagamento à Vista" +msgstr "" + +#. module: l10n_br_account_nfe +#: code:addons/l10n_br_account_nfe/models/document.py:0 +#, python-format +msgid "Payment Mode cannot be empty for this NF-e/NFC-e" +msgstr "" + +#. module: l10n_br_account_nfe +#: model:ir.model,name:l10n_br_account_nfe.model_account_payment_mode +msgid "Payment Modes" +msgstr "" + +#. module: l10n_br_account_nfe +#: model:account.payment.term,note:l10n_br_account_nfe.account_payment_term_30_60_90 +msgid "Payment terms: 30/60/90" +msgstr "" + +#. module: l10n_br_account_nfe +#: model:ir.model,name:l10n_br_account_nfe.model_ir_actions_report +msgid "Report Action" +msgstr "" diff --git a/l10n_br_account_nfe/i18n/pt_BR.po b/l10n_br_account_nfe/i18n/pt_BR.po new file mode 100644 index 000000000000..4c3d7bb698dd --- /dev/null +++ b/l10n_br_account_nfe/i18n/pt_BR.po @@ -0,0 +1,243 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * l10n_br_account_nfe +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 14.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2024-07-19 04:58+0000\n" +"Last-Translator: Antônio Neto \n" +"Language-Team: none\n" +"Language: pt_BR\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n > 1;\n" +"X-Generator: Weblate 5.6.2\n" + +#. module: l10n_br_account_nfe +#: model:ir.actions.report,print_report_name:l10n_br_account_nfe.report_danfe_account +msgid "'%s' % (object.document_key)" +msgstr "" + +#. module: l10n_br_account_nfe +#: model:ir.model.fields.selection,name:l10n_br_account_nfe.selection__account_payment_mode__fiscal_payment_mode__01 +msgid "01 - Dinheiro" +msgstr "01 - Dinheiro" + +#. module: l10n_br_account_nfe +#: model:ir.model.fields.selection,name:l10n_br_account_nfe.selection__account_payment_mode__fiscal_payment_mode__02 +msgid "02 - Cheque" +msgstr "02 - Cheque" + +#. module: l10n_br_account_nfe +#: model:ir.model.fields.selection,name:l10n_br_account_nfe.selection__account_payment_mode__fiscal_payment_mode__03 +msgid "03 - Cartão de Crédito" +msgstr "03 - Cartão de Crédito" + +#. module: l10n_br_account_nfe +#: model:ir.model.fields.selection,name:l10n_br_account_nfe.selection__account_payment_mode__fiscal_payment_mode__04 +msgid "04 - Cartão de Débito" +msgstr "04 - Cartão de Débito" + +#. module: l10n_br_account_nfe +#: model:ir.model.fields.selection,name:l10n_br_account_nfe.selection__account_payment_mode__fiscal_payment_mode__05 +msgid "05 - Crédito de Loja" +msgstr "05 - Crédito de Loja" + +#. module: l10n_br_account_nfe +#: model:ir.model.fields.selection,name:l10n_br_account_nfe.selection__account_payment_mode__fiscal_payment_mode__10 +msgid "10 - Vale Alimentação" +msgstr "10 - Vale Alimentação" + +#. module: l10n_br_account_nfe +#: model:ir.model.fields.selection,name:l10n_br_account_nfe.selection__account_payment_mode__fiscal_payment_mode__11 +msgid "11 - Vale Refeição" +msgstr "11 - Vale Refeição" + +#. module: l10n_br_account_nfe +#: model:ir.model.fields.selection,name:l10n_br_account_nfe.selection__account_payment_mode__fiscal_payment_mode__12 +msgid "12 - Vale Presente" +msgstr "12 - Vale Presente" + +#. module: l10n_br_account_nfe +#: model:ir.model.fields.selection,name:l10n_br_account_nfe.selection__account_payment_mode__fiscal_payment_mode__13 +msgid "13 - Vale Combustível" +msgstr "13 - Vale Combustível" + +#. module: l10n_br_account_nfe +#: model:ir.model.fields.selection,name:l10n_br_account_nfe.selection__account_payment_mode__fiscal_payment_mode__14 +msgid "14 - Duplicata Mercanti" +msgstr "14 - Duplicata Mercanti" + +#. module: l10n_br_account_nfe +#: model:ir.model.fields.selection,name:l10n_br_account_nfe.selection__account_payment_mode__fiscal_payment_mode__15 +msgid "15 - Boleto Bancário" +msgstr "15 - Boleto Bancário" + +#. module: l10n_br_account_nfe +#: model:ir.model.fields.selection,name:l10n_br_account_nfe.selection__account_payment_mode__fiscal_payment_mode__16 +msgid "16 - Depósito Bancário" +msgstr "16 - Depósito Bancário" + +#. module: l10n_br_account_nfe +#: model:ir.model.fields.selection,name:l10n_br_account_nfe.selection__account_payment_mode__fiscal_payment_mode__17 +msgid "17 - Pagamento Instantâneo (PIX)" +msgstr "17 - Pagamento Instantâneo (PIX)" + +#. module: l10n_br_account_nfe +#: model:ir.model.fields.selection,name:l10n_br_account_nfe.selection__account_payment_mode__fiscal_payment_mode__18 +msgid "18 - Transferência bancária, Carteira Digital" +msgstr "18 - Transferência bancária, Carteira Digital" + +#. module: l10n_br_account_nfe +#: model:ir.model.fields.selection,name:l10n_br_account_nfe.selection__account_payment_mode__fiscal_payment_mode__19 +msgid "19 - Programa de fidelidade, Cashback, Crédito Virtual" +msgstr "19 - Programa de fidelidade, Cashback, Crédito Virtual" + +#. module: l10n_br_account_nfe +#: model:account.payment.term,name:l10n_br_account_nfe.account_payment_term_30_60_90 +msgid "30/60/90" +msgstr "30/60/90" + +#. module: l10n_br_account_nfe +#: model:ir.model.fields.selection,name:l10n_br_account_nfe.selection__account_payment_mode__fiscal_payment_mode__90 +msgid "90 - Sem Pagamento" +msgstr "90 - Sem Pagamento" + +#. module: l10n_br_account_nfe +#: model:ir.model.fields.selection,name:l10n_br_account_nfe.selection__account_payment_mode__fiscal_payment_mode__99 +msgid "99 - Outros" +msgstr "99 - Outros" + +#. module: l10n_br_account_nfe +#: model:account.payment.mode,name:l10n_br_account_nfe.demo_payment_mode_boleto +msgid "Boleto" +msgstr "Boleto" + +#. module: l10n_br_account_nfe +#: model:ir.actions.report,name:l10n_br_account_nfe.report_danfe_account +msgid "DANFE" +msgstr "" + +#. module: l10n_br_account_nfe +#: model:ir.model.fields,field_description:l10n_br_account_nfe.field_account_bank_statement_line__nfe40_dup +#: model:ir.model.fields,field_description:l10n_br_account_nfe.field_account_move__nfe40_dup +#: model:ir.model.fields,field_description:l10n_br_account_nfe.field_account_payment__nfe40_dup +#: model:ir.model.fields,field_description:l10n_br_account_nfe.field_l10n_br_fiscal_document__nfe40_dup +#, fuzzy +msgid "Dados das duplicatas NT 2011/004" +msgstr "Dados das duplicatas NT 2011/004" + +#. module: l10n_br_account_nfe +#: model:ir.model.fields,field_description:l10n_br_account_nfe.field_account_payment_mode__display_name +#: model:ir.model.fields,field_description:l10n_br_account_nfe.field_ir_actions_report__display_name +#: model:ir.model.fields,field_description:l10n_br_account_nfe.field_l10n_br_fiscal_document__display_name +#: model:ir.model.fields,field_description:l10n_br_account_nfe.field_nfe_40_detpag__display_name +msgid "Display Name" +msgstr "Nome Exibido" + +#. module: l10n_br_account_nfe +#: model:ir.model,name:l10n_br_account_nfe.model_l10n_br_fiscal_document +msgid "Fiscal Document" +msgstr "Documento Fiscal" + +#. module: l10n_br_account_nfe +#: model:ir.model.fields,field_description:l10n_br_account_nfe.field_nfe_40_detpag__nfe40_indPag +#, fuzzy +msgid "Forma de Pagamento" +msgstr "Forma de Pagamento" + +#. module: l10n_br_account_nfe +#: model:ir.model.fields,field_description:l10n_br_account_nfe.field_account_bank_statement_line__nfe40_detPag +#: model:ir.model.fields,field_description:l10n_br_account_nfe.field_account_move__nfe40_detPag +#: model:ir.model.fields,field_description:l10n_br_account_nfe.field_account_payment__nfe40_detPag +#: model:ir.model.fields,field_description:l10n_br_account_nfe.field_l10n_br_fiscal_document__nfe40_detPag +#, fuzzy +msgid "Grupo de detalhamento da forma" +msgstr "Grupo de detalhamento da forma" + +#. module: l10n_br_account_nfe +#: model:ir.model,name:l10n_br_account_nfe.model_nfe_40_detpag +#: model:ir.model.fields,help:l10n_br_account_nfe.field_account_bank_statement_line__nfe40_detPag +#: model:ir.model.fields,help:l10n_br_account_nfe.field_account_move__nfe40_detPag +#: model:ir.model.fields,help:l10n_br_account_nfe.field_account_payment__nfe40_detPag +#: model:ir.model.fields,help:l10n_br_account_nfe.field_l10n_br_fiscal_document__nfe40_detPag +#, fuzzy +msgid "Grupo de detalhamento da forma de pagamento." +msgstr "Grupo de detalhamento da forma de pagamento." + +#. module: l10n_br_account_nfe +#: model:ir.model.fields,field_description:l10n_br_account_nfe.field_account_payment_mode__id +#: model:ir.model.fields,field_description:l10n_br_account_nfe.field_ir_actions_report__id +#: model:ir.model.fields,field_description:l10n_br_account_nfe.field_l10n_br_fiscal_document__id +#: model:ir.model.fields,field_description:l10n_br_account_nfe.field_nfe_40_detpag__id +msgid "ID" +msgstr "ID" + +#. module: l10n_br_account_nfe +#: model:ir.model.fields,help:l10n_br_account_nfe.field_nfe_40_detpag__nfe40_indPag +#, fuzzy +msgid "Indicador da Forma de Pagamento" +msgstr "Indicador da Forma de Pagamento" + +#. module: l10n_br_account_nfe +#: model:ir.model.fields,field_description:l10n_br_account_nfe.field_account_payment_mode____last_update +#: model:ir.model.fields,field_description:l10n_br_account_nfe.field_ir_actions_report____last_update +#: model:ir.model.fields,field_description:l10n_br_account_nfe.field_l10n_br_fiscal_document____last_update +#: model:ir.model.fields,field_description:l10n_br_account_nfe.field_nfe_40_detpag____last_update +msgid "Last Modified on" +msgstr "Última Modificação em" + +#. module: l10n_br_account_nfe +#: model:ir.model.fields,field_description:l10n_br_account_nfe.field_account_payment_mode__fiscal_payment_mode +msgid "Meio de Pagamento da NF" +msgstr "Meio de Pagamento da NF" + +#. module: l10n_br_account_nfe +#: model:ir.model.fields,help:l10n_br_account_nfe.field_account_payment_mode__fiscal_payment_mode +msgid "" +"Obrigatório o preenchimento do Grupo Informações de Pagamento para NF-e e " +"NFC-e. Para as notas com finalidade de Ajuste ou Devolução o campo Forma de " +"Pagamento deve ser preenchido com 90 - Sem Pagamento." +msgstr "" +"Obrigatório o preenchimento do Grupo Informações de Pagamento para NF-e e " +"NFC-e. Para as notas com finalidade de Ajuste ou Devolução o campo Forma de " +"Pagamento deve ser preenchido com 90 - Sem Pagamento." + +#. module: l10n_br_account_nfe +#: model:ir.model.fields.selection,name:l10n_br_account_nfe.selection__nfe_40_detpag__nfe40_indPag__1 +#, fuzzy +msgid "Pagamento à Prazo" +msgstr "Pagamento à Prazo" + +#. module: l10n_br_account_nfe +#: model:ir.model.fields.selection,name:l10n_br_account_nfe.selection__nfe_40_detpag__nfe40_indPag__0 +#, fuzzy +msgid "Pagamento à Vista" +msgstr "Pagamento à Vista" + +#. module: l10n_br_account_nfe +#: code:addons/l10n_br_account_nfe/models/document.py:0 +#, python-format +msgid "Payment Mode cannot be empty for this NF-e/NFC-e" +msgstr "O Modo de Pagamento não pode estar vazio para esta NF-e/NFC-e" + +#. module: l10n_br_account_nfe +#: model:ir.model,name:l10n_br_account_nfe.model_account_payment_mode +msgid "Payment Modes" +msgstr "Modos de Pagamento" + +#. module: l10n_br_account_nfe +#: model:account.payment.term,note:l10n_br_account_nfe.account_payment_term_30_60_90 +msgid "Payment terms: 30/60/90" +msgstr "Condição de pagamento: 30/60/90" + +#. module: l10n_br_account_nfe +#: model:ir.model,name:l10n_br_account_nfe.model_ir_actions_report +msgid "Report Action" +msgstr "" + +#~ msgid "Journal Item" +#~ msgstr "Item de Diário" diff --git a/l10n_br_account_nfe/models/__init__.py b/l10n_br_account_nfe/models/__init__.py new file mode 100644 index 000000000000..83aec13f5527 --- /dev/null +++ b/l10n_br_account_nfe/models/__init__.py @@ -0,0 +1,3 @@ +from . import account_payment_mode +from . import document +from . import leiauteNFe diff --git a/l10n_br_account_nfe/models/account_payment_mode.py b/l10n_br_account_nfe/models/account_payment_mode.py new file mode 100644 index 000000000000..d7e547992ca8 --- /dev/null +++ b/l10n_br_account_nfe/models/account_payment_mode.py @@ -0,0 +1,23 @@ +# Copyright (C) 2022-Today - Engenere (). +# @author Antônio S. Pereira Neto +# @author Felipe Motter Pereira +# Copyright (C) 2022-Today - Akretion (). +# @author Magno Costa +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import fields, models + +from odoo.addons.l10n_br_fiscal.constants.fiscal import FISCAL_PAYMENT_MODE + + +class AccountPaymentMode(models.Model): + _inherit = "account.payment.mode" + + fiscal_payment_mode = fields.Selection( + selection=FISCAL_PAYMENT_MODE, + string="Meio de Pagamento da NF", + help="Obrigatório o preenchimento do Grupo Informações de Pagamento" + " para NF-e e NFC-e. Para as notas com finalidade de Ajuste" + " ou Devolução o campo Forma de Pagamento deve ser preenchido" + " com 90 - Sem Pagamento.", + ) diff --git a/l10n_br_account_nfe/models/document.py b/l10n_br_account_nfe/models/document.py new file mode 100644 index 000000000000..feb7a1ac7b86 --- /dev/null +++ b/l10n_br_account_nfe/models/document.py @@ -0,0 +1,167 @@ +# Copyright (C) 2022-Today - Engenere (). +# @author Antônio S. Pereira Neto +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + + +from odoo import _, api, fields, models +from odoo.exceptions import UserError + +from odoo.addons.l10n_br_fiscal.constants.fiscal import ( + EDOC_PURPOSE_AJUSTE, + EDOC_PURPOSE_DEVOLUCAO, +) + +A_PRAZO = "1" +A_VISTA = "0" +SEM_PAGAMENTO = "90" +NFE_IN = "0" +NFE_OUT = "1" + + +class DocumentNfe(models.Model): + _inherit = "l10n_br_fiscal.document" + + ########################## + # NF-e tag: Cob + ########################## + + nfe40_dup = fields.One2many( + comodel_name="nfe.40.dup", + compute="_compute_nfe40_dup", + store=True, + copy=False, + readonly=False, + ) + + ########################## + # NF-e tag: dup + # Compute Methods + ########################## + + @api.depends("move_ids", "move_ids.financial_move_line_ids") + def _compute_nfe40_dup(self): + for record in self.filtered(lambda x: x._need_compute_nfe40_dup()): + dups_vals = [] + for count, mov in enumerate(record.move_ids.financial_move_line_ids, 1): + dups_vals.append( + { + "nfe40_nDup": str(count).zfill(3), + "nfe40_dVenc": mov.date_maturity, + "nfe40_vDup": mov.debit, + } + ) + record.nfe40_dup = [(2, dup, 0) for dup in record.nfe40_dup.ids] + record.nfe40_dup = [(0, 0, dup) for dup in dups_vals] + + ########################## + # NF-e tag: Pag + ########################## + + nfe40_detPag = fields.One2many( + comodel_name="nfe.40.detpag", + compute="_compute_nfe40_detpag", + store=True, + readonly=False, + ) + + ########################## + # NF-e tag: detPag + # Compute Methods + ########################## + + @api.depends( + "issuer", + "move_ids", + "move_ids.payment_mode_id", + "move_ids.payment_mode_id.fiscal_payment_mode", + "amount_financial_total", + "nfe40_tpNF", + ) + def _compute_nfe40_detpag(self): + for rec in self.filtered(lambda x: x._need_compute_nfe_tags()): + if rec._is_without_payment(): + det_pag_vals = { + "nfe40_indPag": A_VISTA, + "nfe40_tPag": SEM_PAGAMENTO, + "nfe40_vPag": 0.00, + } + else: + # TODO pode haver pagamento que uma parte é a vista + # e outra a prazo, dividir em dois detPag nestes casos. + det_pag_vals = { + "nfe40_indPag": A_PRAZO if rec._is_installment() > 0 else A_VISTA, + "nfe40_tPag": rec.move_ids.payment_mode_id.fiscal_payment_mode + or "", + "nfe40_vPag": rec.amount_financial_total, + } + detpag_current = { + field: getattr(detpag, field, None) + for detpag in rec.nfe40_detPag + for field in det_pag_vals + } + if det_pag_vals != detpag_current: + rec.nfe40_detPag = [(2, detpag, 0) for detpag in rec.nfe40_detPag.ids] + rec.nfe40_detPag = [(0, 0, det_pag_vals)] + + ################################ + # Business Model Methods + ################################ + + def _is_installment(self): + """checks if the payment is in cash (á vista) or in installments (a prazo)""" + self.ensure_one() + self.move_ids.financial_move_line_ids.mapped("date_maturity") + moves_terms = self.move_ids.financial_move_line_ids.filtered( + lambda move_line: move_line.date_maturity + and move_line.date_maturity > move_line.date + ) + return True if len(moves_terms) > 0 else False + + def _need_compute_nfe40_dup(self): + if ( + self._need_compute_nfe_tags() + and self.amount_financial_total > 0 + and self.nfe40_tpNF == NFE_OUT + and self.document_type != "65" + ): + return True + else: + return False + + def _is_without_payment(self): + if self.edoc_purpose in (EDOC_PURPOSE_DEVOLUCAO, EDOC_PURPOSE_AJUSTE): + return True + if not self.amount_financial_total: + return True + if self.nfe40_tpNF == NFE_IN: + return True + else: + return False + + @api.constrains("nfe40_detPag", "state_edoc") + def _check_fiscal_payment_mode(self): + for rec in self: + if ( + rec.state_edoc == "em_digitacao" + or not rec._need_compute_nfe_tags() + or rec._is_without_payment() + ): + continue + + if not rec.move_ids.payment_mode_id: + raise UserError(_("Payment Mode cannot be empty for this NF-e/NFC-e")) + if not rec.move_ids.payment_mode_id.fiscal_payment_mode: + raise UserError( + _( + "Payment Mode %(mode)s should have " + "a Fiscal Payment Mode filled to be used in the Fiscal Document!", + mode=rec.move_ids.payment_mode_id.name, + ) + ) + + def _update_nfce_for_offline_contingency(self): + res = super()._update_nfce_for_offline_contingency() + if self.move_ids: + copy_invoice = self.move_ids[0].copy() + copy_invoice.action_post() + return res diff --git a/l10n_br_account_nfe/models/leiauteNFe.py b/l10n_br_account_nfe/models/leiauteNFe.py new file mode 100644 index 000000000000..5370d15acf8f --- /dev/null +++ b/l10n_br_account_nfe/models/leiauteNFe.py @@ -0,0 +1,18 @@ +from odoo import fields, models + +# TODO Temporary fixes +# Check if it is possible to make the lib that generates the odoo mixins (nfelib) +# apply these changes. + + +class DetPag(models.AbstractModel): + _inherit = "nfe.40.detpag" + + nfe40_indPag = fields.Selection( + selection=[ + ("0", "Pagamento à Vista"), + ("1", "Pagamento à Prazo"), + ], + string="Forma de Pagamento", + help="Indicador da Forma de Pagamento", + ) diff --git a/l10n_br_account_nfe/readme/CONFIGURE.rst b/l10n_br_account_nfe/readme/CONFIGURE.rst new file mode 100644 index 000000000000..d140c35f7bf8 --- /dev/null +++ b/l10n_br_account_nfe/readme/CONFIGURE.rst @@ -0,0 +1,7 @@ +**Português** +Crie o Modo de Pagamento e informe o campo Meio de Pagamento da NF: +Faturamento > Configuração > Administração > Modos de Pagamento + +**English** +Create the Payment Mode and inform the field Meio de Pagamento da NF: +Invoicing > Configuration > Management > Payment Modes diff --git a/l10n_br_account_nfe/readme/CONTRIBUTORS.rst b/l10n_br_account_nfe/readme/CONTRIBUTORS.rst new file mode 100644 index 000000000000..3a32b755f80b --- /dev/null +++ b/l10n_br_account_nfe/readme/CONTRIBUTORS.rst @@ -0,0 +1,8 @@ +* `Engenere `_: + + * Felipe Motter Pereira + * Antônio S. Pereira Neto + +* `Akretion `_: + + * Magno Barcelo da Costa diff --git a/l10n_br_account_nfe/readme/DESCRIPTION.rst b/l10n_br_account_nfe/readme/DESCRIPTION.rst new file mode 100644 index 000000000000..781fa7df9afc --- /dev/null +++ b/l10n_br_account_nfe/readme/DESCRIPTION.rst @@ -0,0 +1,9 @@ +**Português** +Este módulo integra os módulos l10n_br_account e l10n_br_nfe. + +* Adicionando as informações de Pagamento e Duplicatas da Fatura, TAGs cobr, pag e dup da NF-e/NFC-e. + +**English** +This module integrates the l10n_br_account and l10n_br_nfe modules. + +* Adding Payment Information and Invoice Duplicates, TAGs cobr, pag and dup of NF-e/NFC-e. diff --git a/l10n_br_account_nfe/readme/HISTORY.rst b/l10n_br_account_nfe/readme/HISTORY.rst new file mode 100644 index 000000000000..f1a7831a23e2 --- /dev/null +++ b/l10n_br_account_nfe/readme/HISTORY.rst @@ -0,0 +1,4 @@ +12.0.1.0.0 (2022-03-30) +~~~~~~~~~~~~~~~~~~~~~~~ + +* [NEW] Primeira versão diff --git a/l10n_br_account_nfe/readme/ROADMAP.rst b/l10n_br_account_nfe/readme/ROADMAP.rst new file mode 100644 index 000000000000..510817e58d2d --- /dev/null +++ b/l10n_br_account_nfe/readme/ROADMAP.rst @@ -0,0 +1 @@ +* Existe a possibilidade de criar uma Nota Fiscal com múltiplos Modos/Meio de Pagamentos RFC https://github.com/OCA/l10n-brazil/issues/1850 diff --git a/l10n_br_account_nfe/readme/USAGE.rst b/l10n_br_account_nfe/readme/USAGE.rst new file mode 100644 index 000000000000..50d55786028c --- /dev/null +++ b/l10n_br_account_nfe/readme/USAGE.rst @@ -0,0 +1,5 @@ +**Português** +Ao Confirmar um Documento Fiscal do tipo NFe ou NFCe, os dados das Tags de Pagamento e Duplicatas serão criados automaticamente. + +**English** +When Confirming a NFe or NFCe Fiscal Document, the Payment Tags and Duplicates data will be created automatically. diff --git a/l10n_br_account_nfe/report/__init__.py b/l10n_br_account_nfe/report/__init__.py new file mode 100644 index 000000000000..a248cf2162f5 --- /dev/null +++ b/l10n_br_account_nfe/report/__init__.py @@ -0,0 +1 @@ +from . import ir_actions_report diff --git a/l10n_br_account_nfe/report/danfe_report.xml b/l10n_br_account_nfe/report/danfe_report.xml new file mode 100644 index 000000000000..7a57dc4b1d15 --- /dev/null +++ b/l10n_br_account_nfe/report/danfe_report.xml @@ -0,0 +1,12 @@ + + + DANFE + account.move + qweb-pdf + main_template_danfe_account + main_template_danfe_account + '%s' % (object.document_key) + + report + + diff --git a/l10n_br_account_nfe/report/ir_actions_report.py b/l10n_br_account_nfe/report/ir_actions_report.py new file mode 100644 index 000000000000..b5b3e28beb96 --- /dev/null +++ b/l10n_br_account_nfe/report/ir_actions_report.py @@ -0,0 +1,27 @@ +# Copyright 2024 Engenere.one +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import models + + +class IrActionsReport(models.Model): + _inherit = "ir.actions.report" + + def temp_xml_autorizacao(self, xml_string): + return super().temp_xml_autorizacao(xml_string=xml_string) + + def _render_qweb_html(self, res_ids, data=None): + if self.report_name == "main_template_danfe_account": + return + return super()._render_qweb_html(res_ids, data=data) + + def _render_qweb_pdf(self, res_ids, data=None): + if self.report_name not in ["main_template_danfe_account"]: + return super()._render_qweb_pdf(res_ids, data=data) + + nfe = self.env["account.move"].search([("id", "in", res_ids)]) + + return self._render_danfe(nfe) + + def _render_danfe(self, nfe): + return super()._render_danfe(nfe=nfe) diff --git a/l10n_br_account_nfe/static/description/icon.png b/l10n_br_account_nfe/static/description/icon.png new file mode 100644 index 000000000000..3a0328b516c4 Binary files /dev/null and b/l10n_br_account_nfe/static/description/icon.png differ diff --git a/l10n_br_account_nfe/static/description/index.html b/l10n_br_account_nfe/static/description/index.html new file mode 100644 index 000000000000..505045e6d53c --- /dev/null +++ b/l10n_br_account_nfe/static/description/index.html @@ -0,0 +1,481 @@ + + + + + +Account NFe/NFC-e Integration + + + +
+

Account NFe/NFC-e Integration

+ + +

Beta License: AGPL-3 OCA/l10n-brazil Translate me on Weblate Try me on Runboat

+

Português +Este módulo integra os módulos l10n_br_account e l10n_br_nfe.

+
    +
  • Adicionando as informações de Pagamento e Duplicatas da Fatura, TAGs cobr, pag e dup da NF-e/NFC-e.
  • +
+

English +This module integrates the l10n_br_account and l10n_br_nfe modules.

+
    +
  • Adding Payment Information and Invoice Duplicates, TAGs cobr, pag and dup of NF-e/NFC-e.
  • +
+

Table of contents

+ +
+

Configuration

+

Português +Crie o Modo de Pagamento e informe o campo Meio de Pagamento da NF: +Faturamento > Configuração > Administração > Modos de Pagamento

+

English +Create the Payment Mode and inform the field Meio de Pagamento da NF: +Invoicing > Configuration > Management > Payment Modes

+
+
+

Usage

+

Português +Ao Confirmar um Documento Fiscal do tipo NFe ou NFCe, os dados das Tags de Pagamento e Duplicatas serão criados automaticamente.

+

English +When Confirming a NFe or NFCe Fiscal Document, the Payment Tags and Duplicates data will be created automatically.

+
+
+

Known issues / Roadmap

+ +
+
+

Changelog

+
+

12.0.1.0.0 (2022-03-30)

+
    +
  • [NEW] Primeira versão
  • +
+
+
+
+

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 to smash it by providing a detailed and welcomed +feedback.

+

Do not contact contributors directly about support or help with technical issues.

+
+
+

Credits

+
+

Authors

+
    +
  • Engenere
  • +
  • Akretion
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

This module is maintained by the OCA.

+ +Odoo Community Association + +

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.

+

Current maintainers:

+

antoniospneto felipemotter mbcosta

+

This module is part of the OCA/l10n-brazil project on GitHub.

+

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

+
+
+
+ + diff --git a/l10n_br_account_nfe/tests/__init__.py b/l10n_br_account_nfe/tests/__init__.py new file mode 100644 index 000000000000..4190acd74c14 --- /dev/null +++ b/l10n_br_account_nfe/tests/__init__.py @@ -0,0 +1,4 @@ +from . import test_nfe_generate_tags_cobr_dup_pag +from . import test_nfce_contingency +from . import test_nfe_with_ipi +from . import test_nfe_danfe_account diff --git a/l10n_br_account_nfe/tests/test_nfce_contingency.py b/l10n_br_account_nfe/tests/test_nfce_contingency.py new file mode 100644 index 000000000000..9e25eae44239 --- /dev/null +++ b/l10n_br_account_nfe/tests/test_nfce_contingency.py @@ -0,0 +1,76 @@ +# Copyright 2023 KMEE (Felipe Zago Rodrigues ) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +from odoo.tests import TransactionCase + +from odoo.addons.spec_driven_model import hooks + + +class TestAccountNFCeContingency(TransactionCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + # this hook is required to test l10n_br_account_nfe alone: + hooks.register_hook( + cls.env, + "l10n_br_nfe", + "odoo.addons.l10n_br_nfe_spec.models.v4_0.leiaute_nfe_v4_00", + ) + cls.document_id = cls.env.ref("l10n_br_nfe.demo_nfce_same_state") + cls.prepare_account_move_nfce() + + @classmethod + def prepare_account_move_nfce(cls): + receivable_account_id = cls.env["account.account"].create( + { + "name": "TEST ACCOUNT", + "code": "01.1.1.2.2", + "reconcile": 1, + "company_id": cls.env.ref("base.main_company").id, + "user_type_id": cls.env.ref("account.data_account_type_receivable").id, + } + ) + payable_account_id = cls.env["account.account"].create( + { + "name": "TEST ACCOUNT 2", + "code": "01.1.1.2.3", + "reconcile": 1, + "company_id": cls.env.ref("base.main_company").id, + "user_type_id": cls.env.ref("account.data_account_type_payable").id, + } + ) + payment_method = cls.env.ref("account.account_payment_method_manual_in").id + journal_id = cls.env["account.journal"].create( + { + "name": "JOURNAL TEST", + "code": "TEST", + "type": "bank", + "company_id": cls.env.ref("base.main_company").id, + } + ) + payment_mode = cls.env["account.payment.mode"].create( + { + "name": "PAYMENT MODE TEST", + "company_id": cls.env.ref("base.main_company").id, + "payment_method_id": payment_method, + "fiscal_payment_mode": "15", + "bank_account_link": "fixed", + "fixed_journal_id": journal_id.id, + } + ) + cls.document_move_id = cls.env["account.move"].create( + { + "name": "MOVE TEST", + "payment_mode_id": payment_mode.id, + "company_id": cls.env.ref("base.main_company").id, + "line_ids": [ + (0, 0, {"account_id": receivable_account_id.id, "credit": 10}), + (0, 0, {"account_id": payable_account_id.id, "debit": 10}), + ], + } + ) + cls.document_move_id.fiscal_document_id = cls.document_id.id + + def test_nfce_contingencia(self): + self.document_id._update_nfce_for_offline_contingency() + self.assertIn(self.document_move_id, self.document_id.move_ids) diff --git a/l10n_br_account_nfe/tests/test_nfe_danfe_account.py b/l10n_br_account_nfe/tests/test_nfe_danfe_account.py new file mode 100644 index 000000000000..dee3686c47de --- /dev/null +++ b/l10n_br_account_nfe/tests/test_nfe_danfe_account.py @@ -0,0 +1,37 @@ +# Copyright 2024 Engenere.one +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +from unittest.mock import patch + +from odoo.tests import TransactionCase, tagged + + +@tagged("post_install", "-at_install") +class TestDanfe(TransactionCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + + def test_generate_danfe_brazil_fiscal_report(self): + nfe = self.env.ref("l10n_br_account_nfe.demo_nfe_dados_de_cobranca") + nfe.action_post() + + danfe_report = self.env["ir.actions.report"].search( + [("report_name", "=", "main_template_danfe_account")] + ) + danfe_pdf = danfe_report._render_qweb_pdf([nfe.id]) + self.assertTrue(danfe_pdf) + + def test_generate_danfe_erpbrasil_edoc(self): + nfe = self.env.ref("l10n_br_account_nfe.demo_nfe_dados_de_cobranca") + nfe.company_id.danfe_library = "erpbrasil.edoc.pdf" + + with patch("erpbrasil.edoc.pdf.base.ImprimirXml.imprimir") as mock_make_pdf: + mock_make_pdf.return_value = b"Mock PDF" + + nfe.action_post() + + danfe_report = self.env["ir.actions.report"].search( + [("report_name", "=", "main_template_danfe_account")] + ) + danfe_pdf = danfe_report._render_qweb_pdf([nfe.id]) + self.assertTrue(danfe_pdf) diff --git a/l10n_br_account_nfe/tests/test_nfe_generate_tags_cobr_dup_pag.py b/l10n_br_account_nfe/tests/test_nfe_generate_tags_cobr_dup_pag.py new file mode 100644 index 000000000000..30fc8731822c --- /dev/null +++ b/l10n_br_account_nfe/tests/test_nfe_generate_tags_cobr_dup_pag.py @@ -0,0 +1,229 @@ +# Copyright (C) 2022-Today - Engenere (). +# @author Antônio S. Pereira Neto +# @author Felipe Motter Pereira +# Copyright (C) 2022-Today - Akretion (). +# @author Magno Costa +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo.exceptions import UserError +from odoo.tests import Form, TransactionCase, tagged + + +@tagged("post_install", "-at_install") +class TestGeneratePaymentInfo(TransactionCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + + cls.company = cls.env.ref("l10n_br_base.empresa_lucro_presumido") + + # set default user company + companies = cls.env["res.company"].search([]) + cls.env.user.company_ids = [(6, 0, companies.ids)] + cls.env.user.company_id = cls.company + + cls.payment_mode = cls.env["account.payment.mode"].create( + { + "name": "Money", + "company_id": cls.company.id, + "payment_method_id": cls.env.ref( + "account.account_payment_method_manual_in" + ).id, + "fiscal_payment_mode": "18", + "bank_account_link": "variable", + } + ) + + cls.invoice_account_id = cls.env["account.account"].create( + { + "company_id": cls.company.id, + "user_type_id": cls.env.ref("account.data_account_type_receivable").id, + "code": "RECTEST", + "name": "Test receivable account", + "reconcile": True, + } + ) + + cls.invoice_journal = cls.env["account.journal"].create( + { + "company_id": cls.company.id, + "name": "Invoice Journal - (test)", + "code": "INVTEST", + "type": "sale", + } + ) + + cls.payment_term = cls.env["account.payment.term"].create( + { + "name": "30 Days", + "line_ids": [ + ( + 0, + 0, + { + "value": "balance", + "days": 30, + "option": "day_after_invoice_date", + }, + ) + ], + } + ) + + cls.invoice_line_account_id = cls.env["account.account"].create( + { + "company_id": cls.company.id, + "user_type_id": cls.env.ref("account.data_account_type_revenue").id, + "code": "705070", + "name": "Product revenue account (test)", + } + ) + + cls.fiscal_operation_id = cls.env.ref("l10n_br_fiscal.fo_venda") + cls.fiscal_operation_id.deductible_taxes = True + + move_form = Form( + cls.env["account.move"] + .with_company(cls.company) + .with_context(default_move_type="out_invoice") + ) + move_form.partner_id = cls.env.ref("l10n_br_base.res_partner_cliente1_sp") + move_form.document_type_id = cls.env.ref("l10n_br_fiscal.document_55") + move_form.fiscal_operation_id = cls.fiscal_operation_id + invoice_vals = move_form._values_to_save(all_fields=True) + invoice_vals.update( + { + "company_id": cls.company.id, + "currency_id": cls.company.currency_id.id, + "payment_mode_id": cls.payment_mode.id, + "document_serie_id": cls.env.ref( + "l10n_br_fiscal.empresa_lc_document_55_serie_1" + ).id, + "journal_id": cls.invoice_journal.id, + "invoice_payment_term_id": cls.payment_term.id, + "invoice_origin": "Teste l10n_br_account_nfe", + "invoice_user_id": cls.env.user.id, + } + ) + + line_form = move_form.invoice_line_ids.new() + line_form.product_id = cls.env.ref("product.product_product_7") + line_form.fiscal_operation_id = cls.fiscal_operation_id + invoice_line_vals = line_form._values_to_save(all_fields=True) + invoice_line_vals.update( + { + "account_id": cls.invoice_line_account_id.id, + "quantity": 1, + "product_uom_id": cls.env.ref("uom.product_uom_unit").id, + "price_unit": 450.0, + "name": "Product - Invoice Line Test", + "fiscal_operation_line_id": cls.env.ref( + "l10n_br_fiscal.fo_venda_revenda" + ).id, + "company_id": cls.company.id, + "partner_id": cls.env.ref("l10n_br_base.res_partner_cliente1_sp").id, + } + ) + + invoice_vals["invoice_line_ids"].append((0, 0, invoice_line_vals)) + del invoice_vals["line_ids"] + cls.invoice = cls.env["account.move"].create(invoice_vals) + cls.invoice.invoice_line_ids._onchange_fiscal_tax_ids() + cls.invoice.invoice_line_ids._onchange_fiscal_operation_line_id() + cls.invoice.action_post() + + # Dado de Demonstração + cls.invoice_demo_data = cls.env.ref( + "l10n_br_account_nfe.demo_nfe_dados_de_cobranca" + ) + cls.env.user.company_id = cls.invoice_demo_data.company_id + for line in cls.invoice_demo_data.invoice_line_ids: + line.with_context( + check_move_validity=False + )._onchange_fiscal_operation_line_id() + line.with_context(check_move_validity=False)._onchange_fiscal_tax_ids() + + def test_nfe_generate_tag_pag(self): + """Test NFe generate TAG PAG.""" + # Dados criados no teste + for detPag in self.invoice.nfe40_detPag: + self.assertEqual(detPag.nfe40_indPag, "1", "Error in nfe40_indPag field.") + self.assertEqual(detPag.nfe40_tPag, "18", "Error in nfe40_tPag field.") + self.assertEqual(detPag.nfe40_vPag, 450.0, "Error in nfe40_vPag field.") + + # Dados criados no dados de demonstração + for detPag in self.invoice_demo_data.nfe40_detPag: + self.assertEqual(detPag.nfe40_indPag, "1", "Error in nfe40_indPag field.") + self.assertEqual(detPag.nfe40_tPag, "15", "Error in nfe40_tPag field.") + self.assertEqual(detPag.nfe40_vPag, 1000.0, "Error in nfe40_vPag field.") + + def test_nfe_generate_tag_cobr_and_dup(self): + """Test NFe generate TAG COBR e DUP.""" + # Dados criados no teste + self.assertEqual(self.invoice.nfe40_vOrig, 450.0) + self.assertEqual(self.invoice.nfe40_vDesc, 0.0) + self.assertEqual(self.invoice.nfe40_vLiq, 450.0) + self.assertEqual(self.invoice.nfe40_dup[0].nfe40_nDup, "001") + venc = self.invoice.financial_move_line_ids[0].date_maturity + self.assertEqual(self.invoice.nfe40_dup[0].nfe40_dVenc, venc) + self.assertEqual(self.invoice.nfe40_dup[0].nfe40_vDup, 450.0) + + # Dados criados no dados de demonstração + self.assertEqual(self.invoice_demo_data.nfe40_vOrig, 1000) + self.assertEqual(self.invoice_demo_data.nfe40_vDesc, 0.0) + self.assertEqual(self.invoice_demo_data.nfe40_vLiq, 1000) + self.assertEqual(self.invoice_demo_data.nfe40_dup[0].nfe40_nDup, "001") + venc = self.invoice_demo_data.financial_move_line_ids[0].date_maturity + self.assertEqual(self.invoice_demo_data.nfe40_dup[0].nfe40_dVenc, venc) + self.assertEqual(self.invoice_demo_data.nfe40_dup[0].nfe40_vDup, 330.0) + + def test_payment_mode_without_fiscal_mode(self): + """Test when Payment Mode don't has Fiscal Mode.""" + self.pay_mode = self.env["account.payment.mode"].create( + { + "name": "Sem Meio Fiscal", + "company_id": self.env.ref("l10n_br_base.empresa_simples_nacional").id, + "payment_method_id": self.env.ref( + "account.account_payment_method_manual_in" + ).id, + # "fiscal_payment_mode": "18", + "bank_account_link": "variable", + } + ) + self.invoice_demo_data.payment_mode_id = self.pay_mode.id + with self.assertRaises(UserError) as captured_exception: + self.invoice_demo_data.action_post() + self.assertEqual( + captured_exception.exception.args[0], + ( + "Payment Mode Sem Meio Fiscal should have a " + "Fiscal Payment Mode filled to be used in the Fiscal Document!" + ), + ) + + def test_invoice_without_payment_mode(self): + """Test Invoice without Payment Mode.""" + invoice = self.env.ref("l10n_br_account_nfe.demo_nfe_sem_dados_de_cobranca") + invoice.action_post() + self.assertFalse( + invoice.nfe40_dup, + "Error field nfe40_dup should not filled when Fiscal Operation are Bonificação.", + ) + for detPag in invoice.nfe40_detPag: + self.assertEqual( + detPag.nfe40_tPag, + "90", + "Error in nfe40_tPag field, should be 90 - Sem Pagamento.", + ) + + def test_valid_nfe_xml(self): + """ + Test that NFe XML is valid. This in fact tests that NFe computed fields are + properly computed. + In fact this tests this bug with dummy documents(lines) compute triggers + https://github.com/OCA/l10n-brazil/issues/2451 + is fixed. + """ + invoice = self.invoice + invoice.fiscal_document_id._document_export() + self.assertEqual(invoice.fiscal_document_id.xml_error_message, False) diff --git a/l10n_br_account_nfe/tests/test_nfe_with_ipi.py b/l10n_br_account_nfe/tests/test_nfe_with_ipi.py new file mode 100644 index 000000000000..a792623680fc --- /dev/null +++ b/l10n_br_account_nfe/tests/test_nfe_with_ipi.py @@ -0,0 +1,52 @@ +from odoo.tests import tagged + +from odoo.addons.l10n_br_account.tests.common import AccountMoveBRCommon + + +@tagged("post_install", "-at_install") +class TestNFeWithIPI(AccountMoveBRCommon): + @classmethod + def setUpClass(cls, chart_template_ref=None): + super().setUpClass(chart_template_ref) + + cls.configure_normal_company_taxes() + cls.env.user.groups_id |= cls.env.ref("l10n_br_nfe.group_manager") + + cls.payment_mode = cls.env["account.payment.mode"].create( + { + "name": "Cash", + "company_id": cls.company_data["company"].id, + "payment_method_id": cls.env.ref( + "account.account_payment_method_manual_in" + ).id, + "fiscal_payment_mode": "18", + "bank_account_link": "variable", + } + ) + + # Create the NFe with a product that has a default 5% IPI incidence. + cls.move_out_venda = cls.init_invoice( + move_type="out_invoice", + products=[cls.product_b], + document_type=cls.env.ref("l10n_br_fiscal.document_55"), + document_serie_id=cls.empresa_lc_document_55_serie_1, + fiscal_operation=cls.env.ref("l10n_br_fiscal.fo_venda"), + fiscal_operation_lines=[cls.env.ref("l10n_br_fiscal.fo_venda_venda")], + post=False, + ) + cls.move_out_venda.payment_mode_id = cls.payment_mode + cls.move_out_venda.action_post() + + def test_nfe_with_ipi(self): + """ + Test IPI calculation in NFe. + """ + # Check the IPI percentage and value on the product line + product_line = self.move_out_venda.invoice_line_ids[0] + self.assertEqual(product_line.ipi_percent, 5.00) + self.assertEqual(product_line.ipi_value, 50.00) + + # Check the total values in the NFe + self.assertEqual(self.move_out_venda.nfe40_vIPI, 50.0) + self.assertEqual(self.move_out_venda.nfe40_vProd, 1000.00) + self.assertEqual(self.move_out_venda.nfe40_vNF, 1050.00) diff --git a/l10n_br_account_nfe/views/account_payment_mode.xml b/l10n_br_account_nfe/views/account_payment_mode.xml new file mode 100644 index 000000000000..09ac49d873d5 --- /dev/null +++ b/l10n_br_account_nfe/views/account_payment_mode.xml @@ -0,0 +1,16 @@ + + + + + l10n_br_account.nfe.account.payment.mode.form + account.payment.mode + 97 + + + + + + + + + diff --git a/setup/l10n_br_account_nfe/odoo/addons/l10n_br_account_nfe b/setup/l10n_br_account_nfe/odoo/addons/l10n_br_account_nfe new file mode 120000 index 000000000000..2b6759847200 --- /dev/null +++ b/setup/l10n_br_account_nfe/odoo/addons/l10n_br_account_nfe @@ -0,0 +1 @@ +../../../../l10n_br_account_nfe \ No newline at end of file diff --git a/setup/l10n_br_account_nfe/setup.py b/setup/l10n_br_account_nfe/setup.py new file mode 100644 index 000000000000..28c57bb64031 --- /dev/null +++ b/setup/l10n_br_account_nfe/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +)