diff --git a/account_document_reversal/README.rst b/account_document_reversal/README.rst deleted file mode 100644 index 46277aad1..000000000 --- a/account_document_reversal/README.rst +++ /dev/null @@ -1,108 +0,0 @@ -========================= -Account Document Reversal -========================= - -.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! This file is generated by oca-gen-addon-readme !! - !! changes will be overwritten. !! - !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - -.. |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%2Faccount--financial--tools-lightgray.png?logo=github - :target: https://github.com/OCA/account-financial-tools/tree/12.0/account_document_reversal - :alt: OCA/account-financial-tools -.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png - :target: https://translation.odoo-community.org/projects/account-financial-tools-12-0/account-financial-tools-12-0-account_document_reversal - :alt: Translate me on Weblate -.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png - :target: https://runbot.odoo-community.org/runbot/92/12.0 - :alt: Try me on Runbot - -|badge1| |badge2| |badge3| |badge4| |badge5| - -By Odoo standard, when an account document is cancelled, its journal entry will be deleted completely. -This module enhance the process, instead of deletion, it will create new reversed journal entry. -This will help preserved the accounting history, which is strictly required by some country. - -Following are documented provide this feature, - -- Invoice (account.invoice) -- Payment (acccont.payment) -- Bank Statement (account.bank.statement.line) - -**Table of contents** - -.. contents:: - :local: - -Configuration -============= - -To use document reversal, setup the document's journal as following, - -- Allow Cancelling = True -- Cancel method = Reversal (create reversed journal entries) - -Usage -===== - -After configure document journal to allow cancel with reversal, it is ready to use. - -- Cancel document as normally do, system will show new cancel wizard -- User can select cancel date and new journal (if different from the document) - which will be used for the reversed journal entry - -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 `_. - -Do not contact contributors directly about support or help with technical issues. - -Credits -======= - -Authors -~~~~~~~ - -* Ecosoft -* Eficent - -Contributors -~~~~~~~~~~~~ - -* Kitti Upariphutthiphong -* Jordi Ballester - -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-kittiu| image:: https://github.com/kittiu.png?size=40px - :target: https://github.com/kittiu - :alt: kittiu - -Current `maintainer `__: - -|maintainer-kittiu| - -This module is part of the `OCA/account-financial-tools `_ project on GitHub. - -You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/account_document_reversal/__manifest__.py b/account_document_reversal/__manifest__.py index df73249ac..8be09b44f 100644 --- a/account_document_reversal/__manifest__.py +++ b/account_document_reversal/__manifest__.py @@ -4,15 +4,19 @@ { "name": "Account Document Reversal", "summary": "Create reversed journal entries when cancel document", - "version": "12.0.1.0.1", - "author": "Ecosoft," "Eficent," "Odoo Community Association (OCA)", + "version": "13.0.1.0.0", + "author": "Ecosoft,ForgeFlow,Odoo Community Association (OCA)", "website": "https://github.com/OCA/account-financial-tools", "category": "Accounting & Finance", - "depends": ["account_cancel"], - "data": ["wizard/reverse_account_document_wizard.xml", "views/account_view.xml",], + "depends": ["account", "sale", "purchase"], + "data": [ + "wizard/reverse_account_document_wizard.xml", + "views/account_view.xml", + "views/account_move_view.xml", + "views/account_payment_view.xml", + ], "license": "AGPL-3", "installable": True, "application": False, - "development_status": "Beta", "maintainers": ["kittiu"], } diff --git a/account_document_reversal/i18n/account_document_reversal.pot b/account_document_reversal/i18n/account_document_reversal.pot index cb95dec17..db69ac904 100644 --- a/account_document_reversal/i18n/account_document_reversal.pot +++ b/account_document_reversal/i18n/account_document_reversal.pot @@ -29,7 +29,6 @@ msgid "Bank Statement Line" msgstr "" #. module: account_document_reversal -#: model:ir.model.fields,field_description:account_document_reversal.field_account_bank_statement_import_journal_creation__cancel_method #: model:ir.model.fields,field_description:account_document_reversal.field_account_journal__cancel_method msgid "Cancel Method" msgstr "" @@ -55,7 +54,6 @@ msgid "Created on" msgstr "" #. module: account_document_reversal -#: model:ir.model.fields,field_description:account_document_reversal.field_account_bank_statement_import_journal_creation__reversal_journal_id #: model:ir.model.fields,field_description:account_document_reversal.field_account_journal__reversal_journal_id msgid "Default Reversal Journal" msgstr "" @@ -84,7 +82,6 @@ msgid "ID" msgstr "" #. module: account_document_reversal -#: model:ir.model.fields,help:account_document_reversal.field_account_bank_statement_import_journal_creation__use_different_journal #: model:ir.model.fields,help:account_document_reversal.field_account_journal__use_different_journal msgid "If checked, reversal wizard will show field Reversal Journal" msgstr "" @@ -110,7 +107,6 @@ msgid "Journal Entries" msgstr "" #. module: account_document_reversal -#: model:ir.model.fields,help:account_document_reversal.field_account_bank_statement_import_journal_creation__reversal_journal_id #: model:ir.model.fields,help:account_document_reversal.field_account_journal__reversal_journal_id msgid "Journal in this field will show in reversal wizard as default" msgstr "" @@ -177,21 +173,18 @@ msgid "This action is not allowed for cancel with reversal.\n" msgstr "" #. module: account_document_reversal -#: model:ir.model.fields,help:account_document_reversal.field_account_bank_statement_import_journal_creation__is_cancel_reversal #: model:ir.model.fields,help:account_document_reversal.field_account_journal__is_cancel_reversal #: model:ir.model.fields,help:account_document_reversal.field_account_move__is_cancel_reversal msgid "True, when journal allow cancel entries with method is reversal" msgstr "" #. module: account_document_reversal -#: model:ir.model.fields,field_description:account_document_reversal.field_account_bank_statement_import_journal_creation__is_cancel_reversal #: model:ir.model.fields,field_description:account_document_reversal.field_account_journal__is_cancel_reversal #: model:ir.model.fields,field_description:account_document_reversal.field_account_move__is_cancel_reversal msgid "Use Cancel Reversal" msgstr "" #. module: account_document_reversal -#: model:ir.model.fields,field_description:account_document_reversal.field_account_bank_statement_import_journal_creation__use_different_journal #: model:ir.model.fields,field_description:account_document_reversal.field_account_journal__use_different_journal #: model:ir.model.fields,field_description:account_document_reversal.field_reverse_account_document__use_different_journal msgid "Use different journal for reversal" diff --git a/account_document_reversal/i18n/da.po b/account_document_reversal/i18n/da.po deleted file mode 100644 index ae4e01fad..000000000 --- a/account_document_reversal/i18n/da.po +++ /dev/null @@ -1,216 +0,0 @@ -# Translation of Odoo Server. -# This file contains the translation of the following modules: -# * account_document_reversal -# -msgid "" -msgstr "" -"Project-Id-Version: Odoo Server 12.0\n" -"Report-Msgid-Bugs-To: \n" -"PO-Revision-Date: 2021-07-05 08:39+0000\n" -"Last-Translator: Hans Henrik Gabelgaard \n" -"Language-Team: none\n" -"Language: da\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 4.3.2\n" - -#. module: account_document_reversal -#: model:ir.model,name:account_document_reversal.model_account_document_reversal -msgid "Abstract Module for Document Reversal" -msgstr "" - -#. module: account_document_reversal -#: model:ir.model,name:account_document_reversal.model_reverse_account_document -msgid "Account Document Reversal" -msgstr "Tilbageførsel af regnskabsdokument" - -#. module: account_document_reversal -#: model:ir.model,name:account_document_reversal.model_account_bank_statement_line -msgid "Bank Statement Line" -msgstr "Bank kontoudtogslinie" - -#. module: account_document_reversal -#: model:ir.model.fields,field_description:account_document_reversal.field_account_bank_statement_import_journal_creation__cancel_method -#: model:ir.model.fields,field_description:account_document_reversal.field_account_journal__cancel_method -msgid "Cancel Method" -msgstr "Annulerings metode" - -#. module: account_document_reversal -#: model:ir.model.fields,help:account_document_reversal.field_reverse_account_document__use_different_journal -msgid "Checked, if the journal of underlineing document is checked." -msgstr "" - -#. module: account_document_reversal -#: model_terms:ir.ui.view,arch_db:account_document_reversal.view_reverse_account_document -msgid "Confirm" -msgstr "Bekræft" - -#. module: account_document_reversal -#: model:ir.model.fields,field_description:account_document_reversal.field_reverse_account_document__create_uid -msgid "Created by" -msgstr "Oprettet af" - -#. module: account_document_reversal -#: model:ir.model.fields,field_description:account_document_reversal.field_reverse_account_document__create_date -msgid "Created on" -msgstr "Oprettet den" - -#. module: account_document_reversal -#: model:ir.model.fields,field_description:account_document_reversal.field_account_bank_statement_import_journal_creation__reversal_journal_id -#: model:ir.model.fields,field_description:account_document_reversal.field_account_journal__reversal_journal_id -msgid "Default Reversal Journal" -msgstr "Standard tilbageførsels journal" - -#. module: account_document_reversal -#: model_terms:ir.ui.view,arch_db:account_document_reversal.view_reverse_account_document -msgid "Discard" -msgstr "Kassér" - -#. module: account_document_reversal -#: model:ir.model.fields,field_description:account_document_reversal.field_account_document_reversal__display_name -#: model:ir.model.fields,field_description:account_document_reversal.field_reverse_account_document__display_name -msgid "Display Name" -msgstr "Vist navn" - -#. module: account_document_reversal -#: model:ir.actions.act_window,name:account_document_reversal.action_view_reverse_account_document -#: model_terms:ir.ui.view,arch_db:account_document_reversal.view_reverse_account_document -msgid "Document Cancel" -msgstr "Annuller dokument" - -#. module: account_document_reversal -#: model:ir.model.fields,field_description:account_document_reversal.field_account_document_reversal__id -#: model:ir.model.fields,field_description:account_document_reversal.field_reverse_account_document__id -msgid "ID" -msgstr "" - -#. module: account_document_reversal -#: model:ir.model.fields,help:account_document_reversal.field_account_bank_statement_import_journal_creation__use_different_journal -#: model:ir.model.fields,help:account_document_reversal.field_account_journal__use_different_journal -msgid "If checked, reversal wizard will show field Reversal Journal" -msgstr "" -"Hvis dette er markeret, viser tilbageførselsguiden feltet " -"Tilbageførselsjournal" - -#. module: account_document_reversal -#: model:ir.model.fields,help:account_document_reversal.field_reverse_account_document__journal_id -msgid "If empty, uses the journal of the journal entry to be reversed." -msgstr "" -"Hvis det er tomt, skal du anvende journal for journalpost for tilbageførslen." - -#. module: account_document_reversal -#: model:ir.model,name:account_document_reversal.model_account_invoice -msgid "Invoice" -msgstr "Faktura" - -#. module: account_document_reversal -#: model:ir.model,name:account_document_reversal.model_account_journal -msgid "Journal" -msgstr "Journal" - -#. module: account_document_reversal -#: model:ir.model,name:account_document_reversal.model_account_move -msgid "Journal Entries" -msgstr "Posteringer" - -#. module: account_document_reversal -#: model:ir.model.fields,help:account_document_reversal.field_account_bank_statement_import_journal_creation__reversal_journal_id -#: model:ir.model.fields,help:account_document_reversal.field_account_journal__reversal_journal_id -msgid "Journal in this field will show in reversal wizard as default" -msgstr "Journal i dette felt vises som standard i guiden til tilbageførsel" - -#. module: account_document_reversal -#: model:ir.model.fields,field_description:account_document_reversal.field_account_document_reversal____last_update -#: model:ir.model.fields,field_description:account_document_reversal.field_reverse_account_document____last_update -msgid "Last Modified on" -msgstr "Senest ændret den" - -#. module: account_document_reversal -#: model:ir.model.fields,field_description:account_document_reversal.field_reverse_account_document__write_uid -msgid "Last Updated by" -msgstr "Senest ændret af" - -#. module: account_document_reversal -#: model:ir.model.fields,field_description:account_document_reversal.field_reverse_account_document__write_date -msgid "Last Updated on" -msgstr "Senest ændret den" - -#. module: account_document_reversal -#: selection:account.journal,cancel_method:0 -msgid "Normal (delete journal entries if exists)" -msgstr "Normal (slet journalposter, hvis de findes)" - -#. module: account_document_reversal -#: code:addons/account_document_reversal/models/account_invoice.py:24 -#, python-format -msgid "Only fully unpaid invoice can be cancelled.\n" -"To cancel this invoice, make sure all payment(s) are also cancelled." -msgstr "" -"Kun fuldt ubetalte faktura kan annulleres.\n" -"For at annullere denne faktura skal du sørge for, at alle betalinger også " -"annulleres." - -#. module: account_document_reversal -#: code:addons/account_document_reversal/models/account_bank_statement.py:20 -#, python-format -msgid "Only new bank statement can be cancelled" -msgstr "Kun nye bank kontoudtog kan blive annulleret" - -#. module: account_document_reversal -#: model:ir.model,name:account_document_reversal.model_account_payment -msgid "Payments" -msgstr "Betalinger" - -#. module: account_document_reversal -#: selection:account.journal,cancel_method:0 -msgid "Reversal (create reversed journal entries)" -msgstr "Tilbageførsel (opret omvendte journalposter)" - -#. module: account_document_reversal -#: model:ir.model.fields,field_description:account_document_reversal.field_reverse_account_document__journal_id -msgid "Reversal Journal" -msgstr "Tilbageførselsjournal" - -#. module: account_document_reversal -#: model:ir.model.fields,field_description:account_document_reversal.field_reverse_account_document__date -msgid "Reversal date" -msgstr "Tilbageførselsdato" - -#. module: account_document_reversal -#: code:addons/account_document_reversal/models/account_move.py:22 -#, python-format -msgid "This action is not allowed for cancel with reversal.\n" -"Please use Reverse Entry." -msgstr "" -"Denne handling er ikke tilladt for annullering med tilbageførsel.\n" -"Brug Tilbagefør postering." - -#. module: account_document_reversal -#: model:ir.model.fields,help:account_document_reversal.field_account_bank_statement_import_journal_creation__is_cancel_reversal -#: model:ir.model.fields,help:account_document_reversal.field_account_journal__is_cancel_reversal -#: model:ir.model.fields,help:account_document_reversal.field_account_move__is_cancel_reversal -msgid "True, when journal allow cancel entries with method is reversal" -msgstr "" - -#. module: account_document_reversal -#: model:ir.model.fields,field_description:account_document_reversal.field_account_bank_statement_import_journal_creation__is_cancel_reversal -#: model:ir.model.fields,field_description:account_document_reversal.field_account_journal__is_cancel_reversal -#: model:ir.model.fields,field_description:account_document_reversal.field_account_move__is_cancel_reversal -msgid "Use Cancel Reversal" -msgstr "Anvend Tilbageførsel" - -#. module: account_document_reversal -#: model:ir.model.fields,field_description:account_document_reversal.field_account_bank_statement_import_journal_creation__use_different_journal -#: model:ir.model.fields,field_description:account_document_reversal.field_account_journal__use_different_journal -#: model:ir.model.fields,field_description:account_document_reversal.field_reverse_account_document__use_different_journal -msgid "Use different journal for reversal" -msgstr "Anvend en anden journal for tilbageførsel" - -#. module: account_document_reversal -#: code:addons/account_document_reversal/models/account_invoice.py:36 -#: code:addons/account_document_reversal/models/account_payment.py:27 -#, python-format -msgid "You are trying to cancel the cancelled document" -msgstr "Du prøver at annullere det annullerede dokument" diff --git a/account_document_reversal/i18n/hr.po b/account_document_reversal/i18n/hr.po index 2d77cc185..fc72a4936 100644 --- a/account_document_reversal/i18n/hr.po +++ b/account_document_reversal/i18n/hr.po @@ -1,6 +1,6 @@ # Translation of Odoo Server. # This file contains the translation of the following modules: -# * account_document_reversal +# * account_document_reversal # msgid "" msgstr "" @@ -13,8 +13,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" -"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" -"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" +"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=" +"4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" "X-Generator: Weblate 3.10\n" #. module: account_document_reversal @@ -33,7 +33,6 @@ msgid "Bank Statement Line" msgstr "Stavka izvoda" #. module: account_document_reversal -#: model:ir.model.fields,field_description:account_document_reversal.field_account_bank_statement_import_journal_creation__cancel_method #: model:ir.model.fields,field_description:account_document_reversal.field_account_journal__cancel_method msgid "Cancel Method" msgstr "Metoda otkaza" @@ -59,7 +58,6 @@ msgid "Created on" msgstr "Kreirano" #. module: account_document_reversal -#: model:ir.model.fields,field_description:account_document_reversal.field_account_bank_statement_import_journal_creation__reversal_journal_id #: model:ir.model.fields,field_description:account_document_reversal.field_account_journal__reversal_journal_id msgid "Default Reversal Journal" msgstr "Zadani dnevnik otkazivanja" @@ -88,7 +86,6 @@ msgid "ID" msgstr "ID" #. module: account_document_reversal -#: model:ir.model.fields,help:account_document_reversal.field_account_bank_statement_import_journal_creation__use_different_journal #: model:ir.model.fields,help:account_document_reversal.field_account_journal__use_different_journal msgid "If checked, reversal wizard will show field Reversal Journal" msgstr "" @@ -114,7 +111,6 @@ msgid "Journal Entries" msgstr "Stavke dnevnika" #. module: account_document_reversal -#: model:ir.model.fields,help:account_document_reversal.field_account_bank_statement_import_journal_creation__reversal_journal_id #: model:ir.model.fields,help:account_document_reversal.field_account_journal__reversal_journal_id msgid "Journal in this field will show in reversal wizard as default" msgstr "" @@ -143,8 +139,7 @@ msgstr "" #. module: account_document_reversal #: code:addons/account_document_reversal/models/account_invoice.py:24 #, python-format -msgid "" -"Only fully unpaid invoice can be cancelled.\n" +msgid "Only fully unpaid invoice can be cancelled.\n" "To cancel this invoice, make sure all payment(s) are also cancelled." msgstr "" @@ -177,27 +172,23 @@ msgstr "" #. module: account_document_reversal #: code:addons/account_document_reversal/models/account_move.py:22 #, python-format -msgid "" -"This action is not allowed for cancel with reversal.\n" +msgid "This action is not allowed for cancel with reversal.\n" "Please use Reverse Entry." msgstr "" #. module: account_document_reversal -#: model:ir.model.fields,help:account_document_reversal.field_account_bank_statement_import_journal_creation__is_cancel_reversal #: model:ir.model.fields,help:account_document_reversal.field_account_journal__is_cancel_reversal #: model:ir.model.fields,help:account_document_reversal.field_account_move__is_cancel_reversal msgid "True, when journal allow cancel entries with method is reversal" msgstr "" #. module: account_document_reversal -#: model:ir.model.fields,field_description:account_document_reversal.field_account_bank_statement_import_journal_creation__is_cancel_reversal #: model:ir.model.fields,field_description:account_document_reversal.field_account_journal__is_cancel_reversal #: model:ir.model.fields,field_description:account_document_reversal.field_account_move__is_cancel_reversal msgid "Use Cancel Reversal" msgstr "" #. module: account_document_reversal -#: model:ir.model.fields,field_description:account_document_reversal.field_account_bank_statement_import_journal_creation__use_different_journal #: model:ir.model.fields,field_description:account_document_reversal.field_account_journal__use_different_journal #: model:ir.model.fields,field_description:account_document_reversal.field_reverse_account_document__use_different_journal msgid "Use different journal for reversal" diff --git a/account_document_reversal/i18n/pt.po b/account_document_reversal/i18n/pt.po index 0fd9b5449..d2a7bf9fb 100644 --- a/account_document_reversal/i18n/pt.po +++ b/account_document_reversal/i18n/pt.po @@ -1,6 +1,6 @@ # Translation of Odoo Server. # This file contains the translation of the following modules: -# * account_document_reversal +# * account_document_reversal # msgid "" msgstr "" @@ -32,7 +32,6 @@ msgid "Bank Statement Line" msgstr "Linha de Extrato Bancário" #. module: account_document_reversal -#: model:ir.model.fields,field_description:account_document_reversal.field_account_bank_statement_import_journal_creation__cancel_method #: model:ir.model.fields,field_description:account_document_reversal.field_account_journal__cancel_method msgid "Cancel Method" msgstr "Cancelar o Método" @@ -58,7 +57,6 @@ msgid "Created on" msgstr "Criado em" #. module: account_document_reversal -#: model:ir.model.fields,field_description:account_document_reversal.field_account_bank_statement_import_journal_creation__reversal_journal_id #: model:ir.model.fields,field_description:account_document_reversal.field_account_journal__reversal_journal_id msgid "Default Reversal Journal" msgstr "Diário de Reversão Pré-definido" @@ -87,7 +85,6 @@ msgid "ID" msgstr "ID" #. module: account_document_reversal -#: model:ir.model.fields,help:account_document_reversal.field_account_bank_statement_import_journal_creation__use_different_journal #: model:ir.model.fields,help:account_document_reversal.field_account_journal__use_different_journal msgid "If checked, reversal wizard will show field Reversal Journal" msgstr "" @@ -114,7 +111,6 @@ msgid "Journal Entries" msgstr "Movimentos de Diário" #. module: account_document_reversal -#: model:ir.model.fields,help:account_document_reversal.field_account_bank_statement_import_journal_creation__reversal_journal_id #: model:ir.model.fields,help:account_document_reversal.field_account_journal__reversal_journal_id msgid "Journal in this field will show in reversal wizard as default" msgstr "O diário neste campo mostrará o assistente de reversão por defeito" @@ -143,8 +139,7 @@ msgstr "Normal (apaga movimentos de diário de existirem)" #. module: account_document_reversal #: code:addons/account_document_reversal/models/account_invoice.py:24 #, python-format -msgid "" -"Only fully unpaid invoice can be cancelled.\n" +msgid "Only fully unpaid invoice can be cancelled.\n" "To cancel this invoice, make sure all payment(s) are also cancelled." msgstr "" "Apenas faturas completamente em aberto podem ser canceladas.\n" @@ -180,15 +175,13 @@ msgstr "Data de reversão" #. module: account_document_reversal #: code:addons/account_document_reversal/models/account_move.py:22 #, python-format -msgid "" -"This action is not allowed for cancel with reversal.\n" +msgid "This action is not allowed for cancel with reversal.\n" "Please use Reverse Entry." msgstr "" "Esta ação não é permitida para cancelar com reversão.\n" "Por favor use o Movimento Revertido." #. module: account_document_reversal -#: model:ir.model.fields,help:account_document_reversal.field_account_bank_statement_import_journal_creation__is_cancel_reversal #: model:ir.model.fields,help:account_document_reversal.field_account_journal__is_cancel_reversal #: model:ir.model.fields,help:account_document_reversal.field_account_move__is_cancel_reversal msgid "True, when journal allow cancel entries with method is reversal" @@ -197,14 +190,12 @@ msgstr "" "reversão" #. module: account_document_reversal -#: model:ir.model.fields,field_description:account_document_reversal.field_account_bank_statement_import_journal_creation__is_cancel_reversal #: model:ir.model.fields,field_description:account_document_reversal.field_account_journal__is_cancel_reversal #: model:ir.model.fields,field_description:account_document_reversal.field_account_move__is_cancel_reversal msgid "Use Cancel Reversal" msgstr "Usar Reversão de Cancelamento" #. module: account_document_reversal -#: model:ir.model.fields,field_description:account_document_reversal.field_account_bank_statement_import_journal_creation__use_different_journal #: model:ir.model.fields,field_description:account_document_reversal.field_account_journal__use_different_journal #: model:ir.model.fields,field_description:account_document_reversal.field_reverse_account_document__use_different_journal msgid "Use different journal for reversal" diff --git a/account_document_reversal/models/__init__.py b/account_document_reversal/models/__init__.py index 4ad5a3bf6..8cc5934d9 100644 --- a/account_document_reversal/models/__init__.py +++ b/account_document_reversal/models/__init__.py @@ -2,7 +2,8 @@ # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html) from . import account from . import account_document_reversal -from . import account_invoice from . import account_payment from . import account_bank_statement from . import account_move +from . import sale +from . import purchase diff --git a/account_document_reversal/models/account.py b/account_document_reversal/models/account.py index b7afc1094..da01e0180 100644 --- a/account_document_reversal/models/account.py +++ b/account_document_reversal/models/account.py @@ -1,6 +1,6 @@ # Copyright 2019 Ecosoft Co., Ltd (http://ecosoft.co.th/) # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html) -from odoo import api, fields, models +from odoo import fields, models class AccountJournal(models.Model): @@ -8,7 +8,7 @@ class AccountJournal(models.Model): cancel_method = fields.Selection( [ - ("normal", "Normal (delete journal entries if exists)"), + ("normal", "Normal (remove journal entries)"), ("reversal", "Reversal (create reversed journal entries)"), ], string="Cancel Method", @@ -30,9 +30,6 @@ class AccountJournal(models.Model): help="Journal in this field will show in reversal wizard as default", ) - @api.multi def _compute_is_cancel_reversal(self): for rec in self: - rec.is_cancel_reversal = ( - rec.update_posted and rec.cancel_method == "reversal" - ) + rec.is_cancel_reversal = rec.cancel_method == "reversal" diff --git a/account_document_reversal/models/account_bank_statement.py b/account_document_reversal/models/account_bank_statement.py index 07f2dafbe..3d4f732f3 100644 --- a/account_document_reversal/models/account_bank_statement.py +++ b/account_document_reversal/models/account_bank_statement.py @@ -1,6 +1,6 @@ # Copyright 2019 Ecosoft Co., Ltd (http://ecosoft.co.th/) # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html) -from odoo import _, api, models +from odoo import _, models from odoo.exceptions import UserError @@ -8,11 +8,10 @@ class AccountPayment(models.Model): _name = "account.bank.statement.line" _inherit = ["account.bank.statement.line", "account.document.reversal"] - @api.multi def button_cancel_reconciliation(self): """ If cancel method is to reverse, use document reversal wizard """ cancel_reversal = all( - self.mapped("journal_entry_ids.move_id." "journal_id.is_cancel_reversal") + self.mapped("journal_entry_ids.move_id.journal_id.is_cancel_reversal") ) states = self.mapped("statement_id.state") if cancel_reversal: @@ -21,7 +20,6 @@ class AccountPayment(models.Model): return self.reverse_document_wizard() return super().button_cancel_reconciliation() - @api.multi def action_document_reversal(self, date=None, journal_id=None): """ Reverse all moves related to this statement + delete payment """ # This part is from button_cancel_reconciliation() @@ -37,30 +35,24 @@ class AccountPayment(models.Model): st_line.move_name and line.payment_id.payment_reference == st_line.move_name ): - # there can be several moves linked to a statement line but - # maximum one created by the line itself + # there can be several moves linked to a statement line + # but maximum one created by the line itself aml_to_cancel |= line payment_to_cancel |= line.payment_id aml_to_unbind = aml_to_unbind - aml_to_cancel + if aml_to_unbind: aml_to_unbind.write({"statement_line_id": False}) + payment_to_unreconcile = payment_to_unreconcile - payment_to_cancel if payment_to_unreconcile: payment_to_unreconcile.unreconcile() # -- - # Set all moves to unreconciled - aml_to_cancel.filtered(lambda x: x.account_id.reconcile).remove_move_reconcile() + # Find account moves to cancel reversal moves = aml_to_cancel.mapped("move_id") - # Important to remove relation with move.line before reverse - aml_to_cancel.write( - {"payment_id": False, "statement_id": False, "statement_line_id": False} - ) # Create reverse entries - moves.reverse_moves(date, journal_id) - # Delete related payments - if payment_to_cancel: - payment_to_cancel.unlink() - # Unlink from statement line - self.write({"move_name": False}) + moves._cancel_reversal(journal_id) + # Set cancel related payments + payment_to_cancel.write({"state": "cancelled"}) return True diff --git a/account_document_reversal/models/account_document_reversal.py b/account_document_reversal/models/account_document_reversal.py index 44507cb39..09ed8b1a3 100644 --- a/account_document_reversal/models/account_document_reversal.py +++ b/account_document_reversal/models/account_document_reversal.py @@ -1,22 +1,32 @@ # Copyright 2019 Ecosoft Co., Ltd (http://ecosoft.co.th/) # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html) -from odoo import api, models +from odoo import api, fields, models class AccountDocumentReversal(models.AbstractModel): _name = "account.document.reversal" _description = "Abstract Module for Document Reversal" + is_cancel_reversal = fields.Boolean( + string="Use Cancel Reversal", compute="_compute_is_cancel_reversal", + ) + + def _compute_is_cancel_reversal(self): + """ Based on setting in document's journal """ + for rec in self: + rec.is_cancel_reversal = ( + rec.journal_id.is_cancel_reversal if "journal_id" in rec else False + ) + @api.model def reverse_document_wizard(self): """ Return Wizard to Cancel Document """ action = self.env.ref( - "account_document_reversal." "action_view_reverse_account_document" + "account_document_reversal.action_view_reverse_account_document" ) vals = action.read()[0] return vals - @api.multi def action_document_reversal(self, date=None, journal_id=None): """ Reverse with following guildeline, - Check existing document state / raise warning diff --git a/account_document_reversal/models/account_invoice.py b/account_document_reversal/models/account_invoice.py deleted file mode 100644 index 36c1c2f62..000000000 --- a/account_document_reversal/models/account_invoice.py +++ /dev/null @@ -1,58 +0,0 @@ -# Copyright 2019 Ecosoft Co., Ltd (http://ecosoft.co.th/) -# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html) -from odoo import _, api, models -from odoo.exceptions import UserError, ValidationError - - -class AccountInvoice(models.Model): - _name = "account.invoice" - _inherit = ["account.invoice", "account.document.reversal"] - - @api.multi - def action_invoice_cancel(self): - """ If cancel method is to reverse, use document reversal wizard - * Draft invoice, fall back to standard invoice cancel - * Non draft, must be fully open (not even partial reconciled) to cancel - """ - cancel_reversal = all(self.mapped("journal_id.is_cancel_reversal")) - states = self.mapped("state") - if cancel_reversal and "draft" not in states: - if not all(st == "open" for st in states) or ( - self.mapped("move_id.line_ids.matched_debit_ids") - | self.mapped("move_id.line_ids.matched_credit_ids") - ): - raise UserError( - _( - "Only fully unpaid invoice can be cancelled.\n" - "To cancel this invoice, make sure all payment(s) " - "are also cancelled." - ) - ) - return self.reverse_document_wizard() - return super().action_invoice_cancel() - - @api.multi - def action_document_reversal(self, date=None, journal_id=None): - """ Reverse all moves related to this invoice + set state to cancel """ - # Check document state - if "cancel" in self.mapped("state"): - raise ValidationError(_("You are trying to cancel the cancelled document")) - MoveLine = self.env["account.move.line"] - move_lines = MoveLine.search([("invoice_id", "in", self.ids)]) - moves = move_lines.mapped("move_id") - # Set all moves to unreconciled - move_lines.filtered(lambda x: x.account_id.reconcile).remove_move_reconcile() - # Important to remove relation with move.line before reverse - move_lines.write({"invoice_id": False}) - # Create reverse entries - moves.reverse_moves(date, journal_id) - # Set state cancelled and unlink with account.move - self.write( - { - "move_id": False, - "move_name": False, - "reference": False, - "state": "cancel", - } - ) - return True diff --git a/account_document_reversal/models/account_move.py b/account_document_reversal/models/account_move.py index 8eb1732df..3a17031b6 100644 --- a/account_document_reversal/models/account_move.py +++ b/account_document_reversal/models/account_move.py @@ -1,26 +1,113 @@ -# Copyright 2019 Eficent Business and IT Consulting Services, S.L. +# Copyright 2019 Ecosoft Co., Ltd (http://ecosoft.co.th/) # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html) -from odoo import _, api, fields, models -from odoo.exceptions import ValidationError +from odoo import _, fields, models +from odoo.exceptions import UserError class AccountMove(models.Model): _name = "account.move" _inherit = ["account.move", "account.document.reversal"] - is_cancel_reversal = fields.Boolean( - string="Use Cancel Reversal", related="journal_id.is_cancel_reversal", + cancel_reversal = fields.Boolean( + string="Cancel Reversal", + default=False, + copy=False, + help="This document is being cancelled by using reversal method", + ) + reverse_entry_id = fields.Many2one( + comodel_name="account.move", + string="Reversed by", + compute="_compute_reverse_entry_id", + help="The move that reverse this move (opposite of reversed_entry_id)", ) - @api.multi + def _compute_reverse_entry_id(self): + res = self.sudo().search_read( + fields=["id", "reversed_entry_id"], + domain=[("reversed_entry_id", "in", self.ids)], + ) + reverse_entries = {x["reversed_entry_id"][0]: x["id"] for x in res} + for move in self: + move.reverse_entry_id = reverse_entries.get(move.id, False) + + def button_cancel_reversal(self): + return self.reverse_document_wizard() + + def button_draft(self): + for rec in self: + if rec.is_cancel_reversal and rec.state != "cancel": + raise UserError(_("Cannot set to draft!")) + return super().button_draft() + def button_cancel(self): - """ Do not allow using this button for cancel with reversal """ - cancel_reversal = any(self.mapped("is_cancel_reversal")) - if cancel_reversal: - raise ValidationError( + if any(self.mapped("is_cancel_reversal")): + raise UserError(_("Please use button_cancel_reversal()")) + return super().button_cancel() + + def action_document_reversal(self, date=None, journal_id=None): + # Check document readiness + valid_state = ( + len(self.mapped("state")) == 1 + and list(set(self.mapped("state")))[0] == "posted" + ) + if not valid_state: + raise UserError(_("Only posted document can be cancelled (reversal)")) + if self.mapped("line_ids.matched_debit_ids") | self.mapped( + "line_ids.matched_credit_ids" + ): + raise UserError( _( - "This action is not allowed for cancel with reversal.\n" - "Please use Reverse Entry." + "Only fully unpaid invoice can be cancelled.\n" + "To cancel this invoice, make sure all payment(s) " + "are also cancelled." ) ) - return super().button_cancel() + # Create reverse entries + self._cancel_reversal(journal_id) + return True + + def _cancel_reversal(self, journal_id): + self.mapped("line_ids").filtered( + lambda x: x.account_id.reconcile + ).remove_move_reconcile() + Reversal = self.env["account.move.reversal"] + res = Reversal.with_context( + active_ids=self.ids, active_model="account.move" + ).default_get([]) + res.update( + {"journal_id": journal_id, "refund_method": "cancel", "move_type": "entry"} + ) + reversal = Reversal.create(res) + reversal.with_context(cancel_reversal=True).reverse_moves() + + def _reverse_moves(self, default_values_list=None, cancel=False): + """ Set flag on the moves and the reversal moves being reversed """ + if self._context.get("cancel_reversal"): + self.write({"cancel_reversal": True}) + reverse_moves = super()._reverse_moves(default_values_list, cancel) + if self._context.get("cancel_reversal"): + reverse_moves.write({"cancel_reversal": True}) + return reverse_moves + + def _reverse_move_vals(self, default_values, cancel=True): + """ Reverse with cancel reversal, always use move_type = entry """ + if self._context.get("cancel_reversal"): + default_values.update({"type": "entry"}) + return super()._reverse_move_vals(default_values, cancel) + + +class AccountMoveLine(models.Model): + _inherit = "account.move.line" + + def remove_move_reconcile(self): + """ Freeze move with cancel_reversal = True, disallow unreconcile """ + if not self._context.get("cancel_reversal") and any( + self.mapped("move_id").mapped("cancel_reversal") + ): + raise UserError( + _( + "This document was cancelled and freozen,\n" + "unreconcilation not allowed." + ) + ) + return super().remove_move_reconcile() diff --git a/account_document_reversal/models/account_payment.py b/account_document_reversal/models/account_payment.py index c9adde6de..187348e96 100644 --- a/account_document_reversal/models/account_payment.py +++ b/account_document_reversal/models/account_payment.py @@ -1,38 +1,44 @@ # Copyright 2019 Ecosoft Co., Ltd (http://ecosoft.co.th/) # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html) -from odoo import _, api, models -from odoo.exceptions import ValidationError +from odoo import _, models +from odoo.exceptions import UserError class AccountPayment(models.Model): _name = "account.payment" _inherit = ["account.payment", "account.document.reversal"] - @api.multi + def cancel_reversal(self): + return self.reverse_document_wizard() + + def action_draft(self): + """ Case cancel reversal, set to draft allowed only when no moves """ + for rec in self: + if rec.is_cancel_reversal and rec.move_line_ids: + raise UserError(_("Cannot set to draft!")) + return super().action_draft() + def cancel(self): - """ If cancel method is to reverse, use document reversal wizard """ - cancel_reversal = all( - self.mapped("move_line_ids.move_id.journal_id.is_cancel_reversal") - ) - states = self.mapped("state") - if cancel_reversal and "draft" not in states: - return self.reverse_document_wizard() + if any(self.mapped("is_cancel_reversal")): + raise UserError(_("Please use cancel_reversal()")) return super().cancel() - @api.multi def action_document_reversal(self, date=None, journal_id=None): """ Reverse all moves related to this payment + set state to cancel """ - # Check document state - if "cancelled" in self.mapped("state"): - raise ValidationError(_("You are trying to cancel the cancelled document")) - move_lines = self.mapped("move_line_ids") + # Check document readiness + valid_state = ( + len(self.mapped("state")) == 1 + and list(set(self.mapped("state")))[0] == "posted" + ) + if not valid_state: + raise UserError(_("Only validated document can be cancelled (reversal)")) + # Find moves to get reversed + move_lines = self.mapped("move_line_ids").filtered( + lambda x: x.journal_id == self.mapped("journal_id")[0] + ) moves = move_lines.mapped("move_id") - # Set all moves to unreconciled - move_lines.filtered(lambda x: x.account_id.reconcile).remove_move_reconcile() - # Important to remove relation with move.line before reverse - move_lines.write({"payment_id": False}) # Create reverse entries - moves.reverse_moves(date, journal_id) + moves._cancel_reversal(journal_id) # Set state cancelled and unlink with account.move - self.write({"move_name": False, "state": "cancelled"}) + self.write({"state": "cancelled"}) return True diff --git a/account_document_reversal/models/purchase.py b/account_document_reversal/models/purchase.py new file mode 100644 index 000000000..0092087da --- /dev/null +++ b/account_document_reversal/models/purchase.py @@ -0,0 +1,24 @@ +# Copyright 2019 Ecosoft Co., Ltd (http://ecosoft.co.th/) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html) +from odoo import api, models + + +class PurchaseOrderLine(models.Model): + _inherit = "purchase.order.line" + + @api.depends("invoice_lines.move_id.state", "invoice_lines.quantity") + def _compute_qty_invoiced(self): + """ Cancel Reversal Entry is of type "entry", correction is needed """ + res = super()._compute_qty_invoiced() + for line in self: + for inv_line in line.invoice_lines: + if inv_line.move_id.cancel_reversal: + if inv_line.move_id.type == "in_invoice": + line.qty_invoiced -= inv_line.product_uom_id._compute_quantity( + inv_line.quantity, line.product_uom + ) + elif inv_line.move_id.type == "in_refund": + line.qty_invoiced += inv_line.product_uom_id._compute_quantity( + inv_line.quantity, line.product_uom + ) + return res diff --git a/account_document_reversal/models/sale.py b/account_document_reversal/models/sale.py new file mode 100644 index 000000000..95da5c2a4 --- /dev/null +++ b/account_document_reversal/models/sale.py @@ -0,0 +1,26 @@ +# Copyright 2019 Ecosoft Co., Ltd (http://ecosoft.co.th/) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html) +from odoo import api, models + + +class SaleOrderLine(models.Model): + _inherit = "sale.order.line" + + @api.depends("invoice_lines.move_id.state", "invoice_lines.quantity") + def _get_invoice_qty(self): + """ Cancel Reversal Entry is of type "entry", correction is needed """ + res = super()._get_invoice_qty() + for line in self: + for invoice_line in line.invoice_lines: + if invoice_line.move_id.cancel_reversal: + if invoice_line.move_id.type == "out_invoice": + uom = invoice_line.product_uom_id + line.qty_invoiced -= uom._compute_quantity( + invoice_line.quantity, line.product_uom + ) + elif invoice_line.move_id.type == "out_refund": + uom = invoice_line.product_uom_id + line.qty_invoiced += uom._compute_quantity( + invoice_line.quantity, line.product_uom + ) + return res diff --git a/account_document_reversal/readme/DESCRIPTION.rst b/account_document_reversal/readme/DESCRIPTION.rst index e2e724839..449b939d1 100644 --- a/account_document_reversal/readme/DESCRIPTION.rst +++ b/account_document_reversal/readme/DESCRIPTION.rst @@ -7,3 +7,17 @@ Following are documented provide this feature, - Invoice (account.invoice) - Payment (acccont.payment) - Bank Statement (account.bank.statement.line) + +Remarks on changes when compare to version 12 +============================================= + +Odoo 13 has removed account.invoice, as such Invoice is no longer a front-end document +which generate account.move as a back-end document when validated. + +Invoice is now account.move itself and force following changes, + +- Canceled invoice (account.move) will create reversed account.move of type 'entry' to itself +- Canceled invoice (account.move) status is 'posted', with the new flag 'cancel_reversal = True' +- As result, cancel a posted invoice with reversal (state=posted) is now different from cancel from draft (state=canceled) +- When invoice or payment is reversed canceled, it will not allowed set to draft, in practice it will be frozen. +- The reversed canceled document (both invoice, payment, statement line) will still keep the relation with its journal entries diff --git a/account_document_reversal/tests/test_invoice_reversal.py b/account_document_reversal/tests/test_invoice_reversal.py index 25ee36627..82edb7a49 100644 --- a/account_document_reversal/tests/test_invoice_reversal.py +++ b/account_document_reversal/tests/test_invoice_reversal.py @@ -7,12 +7,11 @@ class TestInvoiceReversal(SavepointCase): @classmethod def setUpClass(cls): super(TestInvoiceReversal, cls).setUpClass() - cls.partner = cls.env["res.partner"].create({"name": "Test"}) cls.account_type_receivable = cls.env["account.account.type"].create( - {"name": "Test Receivable", "type": "receivable",} + {"name": "Test Receivable", "type": "receivable", "internal_group": "asset"} ) cls.account_type_regular = cls.env["account.account.type"].create( - {"name": "Test Regular", "type": "other",} + {"name": "Test Regular", "type": "other", "internal_group": "income"} ) cls.account_receivable = cls.env["account.account"].create( { @@ -31,24 +30,28 @@ class TestInvoiceReversal(SavepointCase): } ) cls.sale_journal = cls.env["account.journal"].search([("type", "=", "sale")])[0] - cls.invoice = cls.env["account.invoice"].create( + cls.partner = cls.env["res.partner"].create( + { + "name": "Test", + "property_account_receivable_id": cls.account_receivable.id, + } + ) + cls.invoice = cls.env["account.move"].create( { "name": "Test Customer Invoice", "journal_id": cls.sale_journal.id, "partner_id": cls.partner.id, - "account_id": cls.account_receivable.id, - } - ) - cls.invoice_line = cls.env["account.invoice.line"] - cls.invoice_line1 = cls.invoice_line.create( - { - "invoice_id": cls.invoice.id, - "name": "Line 1", - "price_unit": 200.0, - "account_id": cls.account_income.id, - "quantity": 1, + "type": "out_invoice", } ) + cls.invoice_line = { + "move_id": cls.invoice.id, + "name": "Line 1", + "price_unit": 200.0, + "account_id": cls.account_income.id, + "quantity": 1, + } + cls.invoice.write({"invoice_line_ids": [(0, 0, cls.invoice_line)]}) def test_journal_invoice_cancel_reversal(self): """ Tests cancel with reversal, end result must follow, @@ -56,30 +59,26 @@ class TestInvoiceReversal(SavepointCase): - Status is changed to cancel """ # Test journal + self.sale_journal.write({"cancel_method": "normal"}) + self.sale_journal.invalidate_cache() self.sale_journal.write( - {"update_posted": True, "cancel_method": "normal",} - ) - self.assertFalse(self.sale_journal.is_cancel_reversal) - self.sale_journal.write( - { - "update_posted": True, - "cancel_method": "reversal", - "use_different_journal": True, - } + {"cancel_method": "reversal", "use_different_journal": True} ) # Open invoice - self.invoice.action_invoice_open() - move = self.invoice.move_id + self.invoice.post() + # Normal cancel button is not usable. + with self.assertRaises(Exception): + self.invoice.button_cancel() # Click Cancel will open reverse document wizard - res = self.invoice.action_invoice_cancel() + res = self.invoice.button_cancel_reversal() self.assertEqual(res["res_model"], "reverse.account.document") # Cancel invoice - ctx = {"active_model": "account.invoice", "active_ids": [self.invoice.id]} + ctx = {"active_model": "account.move", "active_ids": [self.invoice.id]} f = Form(self.env[res["res_model"]].with_context(ctx)) cancel_wizard = f.save() cancel_wizard.action_cancel() - reversed_move = move.reverse_entry_id - move_reconcile = move.mapped("line_ids").mapped("full_reconcile_id") + reversed_move = self.invoice.reverse_entry_id + move_reconcile = self.invoice.mapped("line_ids").mapped("full_reconcile_id") reversed_move_reconcile = reversed_move.mapped("line_ids").mapped( "full_reconcile_id" ) @@ -87,4 +86,8 @@ class TestInvoiceReversal(SavepointCase): self.assertTrue(move_reconcile) self.assertTrue(reversed_move_reconcile) self.assertEqual(move_reconcile, reversed_move_reconcile) - self.assertEqual(self.invoice.state, "cancel") + self.assertEqual(self.invoice.state, "posted") + self.assertEqual(self.invoice.cancel_reversal, True) + # After reversed, set to draft is not allowed + with self.assertRaises(Exception): + self.invoice.button_draft() diff --git a/account_document_reversal/tests/test_payment_reversal.py b/account_document_reversal/tests/test_payment_reversal.py index cc2d42edb..fce57eae4 100644 --- a/account_document_reversal/tests/test_payment_reversal.py +++ b/account_document_reversal/tests/test_payment_reversal.py @@ -13,22 +13,22 @@ class TestPaymentReversal(SavepointCase): # Models cls.acc_bank_stmt_model = cls.env["account.bank.statement"] cls.acc_bank_stmt_line_model = cls.env["account.bank.statement.line"] - cls.partner = cls.env["res.partner"].create({"name": "Test"}) cls.account_account_type_model = cls.env["account.account.type"] cls.account_account_model = cls.env["account.account"] cls.account_journal_model = cls.env["account.journal"] - cls.account_invoice_model = cls.env["account.invoice"] + cls.account_invoice_model = cls.env["account.move"] cls.account_move_line_model = cls.env["account.move.line"] - cls.invoice_line_model = cls.env["account.invoice.line"] + cls.invoice_line_model = cls.env["account.move.line"] + cls.payment_model = cls.env["account.payment"] # Records cls.account_type_bank = cls.account_account_type_model.create( - {"name": "Test Bank", "type": "liquidity",} + {"name": "Test Bank", "type": "liquidity", "internal_group": "asset"} ) cls.account_type_receivable = cls.account_account_type_model.create( - {"name": "Test Receivable", "type": "receivable",} + {"name": "Test Receivable", "type": "receivable", "internal_group": "asset"} ) cls.account_type_regular = cls.account_account_type_model.create( - {"name": "Test Regular", "type": "other",} + {"name": "Test Regular", "type": "other", "internal_group": "income"} ) cls.account_bank = cls.account_account_model.create( { @@ -66,24 +66,29 @@ class TestPaymentReversal(SavepointCase): {"name": "Test Bank", "code": "TBK", "type": "bank"} ) cls.sale_journal = cls.account_journal_model.search([("type", "=", "sale")])[0] + cls.partner = cls.env["res.partner"].create( + { + "name": "Test", + "property_account_receivable_id": cls.account_receivable.id, + } + ) cls.invoice = cls.account_invoice_model.create( { "name": "Test Customer Invoice", "journal_id": cls.sale_journal.id, "partner_id": cls.partner.id, - "account_id": cls.account_receivable.id, + "type": "out_invoice", } ) - cls.invoice_line1 = cls.invoice_line_model.create( - { - "invoice_id": cls.invoice.id, - "name": "Line 1", - "price_unit": 200.0, - "account_id": cls.account_income.id, - "quantity": 1, - } - ) + cls.invoice_line = { + "move_id": cls.invoice.id, + "name": "Line 1", + "price_unit": 200.0, + "account_id": cls.account_income.id, + "quantity": 1, + } + cls.invoice.write({"invoice_line_ids": [(0, 0, cls.invoice_line)]}) def test_payment_cancel_normal(self): """ Tests that, if I don't use cancel reversal, @@ -91,12 +96,24 @@ class TestPaymentReversal(SavepointCase): - account move are removed completely """ # Test journal with normal cancel - self.bank_journal.write({"update_posted": True, "cancel_method": "normal"}) + self.bank_journal.write({"cancel_method": "normal"}) # Open invoice - self.invoice.action_invoice_open() + self.invoice.post() # Pay invoice - self.invoice.pay_and_reconcile(self.bank_journal, 200.0) - payment = self.invoice.payment_ids[0] + payment = self.payment_model.create( + { + "payment_type": "inbound", + "payment_method_id": self.env.ref( + "account.account_payment_method_manual_in" + ).id, + "partner_type": "customer", + "partner_id": self.invoice.partner_id.id, + "amount": 200.0, + "journal_id": self.bank_journal.id, + } + ) + payment.post() + payment.action_draft() payment.cancel() move_lines = self.env["account.move.line"].search( [("payment_id", "=", payment.id)] @@ -112,28 +129,41 @@ class TestPaymentReversal(SavepointCase): - The invoice is not reconciled with the payment anymore """ # Test journal - self.bank_journal.write({"update_posted": True, "cancel_method": "reversal"}) + self.bank_journal.write({"cancel_method": "reversal"}) # Open invoice - self.invoice.action_invoice_open() + self.invoice.post() # Pay invoice - self.invoice.pay_and_reconcile(self.bank_journal, 200.0) - payment = self.invoice.payment_ids[0] + payment = self.payment_model.create( + { + "payment_type": "inbound", + "payment_method_id": self.env.ref( + "account.account_payment_method_manual_in" + ).id, + "partner_type": "customer", + "partner_id": self.invoice.partner_id.id, + "amount": 200.0, + "journal_id": self.bank_journal.id, + } + ) + payment.post() move = ( self.env["account.move.line"] .search([("payment_id", "=", payment.id)], limit=1) .move_id ) - res = payment.cancel() + # Set to draft no longer allowed, must do cancel reversal + with self.assertRaises(Exception): + payment.action_draft() + # Normal cancel no longer allowed + with self.assertRaises(Exception): + payment.cancel() + res = payment.cancel_reversal() # Cancel payment ctx = {"active_model": "account.payment", "active_ids": [payment.id]} f = Form(self.env[res["res_model"]].with_context(ctx)) self.assertEqual(res["res_model"], "reverse.account.document") cancel_wizard = f.save() cancel_wizard.action_cancel() - payment_moves = self.env["account.move.line"].search( - [("payment_id", "=", payment.id)] - ) - self.assertFalse(payment_moves) reversed_move = move.reverse_entry_id move_reconcile = move.mapped("line_ids").mapped("full_reconcile_id") reversed_move_reconcile = reversed_move.mapped("line_ids").mapped( @@ -144,7 +174,7 @@ class TestPaymentReversal(SavepointCase): self.assertTrue(reversed_move_reconcile) self.assertEqual(move_reconcile, reversed_move_reconcile) self.assertEqual(payment.state, "cancelled") - self.assertEqual(self.invoice.state, "open") + self.assertEqual(self.invoice.state, "posted") def test_bank_statement_cancel_normal(self): """ Tests that, if I don't use cancel reversal, @@ -153,9 +183,9 @@ class TestPaymentReversal(SavepointCase): - account move are removed completely """ # Test journal with normal cancel - self.bank_journal.write({"update_posted": True, "cancel_method": "normal"}) + self.bank_journal.write({"cancel_method": "normal"}) # Open invoice - self.invoice.action_invoice_open() + self.invoice.post() bank_stmt = self.acc_bank_stmt_model.create( { "journal_id": self.bank_journal.id, @@ -174,7 +204,7 @@ class TestPaymentReversal(SavepointCase): ) line_id = self.account_move_line_model # reconcile the payment with the invoice - for l in self.invoice.move_id.line_ids: + for l in self.invoice.line_ids: if l.account_id.id == self.account_receivable.id: line_id = l break @@ -204,14 +234,13 @@ class TestPaymentReversal(SavepointCase): """ Tests that I can create an invoice, pay it via a bank statement line and then reverse the bank statement line. I expect: - Reversal journal entry is created, and reconciled with original entry - - Payment is deleted - The invoice is not reconciled with the payment anymore - The line in the statement is ready to reconcile again """ # Test journal - self.bank_journal.write({"update_posted": True, "cancel_method": "reversal"}) + self.bank_journal.write({"cancel_method": "reversal"}) # Open invoice - self.invoice.action_invoice_open() + self.invoice.post() bank_stmt = self.acc_bank_stmt_model.create( { "journal_id": self.bank_journal.id, @@ -231,7 +260,7 @@ class TestPaymentReversal(SavepointCase): ) line_id = self.account_move_line_model # reconcile the payment with the invoice - for l in self.invoice.move_id.line_ids: + for l in self.invoice.line_ids: if l.account_id.id == self.account_receivable.id: line_id = l break @@ -248,7 +277,6 @@ class TestPaymentReversal(SavepointCase): ) self.assertTrue(bank_stmt_line.journal_entry_ids) original_move_lines = bank_stmt_line.journal_entry_ids - original_payment_id = original_move_lines.mapped("payment_id").id self.assertTrue(original_move_lines.mapped("statement_id")) # Cancel the statement line res = bank_stmt_line.button_cancel_reconciliation() @@ -260,12 +288,6 @@ class TestPaymentReversal(SavepointCase): self.assertEqual(res["res_model"], "reverse.account.document") cancel_wizard = f.save() cancel_wizard.action_cancel() - self.assertFalse(bank_stmt_line.journal_entry_ids) - payment = self.env["account.payment"].search( - [("id", "=", original_payment_id)], limit=1 - ) - self.assertFalse(payment) - self.assertFalse(original_move_lines.mapped("statement_id")) move = original_move_lines[0].move_id reversed_move = move.reverse_entry_id move_reconcile = move.mapped("line_ids").mapped("full_reconcile_id") @@ -282,11 +304,10 @@ class TestPaymentReversal(SavepointCase): to an expense account, and then reverse the reconciliation of the statement line. I expect: - Reversal journal entry is created, and reconciled with original entry - - Payment is deleted - The line in the statement is ready to reconcile again """ # Test journal - self.bank_journal.write({"update_posted": True, "cancel_method": "reversal"}) + self.bank_journal.write({"cancel_method": "reversal"}) # Create a bank statement bank_stmt = self.acc_bank_stmt_model.create( { @@ -304,21 +325,18 @@ class TestPaymentReversal(SavepointCase): "date": time.strftime("%Y") + "-07-15", } ) - line_id = self.account_move_line_model - bank_stmt_line.process_reconciliation( new_aml_dicts=[ { - "move_line": line_id, "account_id": self.account_expense.id, "debit": 200.0, + "credit": 0.0, "name": "test_expense_reconciliation", } ] ) self.assertTrue(bank_stmt_line.journal_entry_ids) original_move_lines = bank_stmt_line.journal_entry_ids - original_payment_id = original_move_lines.mapped("payment_id").id self.assertTrue(original_move_lines.mapped("statement_id")) # Cancel the statement line res = bank_stmt_line.button_cancel_reconciliation() @@ -330,12 +348,6 @@ class TestPaymentReversal(SavepointCase): self.assertEqual(res["res_model"], "reverse.account.document") cancel_wizard = f.save() cancel_wizard.action_cancel() - self.assertFalse(bank_stmt_line.journal_entry_ids) - payment = self.env["account.payment"].search( - [("id", "=", original_payment_id)], limit=1 - ) - self.assertFalse(payment) - self.assertFalse(original_move_lines.mapped("statement_id")) move = original_move_lines[0].move_id reversed_move = move.reverse_entry_id move_reconcile = move.mapped("line_ids").mapped("full_reconcile_id") @@ -353,7 +365,7 @@ class TestPaymentReversal(SavepointCase): - UserError will show """ # Test journal - self.bank_journal.write({"update_posted": True, "cancel_method": "reversal"}) + self.bank_journal.write({"cancel_method": "reversal"}) # Create a bank statement bank_stmt = self.acc_bank_stmt_model.create( { @@ -371,19 +383,16 @@ class TestPaymentReversal(SavepointCase): "date": time.strftime("%Y") + "-07-15", } ) - line_id = self.account_move_line_model - bank_stmt_line.process_reconciliation( new_aml_dicts=[ { - "move_line": line_id, "account_id": self.account_expense.id, "debit": 200.0, + "credit": 0.0, "name": "test_expense_reconciliation", } ] ) - bank_stmt.balance_end_real = 200.00 bank_stmt.check_confirm_bank() self.assertEqual(bank_stmt.state, "confirm") diff --git a/account_document_reversal/views/account_move_view.xml b/account_document_reversal/views/account_move_view.xml new file mode 100644 index 000000000..7782e083d --- /dev/null +++ b/account_document_reversal/views/account_move_view.xml @@ -0,0 +1,60 @@ + + + + account.move.form.inherit + account.move + + + + + + + + + + + + + + + + + view.account.invoice.filter + account.move + + + + + + + + + account.invoice.view.tree + account.move + + + + + + + + diff --git a/account_document_reversal/views/account_payment_view.xml b/account_document_reversal/views/account_payment_view.xml new file mode 100644 index 000000000..0d55e255d --- /dev/null +++ b/account_document_reversal/views/account_payment_view.xml @@ -0,0 +1,21 @@ + + + + view.account.payment.form + account.payment + + + + + + + + + diff --git a/account_document_reversal/views/account_view.xml b/account_document_reversal/views/account_view.xml index 6c7351638..ff00888d1 100644 --- a/account_document_reversal/views/account_view.xml +++ b/account_document_reversal/views/account_view.xml @@ -1,52 +1,28 @@ - - + account.journal.form account.journal - + - - - - - + + + + + + + - - - account.move.form.inherit - account.move - - - - - - - - - diff --git a/account_document_reversal/wizard/reverse_account_document.py b/account_document_reversal/wizard/reverse_account_document.py index 4e578ecc3..bfed87c6a 100644 --- a/account_document_reversal/wizard/reverse_account_document.py +++ b/account_document_reversal/wizard/reverse_account_document.py @@ -38,10 +38,9 @@ class ReverseAccountDocument(models.TransientModel): res["journal_id"] = journal.reversal_journal_id.id return res - @api.multi def action_cancel(self): model = self._context.get("active_model") active_ids = self._context.get("active_ids") documents = self.env[model].browse(active_ids) - documents.action_document_reversal(self.date, self.journal_id) + documents.action_document_reversal(self.date, self.journal_id.id) return {"type": "ir.actions.act_window_close"} diff --git a/account_document_reversal/wizard/reverse_account_document_wizard.xml b/account_document_reversal/wizard/reverse_account_document_wizard.xml index 32d324369..903238831 100644 --- a/account_document_reversal/wizard/reverse_account_document_wizard.xml +++ b/account_document_reversal/wizard/reverse_account_document_wizard.xml @@ -31,14 +31,12 @@ special="cancel" /> - + - Document Cancel reverse.account.document - form tree,form new