From 236a70ae7f67be73a1a676be27c0e1c16806c745 Mon Sep 17 00:00:00 2001
From: sergio-teruel
Date: Mon, 7 Dec 2020 10:45:41 +0100
Subject: [PATCH 01/20] [ADD] sale_payment_sheet: New module
---
sale_payment_sheet/README.rst | 111 ++++
sale_payment_sheet/__init__.py | 3 +
sale_payment_sheet/__manifest__.py | 28 +
sale_payment_sheet/i18n/es.po | 551 ++++++++++++++++++
.../i18n/sale_payment_sheet.pot | 542 +++++++++++++++++
sale_payment_sheet/models/__init__.py | 3 +
sale_payment_sheet/models/res_users.py | 13 +
.../models/sale_payment_sheet.py | 279 +++++++++
sale_payment_sheet/readme/CONFIGURE.rst | 4 +
sale_payment_sheet/readme/CONTRIBUTORS.rst | 4 +
sale_payment_sheet/readme/DESCRIPTION.rst | 2 +
sale_payment_sheet/readme/USAGE.rst | 22 +
.../report_sale_payment_sheet_summary.xml | 91 +++
.../report/sale_payment_sheet_report.xml | 12 +
.../security/ir.model.access.csv | 5 +
sale_payment_sheet/security/security.xml | 35 ++
.../static/description/icon.png | Bin 0 -> 9455 bytes
.../static/description/index.html | 459 +++++++++++++++
sale_payment_sheet/tests/__init__.py | 3 +
.../tests/test_sale_payment_sheet.py | 137 +++++
sale_payment_sheet/views/res_users_views.xml | 16 +
.../views/sale_payment_sheet_menu.xml | 70 +++
.../views/sale_payment_sheet_views.xml | 170 ++++++
sale_payment_sheet/wizards/__init__.py | 3 +
.../wizards/sale_invoice_payment.py | 95 +++
.../wizards/sale_invoice_payment_view.xml | 38 ++
26 files changed, 2696 insertions(+)
create mode 100644 sale_payment_sheet/README.rst
create mode 100644 sale_payment_sheet/__init__.py
create mode 100644 sale_payment_sheet/__manifest__.py
create mode 100644 sale_payment_sheet/i18n/es.po
create mode 100644 sale_payment_sheet/i18n/sale_payment_sheet.pot
create mode 100644 sale_payment_sheet/models/__init__.py
create mode 100644 sale_payment_sheet/models/res_users.py
create mode 100644 sale_payment_sheet/models/sale_payment_sheet.py
create mode 100644 sale_payment_sheet/readme/CONFIGURE.rst
create mode 100644 sale_payment_sheet/readme/CONTRIBUTORS.rst
create mode 100644 sale_payment_sheet/readme/DESCRIPTION.rst
create mode 100644 sale_payment_sheet/readme/USAGE.rst
create mode 100644 sale_payment_sheet/report/report_sale_payment_sheet_summary.xml
create mode 100644 sale_payment_sheet/report/sale_payment_sheet_report.xml
create mode 100644 sale_payment_sheet/security/ir.model.access.csv
create mode 100644 sale_payment_sheet/security/security.xml
create mode 100644 sale_payment_sheet/static/description/icon.png
create mode 100644 sale_payment_sheet/static/description/index.html
create mode 100644 sale_payment_sheet/tests/__init__.py
create mode 100644 sale_payment_sheet/tests/test_sale_payment_sheet.py
create mode 100644 sale_payment_sheet/views/res_users_views.xml
create mode 100644 sale_payment_sheet/views/sale_payment_sheet_menu.xml
create mode 100644 sale_payment_sheet/views/sale_payment_sheet_views.xml
create mode 100644 sale_payment_sheet/wizards/__init__.py
create mode 100644 sale_payment_sheet/wizards/sale_invoice_payment.py
create mode 100644 sale_payment_sheet/wizards/sale_invoice_payment_view.xml
diff --git a/sale_payment_sheet/README.rst b/sale_payment_sheet/README.rst
new file mode 100644
index 00000000000..2e8af10d759
--- /dev/null
+++ b/sale_payment_sheet/README.rst
@@ -0,0 +1,111 @@
+==================
+Sale payment sheet
+==================
+
+.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ !! 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%2Fsale--workflow-lightgray.png?logo=github
+ :target: https://github.com/OCA/sale-workflow/tree/13.0/sale_payment_sheet
+ :alt: OCA/sale-workflow
+.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
+ :target: https://translation.odoo-community.org/projects/sale-workflow-13-0/sale-workflow-13-0-sale_payment_sheet
+ :alt: Translate me on Weblate
+.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png
+ :target: https://runbot.odoo-community.org/runbot/167/13.0
+ :alt: Try me on Runbot
+
+|badge1| |badge2| |badge3| |badge4| |badge5|
+
+This module allows to commercial users register payments in a payment sheet.
+This payment sheet will generate a bank statement when is confirmed.
+
+**Table of contents**
+
+.. contents::
+ :local:
+
+Configuration
+=============
+
+To configure this module, you need to:
+
+#. Go to Settings > User and Companies > Users
+#. Select the allowed journals to register payments
+
+Usage
+=====
+
+To use this module, you need to:
+
+Create manual payment sheet:
+
+#. Go to Sales > Orders > Payments.
+#. Create new payment sheet.
+
+You can pay invoices directly, to do this:
+
+#. Go to Sales > Orders > Invoices.
+#. Select some invoices to pay.
+#. Click on Action > Sale invoice payment.
+#. A wizard will be displayed and select journal and put amount that you want
+ to pay.
+
+Payment one invoice:
+
+#. Go to Sales > Orders > Invoices.
+#. Enter to invoice form.
+#. Click "register payment".
+#. A wizard will be displayed and select journal and put amount that you want
+ to pay.
+
+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
+~~~~~~~
+
+* Tecnativa
+
+Contributors
+~~~~~~~~~~~~
+
+* `Tecnativa `__:
+
+ * Carlos Dauden
+ * Sergio Teruel
+
+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.
+
+This module is part of the `OCA/sale-workflow `_ project on GitHub.
+
+You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
diff --git a/sale_payment_sheet/__init__.py b/sale_payment_sheet/__init__.py
new file mode 100644
index 00000000000..9b2246d7e62
--- /dev/null
+++ b/sale_payment_sheet/__init__.py
@@ -0,0 +1,3 @@
+# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
+from . import models
+from . import wizards
diff --git a/sale_payment_sheet/__manifest__.py b/sale_payment_sheet/__manifest__.py
new file mode 100644
index 00000000000..dc449330ede
--- /dev/null
+++ b/sale_payment_sheet/__manifest__.py
@@ -0,0 +1,28 @@
+# Copyright 2020 Tecnativa - Carlos Dauden
+# Copyright 2020 Tecnativa - Sergio Teruel
+# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
+{
+ "name": "Sale payment sheet",
+ "summary": "Allow to create invoice payments to commercial users without "
+ "accounting permissions",
+ "version": "13.0.1.0.0",
+ "development_status": "Beta",
+ "category": "Account",
+ "website": "https://github.com/OCA/sale-workflow",
+ "author": "Tecnativa, Odoo Community Association (OCA)",
+ "maintainers": ["sergio-teruel"],
+ "license": "AGPL-3",
+ "application": False,
+ "installable": True,
+ "depends": ["sale"],
+ "data": [
+ "security/ir.model.access.csv",
+ "security/security.xml",
+ "report/report_sale_payment_sheet_summary.xml",
+ "report/sale_payment_sheet_report.xml",
+ "views/res_users_views.xml",
+ "views/sale_payment_sheet_views.xml",
+ "views/sale_payment_sheet_menu.xml",
+ "wizards/sale_invoice_payment_view.xml",
+ ],
+}
diff --git a/sale_payment_sheet/i18n/es.po b/sale_payment_sheet/i18n/es.po
new file mode 100644
index 00000000000..49475286ea6
--- /dev/null
+++ b/sale_payment_sheet/i18n/es.po
@@ -0,0 +1,551 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * sale_payment_sheet
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 13.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2021-02-09 08:37+0000\n"
+"PO-Revision-Date: 2021-02-09 09:39+0100\n"
+"Last-Translator: Sergio Teruel \n"
+"Language-Team: \n"
+"Language: es\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Generator: Poedit 2.3\n"
+
+#. module: sale_payment_sheet
+#: model:ir.actions.report,print_report_name:sale_payment_sheet.action_report_sale_payment_sheet
+msgid "'Payment sheet %s' % (object.name)"
+msgstr "'Hoja de pagos %s' % (object.name)"
+
+#. module: sale_payment_sheet
+#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.report_sale_payment_sheet
+msgid "Page: "
+msgstr "Página: "
+
+#. module: sale_payment_sheet
+#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.report_sale_payment_sheet
+msgid "Sheet: "
+msgstr " Hoja "
+
+#. module: sale_payment_sheet
+#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.report_sale_payment_sheet
+msgid "Total: "
+msgstr "Total: "
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__message_needaction
+msgid "Action Needed"
+msgstr "Necesaria acción"
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_res_users__commercial_journal_ids
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_invoice_payment_wiz__commercial_journal_ids
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__commercial_journal_ids
+msgid "Allowed journals for commercial"
+msgstr "Diarios permitidos"
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_invoice_payment_wiz__amount
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet_line__amount
+#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.report_sale_payment_sheet
+msgid "Amount"
+msgstr "Importe"
+
+#. module: sale_payment_sheet
+#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.view_invoice_tree
+msgid "Amount Due"
+msgstr "Importe adeudado"
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__message_attachment_count
+msgid "Attachment Count"
+msgstr "Conteo de archivos adjuntos"
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__statement_id
+#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.view_sale_payment_sheet_form
+msgid "Bank statement"
+msgstr "Extracto bancario"
+
+#. module: sale_payment_sheet
+#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.sale_invoice_payment_wiz
+msgid "Cancel"
+msgstr "Cancelar"
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__company_id
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet_line__company_id
+msgid "Company"
+msgstr "Compañía"
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,help:sale_payment_sheet.field_sale_payment_sheet__company_id
+#: model:ir.model.fields,help:sale_payment_sheet.field_sale_payment_sheet_line__company_id
+msgid "Company related to this journal"
+msgstr "Compañía relacionada con este diario"
+
+#. module: sale_payment_sheet
+#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.view_sale_payment_sheet_form
+msgid "Confirm sheet"
+msgstr "Confirmar hoja"
+
+#. module: sale_payment_sheet
+#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.view_sale_payment_sheet_search
+msgid "Confirmed"
+msgstr "Confirmado"
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_invoice_payment_wiz__create_uid
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__create_uid
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet_line__create_uid
+msgid "Created by"
+msgstr "Creado el"
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_invoice_payment_wiz__create_date
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__create_date
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet_line__create_date
+msgid "Created on"
+msgstr "Creado el"
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_invoice_payment_wiz__currency_id
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__currency_id
+msgid "Currency"
+msgstr "Moneda"
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__date
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet_line__date
+#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.report_sale_payment_sheet
+#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.view_sale_payment_sheet_search
+msgid "Date"
+msgstr "Fecha"
+
+#. module: sale_payment_sheet
+#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.report_sale_payment_sheet
+msgid "Description"
+msgstr "Descripción"
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_invoice_payment_wiz__display_name
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__display_name
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet_line__display_name
+msgid "Display Name"
+msgstr "Nombre a mostrar"
+
+#. module: sale_payment_sheet
+#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.view_sale_payment_sheet_search
+msgid "Draft"
+msgstr "Borrador"
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__reference
+msgid "External Reference"
+msgstr "Referencia Externa"
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__failed_message_ids
+msgid "Failed Messages"
+msgstr "Mensajes Fallidos"
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__message_follower_ids
+msgid "Followers"
+msgstr "Seguidores"
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__message_channel_ids
+msgid "Followers (Channels)"
+msgstr "Seguidores (Canales)"
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__message_partner_ids
+msgid "Followers (Partners)"
+msgstr "Seguidores (Empresas)"
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields.selection,name:sale_payment_sheet.selection__sale_payment_sheet_line__transaction_type__full
+msgid "Full payment"
+msgstr "Completo"
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,help:sale_payment_sheet.field_sale_payment_sheet_line__sequence
+msgid "Gives the sequence order when displaying a list of payment sheet lines."
+msgstr ""
+"Indica el orden de secuencia cuando se muestra una lista de líneas de la "
+"hoja de pagos."
+
+#. module: sale_payment_sheet
+#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.view_sale_payment_sheet_search
+msgid "Group By"
+msgstr "Agrupado por..."
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_invoice_payment_wiz__id
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__id
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet_line__id
+msgid "ID"
+msgstr "ID (Identificador)"
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,help:sale_payment_sheet.field_sale_payment_sheet__message_needaction
+#: model:ir.model.fields,help:sale_payment_sheet.field_sale_payment_sheet__message_unread
+msgid "If checked, new messages require your attention."
+msgstr "Si está marcado, hay nuevos mensajes que requieren su atención."
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,help:sale_payment_sheet.field_sale_payment_sheet__message_has_error
+msgid "If checked, some messages have a delivery error."
+msgstr "Si se encuentra marcado, algunos mensajes tienen error de envío."
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet_line__invoice_id
+#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.report_sale_payment_sheet
+msgid "Invoice"
+msgstr "Factura"
+
+#. module: sale_payment_sheet
+#: model:ir.actions.act_window,name:sale_payment_sheet.action_invoice_sale_payment_sheet
+#: model:ir.ui.menu,name:sale_payment_sheet.sale_payment_invoice
+#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.view_invoice_tree
+msgid "Invoices"
+msgstr "Facturas"
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__message_is_follower
+msgid "Is Follower"
+msgstr "Es seguidor"
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_invoice_payment_wiz__journal_id
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__journal_id
+#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.view_sale_payment_sheet_search
+msgid "Journal"
+msgstr "Diario"
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet_line__journal_currency_id
+msgid "Journal's Currency"
+msgstr "Moneda del diario"
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet_line__name
+msgid "Label"
+msgstr "Etiqueta"
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_invoice_payment_wiz____last_update
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet____last_update
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet_line____last_update
+msgid "Last Modified on"
+msgstr "Última modificación en"
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_invoice_payment_wiz__write_uid
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__write_uid
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet_line__write_uid
+msgid "Last Updated by"
+msgstr "Última actualización de"
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_invoice_payment_wiz__write_date
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__write_date
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet_line__write_date
+msgid "Last Updated on"
+msgstr "Última actualización en"
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__message_main_attachment_id
+msgid "Main Attachment"
+msgstr "Adjuntos principales"
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__message_content
+msgid "Message Content"
+msgstr "Contenido del mensaje"
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__message_has_error
+msgid "Message Delivery error"
+msgstr "Error de Envío de Mensaje"
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,help:sale_payment_sheet.field_sale_payment_sheet__message_content
+msgid "Message content, to be used only in searches"
+msgstr "Contenido del mensaje, para usarse en búsquedas"
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__message_ids
+msgid "Messages"
+msgstr "Messages"
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields.selection,name:sale_payment_sheet.selection__sale_payment_sheet__state__open
+msgid "New"
+msgstr "Nuevo"
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet_line__note
+msgid "Notes"
+msgstr "Notas"
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__message_needaction_counter
+msgid "Number of Actions"
+msgstr "Número de acciones"
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__message_has_error_counter
+msgid "Number of errors"
+msgstr "Errores"
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,help:sale_payment_sheet.field_sale_payment_sheet__message_needaction_counter
+msgid "Number of messages which requires an action"
+msgstr "Número de mensajes que requieren una acción"
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,help:sale_payment_sheet.field_sale_payment_sheet__message_has_error_counter
+msgid "Number of messages with delivery error"
+msgstr "Número de mensajes con error de envío"
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,help:sale_payment_sheet.field_sale_payment_sheet__message_unread_counter
+msgid "Number of unread messages"
+msgstr "Número de mensajes no leidos"
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields.selection,name:sale_payment_sheet.selection__sale_payment_sheet_line__transaction_type__partial
+msgid "Partial payment"
+msgstr "Parcial"
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet_line__partner_id
+#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.report_sale_payment_sheet
+msgid "Partner"
+msgstr "Empresa"
+
+#. module: sale_payment_sheet
+#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.sale_invoice_payment_wiz
+msgid "Payment"
+msgstr "Pagos"
+
+#. module: sale_payment_sheet
+#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.view_sale_payment_sheet_search
+msgid "Payment sheet"
+msgstr "Hoja de pagos"
+
+#. module: sale_payment_sheet
+#: model:ir.ui.menu,name:sale_payment_sheet.sale_payment_sheet_menu
+msgid "Payments"
+msgstr "Pagos"
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__name
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet_line__ref
+msgid "Reference"
+msgstr "Referencia"
+
+#. module: sale_payment_sheet
+#: model_terms:ir.actions.act_window,help:sale_payment_sheet.action_sale_payment_sheet
+msgid "Register a invoice payment (Salesman)"
+msgstr "Registrar pago de factura (Comerciales)"
+
+#. module: sale_payment_sheet
+#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.view_sale_payment_sheet_form
+msgid "Reset to New"
+msgstr "Reestablecer a Nuevo"
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_invoice_payment_wiz__user_id
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__user_id
+msgid "Responsible"
+msgstr "Responsable"
+
+#. module: sale_payment_sheet
+#: model:ir.model,name:sale_payment_sheet.model_sale_payment_sheet
+msgid "Sale Payment Sheet"
+msgstr "Hoja de pagos"
+
+#. module: sale_payment_sheet
+#: model:ir.model,name:sale_payment_sheet.model_sale_payment_sheet_line
+msgid "Sale Payment Sheet Line"
+msgstr "Líneas de la hoja de pagos"
+
+#. module: sale_payment_sheet
+#: model:ir.actions.act_window,name:sale_payment_sheet.action_sale_invoice_payment_wiz
+msgid "Sale invoice payment"
+msgstr "Pago de facturas"
+
+#. module: sale_payment_sheet
+#: model:ir.model,name:sale_payment_sheet.model_sale_invoice_payment_wiz
+#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.sale_invoice_payment_wiz
+msgid "Sale invoice payment wizard"
+msgstr "Asistente de pago de factura"
+
+#. module: sale_payment_sheet
+#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.view_sale_payment_sheet_tree
+msgid "Sale invoice payments"
+msgstr "Pagos de facturas"
+
+#. module: sale_payment_sheet
+#: model:ir.actions.act_window,name:sale_payment_sheet.action_sale_payment_sheet
+#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.view_sale_payment_sheet_form
+msgid "Sale payment sheet"
+msgstr "Hoja de pagos"
+
+#. module: sale_payment_sheet
+#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.view_invoice_tree
+msgid "Sales Person"
+msgstr "Comercial"
+
+#. module: sale_payment_sheet
+#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.view_sale_payment_sheet_search
+msgid "Search sale payment sheets"
+msgstr "Búsqueda de pagos de facturas"
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet_line__sequence
+msgid "Sequence"
+msgstr "Secuencia"
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet_line__sheet_id
+msgid "Sheet"
+msgstr "Hoja"
+
+#. module: sale_payment_sheet
+#: code:addons/sale_payment_sheet/models/sale_payment_sheet.py:0
+#, python-format
+msgid "Sheet %s confirmed, bank statement were created."
+msgstr "Hoja %s confirmada, se crearon los extractos bancarios."
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__line_ids
+#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.view_sale_payment_sheet_form
+msgid "Sheet lines"
+msgstr "Líneas"
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet_line__statement_line_id
+msgid "Statement Line"
+msgstr "Línea de extracto"
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__state
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet_line__state
+#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.view_sale_payment_sheet_search
+msgid "Status"
+msgstr "Estado"
+
+#. module: sale_payment_sheet
+#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.view_invoice_tree
+msgid "Tax Excluded"
+msgstr "Impuesto no incluido"
+
+#. module: sale_payment_sheet
+#: code:addons/sale_payment_sheet/models/sale_payment_sheet.py:0
+#, python-format
+msgid "The amount of a cash transaction cannot be 0."
+msgstr "El importe de una transacción en efectivo no puede ser 0."
+
+#. module: sale_payment_sheet
+#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.view_invoice_tree
+#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.view_sale_payment_sheet_form
+msgid "Total"
+msgstr "Total"
+
+#. module: sale_payment_sheet
+#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.view_invoice_tree
+msgid "Total Amount"
+msgstr "Importe total"
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet_line__transaction_type
+msgid "Transaction type"
+msgstr "Tipo de transacción"
+
+#. module: sale_payment_sheet
+#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.view_sale_payment_sheet_form
+msgid "Transactions"
+msgstr "Transacciones"
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__message_unread
+msgid "Unread Messages"
+msgstr "Mensajes sin leer"
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__message_unread_counter
+msgid "Unread Messages Counter"
+msgstr "Contador de mensajes no leidos"
+
+#. module: sale_payment_sheet
+#: model:ir.model,name:sale_payment_sheet.model_res_users
+msgid "Users"
+msgstr "Usuarios"
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,help:sale_payment_sheet.field_sale_payment_sheet_line__journal_currency_id
+msgid "Utility field to express amount currency"
+msgstr "Campo útil para expresar importe en divisa."
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields.selection,name:sale_payment_sheet.selection__sale_payment_sheet__state__confirm
+msgid "Validated"
+msgstr "Validado"
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__website_message_ids
+msgid "Website Messages"
+msgstr "Mensajes del sitio web"
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,help:sale_payment_sheet.field_sale_payment_sheet__website_message_ids
+msgid "Website communication history"
+msgstr "Historial de comunicaciones del sitio web"
+
+#. module: sale_payment_sheet
+#: code:addons/sale_payment_sheet/models/sale_payment_sheet.py:0
+#, python-format
+msgid "You can not delete a sheet if has related journal items."
+msgstr ""
+"No puede eliminar una hoja de pagos si tiene un extracto bancario "
+"relacionado."
+
+#. module: sale_payment_sheet
+#: code:addons/sale_payment_sheet/models/sale_payment_sheet.py:0
+#, python-format
+msgid "You can not delete payment lines if have related statement lines."
+msgstr ""
+"No puede eliminar líneas de pago si tienen una línea de extracto relacionada"
+
+#. module: sale_payment_sheet
+#: code:addons/sale_payment_sheet/models/sale_payment_sheet.py:0
+#, python-format
+msgid "You can not reopen a sheet that has any reconciled line."
+msgstr "No puede reabrir una hoja de pagos si tiene alguna línea conciliada."
+
+#. module: sale_payment_sheet
+#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.view_users_form
+msgid "sale payment sheet"
+msgstr "Hoja de pagos"
+
+#. module: sale_payment_sheet
+#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.report_sale_payment_sheet
+msgid "sale payment sheet Summary"
+msgstr "Resumen de pagos de facturas"
+
+#. module: sale_payment_sheet
+#: model:ir.actions.report,name:sale_payment_sheet.action_report_sale_payment_sheet
+msgid "sale payment sheet summary"
+msgstr "Resumen de pagos de facturas"
+
+#~ msgid "Journal Entries"
+#~ msgstr "Asientos contables"
diff --git a/sale_payment_sheet/i18n/sale_payment_sheet.pot b/sale_payment_sheet/i18n/sale_payment_sheet.pot
new file mode 100644
index 00000000000..a8a5776f85b
--- /dev/null
+++ b/sale_payment_sheet/i18n/sale_payment_sheet.pot
@@ -0,0 +1,542 @@
+# Translation of Odoo Server.
+# This file contains the translation of the following modules:
+# * sale_payment_sheet
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: Odoo Server 13.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2021-02-09 08:37+0000\n"
+"PO-Revision-Date: 2021-02-09 08:37+0000\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: sale_payment_sheet
+#: model:ir.actions.report,print_report_name:sale_payment_sheet.action_report_sale_payment_sheet
+msgid "'Payment sheet %s' % (object.name)"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.report_sale_payment_sheet
+msgid "Page: "
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.report_sale_payment_sheet
+msgid "Sheet: "
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.report_sale_payment_sheet
+msgid "Total: "
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__message_needaction
+msgid "Action Needed"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_res_users__commercial_journal_ids
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_invoice_payment_wiz__commercial_journal_ids
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__commercial_journal_ids
+msgid "Allowed journals for commercial"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_invoice_payment_wiz__amount
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet_line__amount
+#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.report_sale_payment_sheet
+msgid "Amount"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.view_invoice_tree
+msgid "Amount Due"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__message_attachment_count
+msgid "Attachment Count"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__statement_id
+#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.view_sale_payment_sheet_form
+msgid "Bank statement"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.sale_invoice_payment_wiz
+msgid "Cancel"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__company_id
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet_line__company_id
+msgid "Company"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,help:sale_payment_sheet.field_sale_payment_sheet__company_id
+#: model:ir.model.fields,help:sale_payment_sheet.field_sale_payment_sheet_line__company_id
+msgid "Company related to this journal"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.view_sale_payment_sheet_form
+msgid "Confirm sheet"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.view_sale_payment_sheet_search
+msgid "Confirmed"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_invoice_payment_wiz__create_uid
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__create_uid
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet_line__create_uid
+msgid "Created by"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_invoice_payment_wiz__create_date
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__create_date
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet_line__create_date
+msgid "Created on"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_invoice_payment_wiz__currency_id
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__currency_id
+msgid "Currency"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__date
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet_line__date
+#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.report_sale_payment_sheet
+#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.view_sale_payment_sheet_search
+msgid "Date"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.report_sale_payment_sheet
+msgid "Description"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_invoice_payment_wiz__display_name
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__display_name
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet_line__display_name
+msgid "Display Name"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.view_sale_payment_sheet_search
+msgid "Draft"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__reference
+msgid "External Reference"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__failed_message_ids
+msgid "Failed Messages"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__message_follower_ids
+msgid "Followers"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__message_channel_ids
+msgid "Followers (Channels)"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__message_partner_ids
+msgid "Followers (Partners)"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields.selection,name:sale_payment_sheet.selection__sale_payment_sheet_line__transaction_type__full
+msgid "Full payment"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,help:sale_payment_sheet.field_sale_payment_sheet_line__sequence
+msgid ""
+"Gives the sequence order when displaying a list of payment sheet lines."
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.view_sale_payment_sheet_search
+msgid "Group By"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_invoice_payment_wiz__id
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__id
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet_line__id
+msgid "ID"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,help:sale_payment_sheet.field_sale_payment_sheet__message_needaction
+#: model:ir.model.fields,help:sale_payment_sheet.field_sale_payment_sheet__message_unread
+msgid "If checked, new messages require your attention."
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,help:sale_payment_sheet.field_sale_payment_sheet__message_has_error
+msgid "If checked, some messages have a delivery error."
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet_line__invoice_id
+#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.report_sale_payment_sheet
+msgid "Invoice"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model:ir.actions.act_window,name:sale_payment_sheet.action_invoice_sale_payment_sheet
+#: model:ir.ui.menu,name:sale_payment_sheet.sale_payment_invoice
+#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.view_invoice_tree
+msgid "Invoices"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__message_is_follower
+msgid "Is Follower"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_invoice_payment_wiz__journal_id
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__journal_id
+#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.view_sale_payment_sheet_search
+msgid "Journal"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet_line__journal_currency_id
+msgid "Journal's Currency"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet_line__name
+msgid "Label"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_invoice_payment_wiz____last_update
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet____last_update
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet_line____last_update
+msgid "Last Modified on"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_invoice_payment_wiz__write_uid
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__write_uid
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet_line__write_uid
+msgid "Last Updated by"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_invoice_payment_wiz__write_date
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__write_date
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet_line__write_date
+msgid "Last Updated on"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__message_main_attachment_id
+msgid "Main Attachment"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__message_content
+msgid "Message Content"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__message_has_error
+msgid "Message Delivery error"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,help:sale_payment_sheet.field_sale_payment_sheet__message_content
+msgid "Message content, to be used only in searches"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__message_ids
+msgid "Messages"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields.selection,name:sale_payment_sheet.selection__sale_payment_sheet__state__open
+msgid "New"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet_line__note
+msgid "Notes"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__message_needaction_counter
+msgid "Number of Actions"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__message_has_error_counter
+msgid "Number of errors"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,help:sale_payment_sheet.field_sale_payment_sheet__message_needaction_counter
+msgid "Number of messages which requires an action"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,help:sale_payment_sheet.field_sale_payment_sheet__message_has_error_counter
+msgid "Number of messages with delivery error"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,help:sale_payment_sheet.field_sale_payment_sheet__message_unread_counter
+msgid "Number of unread messages"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields.selection,name:sale_payment_sheet.selection__sale_payment_sheet_line__transaction_type__partial
+msgid "Partial payment"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet_line__partner_id
+#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.report_sale_payment_sheet
+msgid "Partner"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.sale_invoice_payment_wiz
+msgid "Payment"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.view_sale_payment_sheet_search
+msgid "Payment sheet"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model:ir.ui.menu,name:sale_payment_sheet.sale_payment_sheet_menu
+msgid "Payments"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__name
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet_line__ref
+msgid "Reference"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model_terms:ir.actions.act_window,help:sale_payment_sheet.action_sale_payment_sheet
+msgid "Register a invoice payment (Salesman)"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.view_sale_payment_sheet_form
+msgid "Reset to New"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_invoice_payment_wiz__user_id
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__user_id
+msgid "Responsible"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model:ir.model,name:sale_payment_sheet.model_sale_payment_sheet
+msgid "Sale Payment Sheet"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model:ir.model,name:sale_payment_sheet.model_sale_payment_sheet_line
+msgid "Sale Payment Sheet Line"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model:ir.actions.act_window,name:sale_payment_sheet.action_sale_invoice_payment_wiz
+msgid "Sale invoice payment"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model:ir.model,name:sale_payment_sheet.model_sale_invoice_payment_wiz
+#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.sale_invoice_payment_wiz
+msgid "Sale invoice payment wizard"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.view_sale_payment_sheet_tree
+msgid "Sale invoice payments"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model:ir.actions.act_window,name:sale_payment_sheet.action_sale_payment_sheet
+#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.view_sale_payment_sheet_form
+msgid "Sale payment sheet"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.view_invoice_tree
+msgid "Sales Person"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.view_sale_payment_sheet_search
+msgid "Search sale payment sheets"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet_line__sequence
+msgid "Sequence"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet_line__sheet_id
+msgid "Sheet"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: code:addons/sale_payment_sheet/models/sale_payment_sheet.py:0
+#, python-format
+msgid "Sheet %s confirmed, bank statement were created."
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__line_ids
+#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.view_sale_payment_sheet_form
+msgid "Sheet lines"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet_line__statement_line_id
+msgid "Statement Line"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__state
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet_line__state
+#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.view_sale_payment_sheet_search
+msgid "Status"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.view_invoice_tree
+msgid "Tax Excluded"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: code:addons/sale_payment_sheet/models/sale_payment_sheet.py:0
+#, python-format
+msgid "The amount of a cash transaction cannot be 0."
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.view_invoice_tree
+#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.view_sale_payment_sheet_form
+msgid "Total"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.view_invoice_tree
+msgid "Total Amount"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet_line__transaction_type
+msgid "Transaction type"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.view_sale_payment_sheet_form
+msgid "Transactions"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__message_unread
+msgid "Unread Messages"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__message_unread_counter
+msgid "Unread Messages Counter"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model:ir.model,name:sale_payment_sheet.model_res_users
+msgid "Users"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,help:sale_payment_sheet.field_sale_payment_sheet_line__journal_currency_id
+msgid "Utility field to express amount currency"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields.selection,name:sale_payment_sheet.selection__sale_payment_sheet__state__confirm
+msgid "Validated"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__website_message_ids
+msgid "Website Messages"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model:ir.model.fields,help:sale_payment_sheet.field_sale_payment_sheet__website_message_ids
+msgid "Website communication history"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: code:addons/sale_payment_sheet/models/sale_payment_sheet.py:0
+#, python-format
+msgid "You can not delete a sheet if has related journal items."
+msgstr ""
+
+#. module: sale_payment_sheet
+#: code:addons/sale_payment_sheet/models/sale_payment_sheet.py:0
+#, python-format
+msgid "You can not delete payment lines if have related statement lines."
+msgstr ""
+
+#. module: sale_payment_sheet
+#: code:addons/sale_payment_sheet/models/sale_payment_sheet.py:0
+#, python-format
+msgid "You can not reopen a sheet that has any reconciled line."
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.view_users_form
+msgid "sale payment sheet"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.report_sale_payment_sheet
+msgid "sale payment sheet Summary"
+msgstr ""
+
+#. module: sale_payment_sheet
+#: model:ir.actions.report,name:sale_payment_sheet.action_report_sale_payment_sheet
+msgid "sale payment sheet summary"
+msgstr ""
diff --git a/sale_payment_sheet/models/__init__.py b/sale_payment_sheet/models/__init__.py
new file mode 100644
index 00000000000..3a56ee3e8b4
--- /dev/null
+++ b/sale_payment_sheet/models/__init__.py
@@ -0,0 +1,3 @@
+# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
+from . import res_users
+from . import sale_payment_sheet
diff --git a/sale_payment_sheet/models/res_users.py b/sale_payment_sheet/models/res_users.py
new file mode 100644
index 00000000000..dc7e5a3798c
--- /dev/null
+++ b/sale_payment_sheet/models/res_users.py
@@ -0,0 +1,13 @@
+# Copyright 2020 Tecnativa - Carlos Dauden
+# Copyright 2020 Tecnativa - Sergio Teruel
+# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
+
+from odoo import fields, models
+
+
+class ResUsers(models.Model):
+ _inherit = "res.users"
+
+ commercial_journal_ids = fields.Many2many(
+ comodel_name="account.journal", string="Allowed journals for commercial",
+ )
diff --git a/sale_payment_sheet/models/sale_payment_sheet.py b/sale_payment_sheet/models/sale_payment_sheet.py
new file mode 100644
index 00000000000..f2888aa2a71
--- /dev/null
+++ b/sale_payment_sheet/models/sale_payment_sheet.py
@@ -0,0 +1,279 @@
+# Copyright 2020 Tecnativa - Carlos Dauden
+# Copyright 2020 Tecnativa - Sergio Teruel
+# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
+
+from odoo import _, api, fields, models
+from odoo.exceptions import UserError, ValidationError
+from odoo.tools import float_compare
+
+
+class SalePaymentSheet(models.Model):
+ _name = "sale.payment.sheet"
+ _description = "Sale Payment Sheet"
+ _order = "date desc, id desc"
+ _inherit = ["mail.thread"]
+ _check_company_auto = True
+
+ name = fields.Char(
+ string="Reference",
+ states={"open": [("readonly", False)]},
+ copy=False,
+ compute="_compute_name",
+ readonly=True,
+ store=True,
+ )
+ reference = fields.Char(
+ string="External Reference",
+ states={"open": [("readonly", False)]},
+ copy=False,
+ readonly=True,
+ )
+ date = fields.Date(
+ required=True,
+ states={"confirm": [("readonly", True)]},
+ index=True,
+ copy=False,
+ default=fields.Date.context_today,
+ )
+ state = fields.Selection(
+ [("open", "New"), ("confirm", "Validated")],
+ string="Status",
+ required=True,
+ readonly=True,
+ copy=False,
+ default="open",
+ )
+ currency_id = fields.Many2one(
+ "res.currency", compute="_compute_currency", string="Currency"
+ )
+ journal_id = fields.Many2one(
+ "account.journal",
+ string="Journal",
+ required=True,
+ states={"confirm": [("readonly", True)]},
+ default=lambda self: self._default_journal(),
+ )
+ commercial_journal_ids = fields.Many2many(related="user_id.commercial_journal_ids")
+ company_id = fields.Many2one(
+ "res.company",
+ related="journal_id.company_id",
+ string="Company",
+ store=True,
+ readonly=True,
+ default=lambda self: self.env.company,
+ )
+ line_ids = fields.One2many(
+ "sale.payment.sheet.line",
+ "sheet_id",
+ string="Sheet lines",
+ states={"confirm": [("readonly", True)]},
+ copy=True,
+ )
+ user_id = fields.Many2one(
+ "res.users",
+ string="Responsible",
+ required=False,
+ default=lambda self: self.env.user,
+ )
+ statement_id = fields.Many2one(
+ comodel_name="account.bank.statement", string="Bank statement"
+ )
+
+ @api.model
+ def _default_journal(self):
+ return self.env.user.commercial_journal_ids[:1]
+
+ @api.depends("journal_id.currency_id")
+ def _compute_currency(self):
+ for sheet in self:
+ sheet.currency_id = (
+ sheet.journal_id.currency_id or sheet.company_id.currency_id
+ )
+
+ @api.depends("journal_id", "user_id", "date")
+ def _compute_name(self):
+ for sheet in self:
+ sheet.name = "{} - {} - {}".format(
+ sheet.date and sheet.date.strftime("%Y.%m.%d"),
+ sheet.journal_id.name,
+ sheet.user_id.name,
+ )
+
+ def unlink(self):
+ for sheet in self:
+ if sheet.state != "open":
+ raise UserError(
+ _("You can not delete a sheet if has related journal items.")
+ )
+ return super().unlink()
+
+ def button_confirm_sheet(self):
+ sheets = self.filtered(lambda r: r.state == "open")
+ BankStatement = self.env["account.bank.statement"].sudo()
+ BankStatementLine = self.env["account.bank.statement.line"].sudo()
+ for sheet in sheets:
+ statement = BankStatement.create(
+ {
+ "name": sheet.name,
+ "date": sheet.date,
+ "journal_id": sheet.journal_id.id,
+ "user_id": sheet.user_id.id,
+ }
+ )
+ for line in sheet.line_ids:
+ vals = {
+ "name": line.name,
+ "date": line.date,
+ "amount": line.amount,
+ "partner_id": line.partner_id.id,
+ "ref": line.ref,
+ "note": line.note,
+ "sequence": line.sequence,
+ "statement_id": statement.id,
+ }
+ if line.invoice_id.type == "out_refund" and line.amount > 0.0:
+ # convert to negative amounts if user pays a refund out
+ # invoice with a positive amount.
+ vals["amount"] = -line.amount
+ statement_line = BankStatementLine.create(vals)
+ line.statement_line_id = statement_line
+ sheet.message_post(
+ body=_("Sheet %s confirmed, bank statement were created.")
+ % (statement.name,)
+ )
+ sheet.write({"state": "confirm", "statement_id": statement.id})
+
+ def button_reopen(self):
+ self.ensure_one()
+ self_sudo = self.sudo()
+ if self_sudo.statement_id.line_ids.filtered("journal_entry_ids"):
+ raise UserError(
+ _("You can not reopen a sheet that has any reconciled line.")
+ )
+ self_sudo.statement_id.unlink()
+ self.state = "open"
+
+ def button_bank_statement(self):
+ """
+ Action to open bank statement linked
+ """
+ self.ensure_one()
+ return self.statement_id.get_formview_action()
+
+
+class SalePaymentSheetLine(models.Model):
+ _name = "sale.payment.sheet.line"
+ _description = "Sale Payment Sheet Line"
+ _order = "sheet_id desc, date, sequence, id desc"
+
+ name = fields.Char(
+ string="Label", compute="_compute_name", store=True, readonly=False
+ )
+ date = fields.Date(
+ required=True,
+ default=lambda self: self._context.get("date", fields.Date.context_today(self)),
+ )
+ sheet_id = fields.Many2one(
+ "sale.payment.sheet",
+ string="Sheet",
+ index=True,
+ required=True,
+ ondelete="cascade",
+ )
+ statement_line_id = fields.Many2one(
+ "account.bank.statement.line", string="Statement Line", index=True
+ )
+ amount = fields.Monetary(
+ compute="_compute_amount",
+ inverse="_inverse_amount",
+ currency_field="journal_currency_id",
+ store=True,
+ readonly=False,
+ )
+ journal_currency_id = fields.Many2one(
+ "res.currency",
+ string="Journal's Currency",
+ related="sheet_id.currency_id",
+ help="Utility field to express amount currency",
+ readonly=True,
+ )
+ partner_id = fields.Many2one("res.partner", string="Partner")
+ ref = fields.Char(string="Reference")
+ note = fields.Text(string="Notes")
+ sequence = fields.Integer(
+ index=True,
+ help="Gives the sequence order when displaying a list of payment sheet lines.",
+ default=1,
+ )
+ company_id = fields.Many2one(
+ "res.company",
+ related="sheet_id.company_id",
+ string="Company",
+ store=True,
+ readonly=True,
+ )
+ state = fields.Selection(related="sheet_id.state", string="Status", readonly=True)
+ invoice_id = fields.Many2one(comodel_name="account.move", string="Invoice")
+ transaction_type = fields.Selection(
+ [("partial", "Partial payment"), ("full", "Full payment")],
+ compute="_compute_transaction_type",
+ string="Transaction type",
+ )
+
+ @api.depends("amount", "invoice_id")
+ def _compute_transaction_type(self):
+ for line in self:
+ amount = (
+ line.amount if line.invoice_id.type == "out_invoice" else -line.amount
+ )
+ if float_compare(
+ amount,
+ line.invoice_id.amount_total,
+ precision_digits=line.sheet_id.currency_id.decimal_places,
+ ):
+ line.transaction_type = "partial"
+ else:
+ line.transaction_type = "full"
+
+ @api.depends("sheet_id.user_id", "invoice_id", "transaction_type")
+ def _compute_name(self):
+ for line in self:
+ if not line.create_date:
+ line.create_date = fields.Datetime.now()
+ line.name = "[{}] - {} - {} - ({})".format(
+ fields.Datetime.context_timestamp(line, line.create_date).strftime(
+ "%H:%M"
+ ),
+ line.sheet_id.user_id.name,
+ line.invoice_id.name,
+ dict(
+ line._fields["transaction_type"]._description_selection(line.env)
+ ).get(line.transaction_type),
+ )
+
+ @api.depends("invoice_id")
+ def _compute_amount(self):
+ for line in self:
+ amount = line.invoice_id.amount_residual
+ line.amount = amount if line.invoice_id.type == "out_invoice" else -amount
+
+ def _inverse_amount(self):
+ for line in self:
+ if line.invoice_id.type == "out_refund" and line.amount > 0.0:
+ line.amount = -line.amount
+
+ @api.constrains("amount")
+ def _check_amount(self):
+ for line in self:
+ # Allow to enter sheet line with an amount of 0,
+ if line.journal_currency_id.is_zero(line.amount):
+ raise ValidationError(
+ _("The amount of a cash transaction cannot be 0.")
+ )
+
+ def unlink(self):
+ if self.filtered("statement_line_id"):
+ raise UserError(
+ _("You can not delete payment lines if have related statement lines.")
+ )
+ return super().unlink()
diff --git a/sale_payment_sheet/readme/CONFIGURE.rst b/sale_payment_sheet/readme/CONFIGURE.rst
new file mode 100644
index 00000000000..49371d2be71
--- /dev/null
+++ b/sale_payment_sheet/readme/CONFIGURE.rst
@@ -0,0 +1,4 @@
+To configure this module, you need to:
+
+#. Go to Settings > User and Companies > Users
+#. Select the allowed journals to register payments
diff --git a/sale_payment_sheet/readme/CONTRIBUTORS.rst b/sale_payment_sheet/readme/CONTRIBUTORS.rst
new file mode 100644
index 00000000000..29ec7c3c9da
--- /dev/null
+++ b/sale_payment_sheet/readme/CONTRIBUTORS.rst
@@ -0,0 +1,4 @@
+* `Tecnativa `__:
+
+ * Carlos Dauden
+ * Sergio Teruel
diff --git a/sale_payment_sheet/readme/DESCRIPTION.rst b/sale_payment_sheet/readme/DESCRIPTION.rst
new file mode 100644
index 00000000000..bd730118c39
--- /dev/null
+++ b/sale_payment_sheet/readme/DESCRIPTION.rst
@@ -0,0 +1,2 @@
+This module allows to commercial users register payments in a payment sheet.
+This payment sheet will generate a bank statement when is confirmed.
diff --git a/sale_payment_sheet/readme/USAGE.rst b/sale_payment_sheet/readme/USAGE.rst
new file mode 100644
index 00000000000..9d2ad956007
--- /dev/null
+++ b/sale_payment_sheet/readme/USAGE.rst
@@ -0,0 +1,22 @@
+To use this module, you need to:
+
+Create manual payment sheet:
+
+#. Go to Sales > Orders > Payments.
+#. Create new payment sheet.
+
+You can pay invoices directly, to do this:
+
+#. Go to Sales > Orders > Invoices.
+#. Select some invoices to pay.
+#. Click on Action > Sale invoice payment.
+#. A wizard will be displayed and select journal and put amount that you want
+ to pay.
+
+Payment one invoice:
+
+#. Go to Sales > Orders > Invoices.
+#. Enter to invoice form.
+#. Click "register payment".
+#. A wizard will be displayed and select journal and put amount that you want
+ to pay.
diff --git a/sale_payment_sheet/report/report_sale_payment_sheet_summary.xml b/sale_payment_sheet/report/report_sale_payment_sheet_summary.xml
new file mode 100644
index 00000000000..d5ef327a352
--- /dev/null
+++ b/sale_payment_sheet/report/report_sale_payment_sheet_summary.xml
@@ -0,0 +1,91 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ Date
+ Description
+ Partner
+ Invoice
+ Amount
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Total:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sale_payment_sheet/report/sale_payment_sheet_report.xml b/sale_payment_sheet/report/sale_payment_sheet_report.xml
new file mode 100644
index 00000000000..0af18681581
--- /dev/null
+++ b/sale_payment_sheet/report/sale_payment_sheet_report.xml
@@ -0,0 +1,12 @@
+
+
+
+
diff --git a/sale_payment_sheet/security/ir.model.access.csv b/sale_payment_sheet/security/ir.model.access.csv
new file mode 100644
index 00000000000..6a4d46846de
--- /dev/null
+++ b/sale_payment_sheet/security/ir.model.access.csv
@@ -0,0 +1,5 @@
+id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
+access_sale_payment_sheet_salesman,access_sale_payment_sheet_salesman,model_sale_payment_sheet,sales_team.group_sale_salesman,1,1,1,1
+access_sale_payment_sheet_line_salesman,access_sale_payment_sheet_line_salesman,model_sale_payment_sheet_line,sales_team.group_sale_salesman,1,1,1,1
+access_sale_payment_sheet_accountant,access_sale_payment_sheet_accountant,model_sale_payment_sheet,account.group_account_invoice,1,1,1,1
+access_sale_payment_sheet_line_accountant,access_sale_payment_sheet_line_accountant,model_sale_payment_sheet_line,account.group_account_invoice,1,1,1,1
diff --git a/sale_payment_sheet/security/security.xml b/sale_payment_sheet/security/security.xml
new file mode 100644
index 00000000000..d88c7b81933
--- /dev/null
+++ b/sale_payment_sheet/security/security.xml
@@ -0,0 +1,35 @@
+
+
+ Sale payment sheet multi-company
+
+ ['|',('company_id','=',False),('company_id','in',company_ids)]
+
+
+
+
+
+
+ Sale payment sheet account manager
+
+ []
+
+
+
+
+
+
+
+
+ Sale payment sheet salesman
+
+ [('user_id','=', user.id)]
+
+
+
+
+
+
+
+
diff --git a/sale_payment_sheet/static/description/icon.png b/sale_payment_sheet/static/description/icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..3a0328b516c4980e8e44cdb63fd945757ddd132d
GIT binary patch
literal 9455
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
z
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
Xviia!U7SGha1wx#SCgwmn*{w2TRX*I
literal 0
HcmV?d00001
diff --git a/sale_payment_sheet/static/description/index.html b/sale_payment_sheet/static/description/index.html
new file mode 100644
index 00000000000..1f638f04519
--- /dev/null
+++ b/sale_payment_sheet/static/description/index.html
@@ -0,0 +1,459 @@
+
+
+
+
+
+
+Sale payment sheet
+
+
+
+
+
Sale payment sheet
+
+
+
+
This module allows to commercial users register payments in a payment sheet.
+This payment sheet will generate a bank statement when is confirmed.
+
Table of contents
+
+
+
+
To configure this module, you need to:
+
+Go to Settings > User and Companies > Users
+Select the allowed journals to register payments
+
+
+
+
+
To use this module, you need to:
+
Create manual payment sheet:
+
+Go to Sales > Orders > Payments.
+Create new payment sheet.
+
+
You can pay invoices directly, to do this:
+
+Go to Sales > Orders > Invoices.
+Select some invoices to pay.
+Click on Action > Sale invoice payment.
+A wizard will be displayed and select journal and put amount that you want
+to pay.
+
+
Payment one invoice:
+
+Go to Sales > Orders > Invoices.
+Enter to invoice form.
+Click “register payment”.
+A wizard will be displayed and select journal and put amount that you want
+to pay.
+
+
+
+
+
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.
+
+
+
+
+
+
+
+
This module is maintained by the OCA.
+
+
OCA, or the Odoo Community Association, is a nonprofit organization whose
+mission is to support the collaborative development of Odoo features and
+promote its widespread use.
+
This module is part of the OCA/sale-workflow project on GitHub.
+
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute .
+
+
+
+
+
diff --git a/sale_payment_sheet/tests/__init__.py b/sale_payment_sheet/tests/__init__.py
new file mode 100644
index 00000000000..a66d7145ed6
--- /dev/null
+++ b/sale_payment_sheet/tests/__init__.py
@@ -0,0 +1,3 @@
+# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
+
+from . import test_sale_payment_sheet
diff --git a/sale_payment_sheet/tests/test_sale_payment_sheet.py b/sale_payment_sheet/tests/test_sale_payment_sheet.py
new file mode 100644
index 00000000000..77b990b6417
--- /dev/null
+++ b/sale_payment_sheet/tests/test_sale_payment_sheet.py
@@ -0,0 +1,137 @@
+# Copyright 2020 Tecnativa - Carlos Dauden
+# Copyright 2020 Tecnativa - Sergio Teruel
+# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
+
+from odoo import fields
+from odoo.exceptions import UserError
+from odoo.tests import Form, SavepointCase
+
+
+class TestSaleInvoicePayment(SavepointCase):
+ @classmethod
+ def setUpClass(cls):
+ super().setUpClass()
+ cls.wizard_obj = cls.env["sale.invoice.payment.wiz"]
+ cls.SalePaymentSheet = cls.env["sale.payment.sheet"]
+ cls.partner = cls.env["res.partner"].create({"name": "Test partner"})
+ cls.bank_journal = cls.env["account.journal"].create(
+ {"name": "Bank journal", "type": "bank", "code": "test"}
+ )
+ account_type_income = cls.env.ref("account.data_account_type_revenue")
+ cls.account_invoice = cls.env["account.account"].create(
+ {
+ "code": "test",
+ "name": "Test account",
+ "user_type_id": account_type_income.id,
+ }
+ )
+ cls.invoice1 = cls._create_invoice(cls)
+ cls.invoice2 = cls._create_invoice(cls)
+ (cls.invoice1 + cls.invoice2).action_post()
+
+ def _create_invoice(self):
+ with Form(
+ self.env["account.move"].with_context(default_type="out_invoice")
+ ) as invoice_form:
+ invoice_form.partner_id = self.partner
+ with invoice_form.invoice_line_ids.new() as line_form:
+ line_form.name = "invoice test"
+ line_form.account_id = self.account_invoice
+ line_form.quantity = 1.0
+ line_form.price_unit = 100.00
+ return invoice_form.save()
+
+ def test_payment_wizard(self):
+ PaymentWiz = self.env["sale.invoice.payment.wiz"].with_context(
+ active_model="account.move", active_ids=(self.invoice1 + self.invoice2).ids,
+ )
+ with Form(PaymentWiz) as wiz_form:
+ wiz_form.journal_id = self.bank_journal
+ wiz_form.amount = 150.00
+ wiz = wiz_form.save()
+ sheet = wiz.create_sale_invoice_payment_sheet()
+ self.assertEqual(len(sheet.line_ids), 2)
+ line_partial_payment = sheet.line_ids.filtered(
+ lambda ln: ln.transaction_type == "partial"
+ )
+ self.assertTrue(line_partial_payment)
+ self.assertEqual(line_partial_payment.invoice_id, self.invoice2)
+ line_full_payment = sheet.line_ids.filtered(
+ lambda ln: ln.transaction_type == "full"
+ )
+ self.assertTrue(line_full_payment)
+ self.assertEqual(line_full_payment.invoice_id, self.invoice1)
+
+ def _create_payment_sheet(self):
+ with Form(self.SalePaymentSheet) as sheet_form:
+ sheet_form.journal_id = self.bank_journal
+ for index, invoice in enumerate(self.invoice1 + self.invoice2):
+ with sheet_form.line_ids.new() as line_sheet:
+ line_sheet.partner_id = self.partner
+ line_sheet.invoice_id = invoice
+ # Only write for partial amount payed, by default the
+ # amount line is total amount residual
+ if index > 0:
+ line_sheet.amount = 50.0
+ return sheet_form.save()
+
+ def test_manual_payment_sheet(self):
+ sheet = self._create_payment_sheet()
+ self.assertEqual(len(sheet.line_ids), 2)
+ line_partial_payment = sheet.line_ids.filtered(
+ lambda ln: ln.transaction_type == "partial"
+ )
+ self.assertTrue(line_partial_payment)
+ self.assertEqual(line_partial_payment.invoice_id, self.invoice2)
+ line_full_payment = sheet.line_ids.filtered(
+ lambda ln: ln.transaction_type == "full"
+ )
+ self.assertTrue(line_full_payment)
+ self.assertEqual(line_full_payment.invoice_id, self.invoice1)
+ self.assertEqual(
+ sheet.name,
+ "{} - {} - {}".format(
+ sheet.date.strftime("%Y.%m.%d"),
+ sheet.journal_id.name,
+ sheet.user_id.name,
+ ),
+ )
+ self.assertEqual(
+ line_partial_payment.name,
+ "[{}] - {} - {} - ({})".format(
+ fields.Datetime.context_timestamp(
+ line_partial_payment, line_partial_payment.create_date
+ ).strftime("%H:%M"),
+ line_partial_payment.sheet_id.user_id.name,
+ line_partial_payment.invoice_id.name,
+ dict(
+ line_partial_payment._fields[
+ "transaction_type"
+ ]._description_selection(line_partial_payment.env)
+ ).get(line_partial_payment.transaction_type),
+ ),
+ )
+
+ def test_payment_sheet_confirm(self):
+ sheet = self._create_payment_sheet()
+ sheet.button_confirm_sheet()
+ self.assertTrue(sheet.statement_id)
+ self.assertEqual(len(sheet.line_ids.mapped("statement_line_id")), 2)
+
+ def test_payment_sheet_reopen(self):
+ sheet = self._create_payment_sheet()
+ sheet.button_confirm_sheet()
+ sheet.button_reopen()
+ self.assertFalse(sheet.statement_id)
+
+ def test_payment_sheet_unlink(self):
+ sheet = self._create_payment_sheet()
+ sheet.button_confirm_sheet()
+ with self.assertRaises(UserError):
+ sheet.unlink()
+
+ def test_payment_sheet_line_unlink(self):
+ sheet = self._create_payment_sheet()
+ sheet.button_confirm_sheet()
+ with self.assertRaises(UserError):
+ sheet.line_ids.unlink()
diff --git a/sale_payment_sheet/views/res_users_views.xml b/sale_payment_sheet/views/res_users_views.xml
new file mode 100644
index 00000000000..88a9cb489b2
--- /dev/null
+++ b/sale_payment_sheet/views/res_users_views.xml
@@ -0,0 +1,16 @@
+
+
+
+ res.users
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sale_payment_sheet/views/sale_payment_sheet_menu.xml b/sale_payment_sheet/views/sale_payment_sheet_menu.xml
new file mode 100644
index 00000000000..0fd2d2a8151
--- /dev/null
+++ b/sale_payment_sheet/views/sale_payment_sheet_menu.xml
@@ -0,0 +1,70 @@
+
+
+
+
+ sale.payment.sheet.account.invoice.tree
+ account.move
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Invoices
+ account.move
+ tree,form
+
+ [
+ ('state', '=', 'posted'),
+ ('type', 'in', ['out_invoice', 'out_refund'])]
+ {
+ 'default_type':'out_invoice',
+ 'type':'out_invoice',
+ 'journal_type': 'sale',
+ 'search_default_in_payment': True,
+ 'search_default_unpaid': True,
+ }
+
+
+
+
+
diff --git a/sale_payment_sheet/views/sale_payment_sheet_views.xml b/sale_payment_sheet/views/sale_payment_sheet_views.xml
new file mode 100644
index 00000000000..310981f4e93
--- /dev/null
+++ b/sale_payment_sheet/views/sale_payment_sheet_views.xml
@@ -0,0 +1,170 @@
+
+
+
+ sale.payment.sheet.tree
+ sale.payment.sheet
+
+
+
+
+
+
+
+
+
+
+
+
+ sale.payment.sheet.search
+ sale.payment.sheet
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ sale.payment.sheet.form
+ sale.payment.sheet
+ 1
+
+
+
+
+
+ Sale payment sheet
+ sale.payment.sheet
+ tree,form
+ []
+ {}
+
+
+
+ Register a invoice payment (Salesman)
+
+
+
+
+
diff --git a/sale_payment_sheet/wizards/__init__.py b/sale_payment_sheet/wizards/__init__.py
new file mode 100644
index 00000000000..b2756b3b8e6
--- /dev/null
+++ b/sale_payment_sheet/wizards/__init__.py
@@ -0,0 +1,3 @@
+# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
+
+from . import sale_invoice_payment
diff --git a/sale_payment_sheet/wizards/sale_invoice_payment.py b/sale_payment_sheet/wizards/sale_invoice_payment.py
new file mode 100644
index 00000000000..4349bba8325
--- /dev/null
+++ b/sale_payment_sheet/wizards/sale_invoice_payment.py
@@ -0,0 +1,95 @@
+# Copyright 2020 Tecnativa - Carlos Dauden
+# Copyright 2020 Tecnativa - Sergio Teruel
+# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
+
+from odoo import api, fields, models
+
+
+class SaleInvoicePaymentWiz(models.TransientModel):
+ _name = "sale.invoice.payment.wiz"
+ _description = "Sale invoice payment wizard"
+
+ user_id = fields.Many2one(
+ "res.users",
+ string="Responsible",
+ required=False,
+ default=lambda self: self.env.user,
+ )
+ commercial_journal_ids = fields.Many2many(related="user_id.commercial_journal_ids")
+ currency_id = fields.Many2one(
+ "res.currency", compute="_compute_currency", string="Currency"
+ )
+ journal_id = fields.Many2one(
+ comodel_name="account.journal", string="Journal", required=True,
+ )
+ amount = fields.Monetary(
+ currency_field="currency_id", string="Amount", required=True,
+ )
+
+ @api.model
+ def default_get(self, fields_list):
+ res = super(SaleInvoicePaymentWiz, self).default_get(fields_list)
+ invoices = self.env["account.move"].browse(self.env.context.get("active_ids"))
+ res["amount"] = sum(invoices.mapped("amount_residual"))
+ return res
+
+ @api.depends("journal_id")
+ def _compute_currency(self):
+ for wiz in self:
+ wiz.currency_id = wiz.journal_id.currency_id
+
+ def create_sale_invoice_payment_sheet(self):
+ invoices = (
+ self.env["account.move"]
+ .browse(self.env.context.get("active_ids"))
+ .filtered(
+ lambda inv: inv.state == "posted"
+ and inv.invoice_payment_state != "paid"
+ )
+ )
+ if not invoices:
+ return
+ # Search an open payment sheet or create one if not exists
+ SalePaymentSheet = self.env["sale.payment.sheet"]
+ sheet = SalePaymentSheet.search(
+ [
+ ("state", "=", "open"),
+ ("user_id", "=", self.env.user.id),
+ ("journal_id", "=", self.journal_id.id),
+ ("date", "=", fields.Date.today()),
+ ]
+ )
+ if not sheet:
+ sheet = SalePaymentSheet.create(
+ {
+ "user_id": self.env.user.id,
+ "journal_id": self.journal_id.id,
+ "date": fields.Date.today(),
+ }
+ )
+ for invoice in invoices:
+ if not self.amount:
+ break
+ sheet_line = sheet.line_ids.filtered(lambda ln: ln.invoice_id == invoice)
+ amount_pay = (
+ invoice.amount_residual
+ if self.amount >= invoice.amount_residual
+ else self.amount
+ )
+ # TODO: What to do if a line has been finded
+ if sheet_line:
+ sheet_line.amount = amount_pay
+ else:
+ sheet.line_ids = [
+ (
+ 0,
+ 0,
+ {
+ "amount": amount_pay,
+ "partner_id": invoice.partner_id.id,
+ "invoice_id": invoice.id,
+ },
+ )
+ ]
+ self.amount -= amount_pay
+ return sheet
diff --git a/sale_payment_sheet/wizards/sale_invoice_payment_view.xml b/sale_payment_sheet/wizards/sale_invoice_payment_view.xml
new file mode 100644
index 00000000000..0df6c7f089e
--- /dev/null
+++ b/sale_payment_sheet/wizards/sale_invoice_payment_view.xml
@@ -0,0 +1,38 @@
+
+
+
+ Sale invoice payment wizard
+ sale.invoice.payment.wiz
+
+
+
+
+
+
From 03113ad0e18f44b11a1521a52cc467a6e6aca059 Mon Sep 17 00:00:00 2001
From: sergio-teruel
Date: Wed, 24 Feb 2021 22:19:42 +0100
Subject: [PATCH 02/20] [ADD] sale_payment_sheet: Allow add refund invoices to
payment sheets
---
.../tests/test_sale_payment_sheet.py | 3 +-
.../wizards/sale_invoice_payment.py | 42 ++++++++++++++-----
2 files changed, 34 insertions(+), 11 deletions(-)
diff --git a/sale_payment_sheet/tests/test_sale_payment_sheet.py b/sale_payment_sheet/tests/test_sale_payment_sheet.py
index 77b990b6417..71cbf35a9ff 100644
--- a/sale_payment_sheet/tests/test_sale_payment_sheet.py
+++ b/sale_payment_sheet/tests/test_sale_payment_sheet.py
@@ -49,7 +49,8 @@ def test_payment_wizard(self):
wiz_form.journal_id = self.bank_journal
wiz_form.amount = 150.00
wiz = wiz_form.save()
- sheet = wiz.create_sale_invoice_payment_sheet()
+ action = wiz.create_sale_invoice_payment_sheet()
+ sheet = self.SalePaymentSheet.browse(action["res_id"])
self.assertEqual(len(sheet.line_ids), 2)
line_partial_payment = sheet.line_ids.filtered(
lambda ln: ln.transaction_type == "partial"
diff --git a/sale_payment_sheet/wizards/sale_invoice_payment.py b/sale_payment_sheet/wizards/sale_invoice_payment.py
index 4349bba8325..6038c6b31e3 100644
--- a/sale_payment_sheet/wizards/sale_invoice_payment.py
+++ b/sale_payment_sheet/wizards/sale_invoice_payment.py
@@ -30,7 +30,13 @@ class SaleInvoicePaymentWiz(models.TransientModel):
def default_get(self, fields_list):
res = super(SaleInvoicePaymentWiz, self).default_get(fields_list)
invoices = self.env["account.move"].browse(self.env.context.get("active_ids"))
- res["amount"] = sum(invoices.mapped("amount_residual"))
+ res["journal_id"] = self.env.user.commercial_journal_ids[:1].id
+ res["amount"] = 0.0
+ for invoice in invoices:
+ if invoice.type == "out_refund":
+ res["amount"] -= invoice.amount_residual
+ else:
+ res["amount"] += invoice.amount_residual
return res
@api.depends("journal_id")
@@ -67,16 +73,33 @@ def create_sale_invoice_payment_sheet(self):
"date": fields.Date.today(),
}
)
- for invoice in invoices:
- if not self.amount:
- break
- sheet_line = sheet.line_ids.filtered(lambda ln: ln.invoice_id == invoice)
+ # First process refund invoices su summarize negative amounts
+ for invoice in invoices.filtered(lambda inv: inv.type == "out_refund"):
+ self._process_invoice(sheet, invoice)
+
+ for invoice in invoices.filtered(lambda inv: inv.type == "out_invoice").sorted(
+ key=lambda x: (x.date, x.id)
+ ):
+ self._process_invoice(sheet, invoice)
+ return sheet.get_formview_action()
+
+ def _process_invoice(self, sheet, invoice):
+ sheet_line = sheet.line_ids.filtered(lambda ln: ln.invoice_id == invoice)
+ invoice_amount_residual = (
+ invoice.amount_residual
+ if invoice.type == "out_invoice"
+ else -invoice.amount_residual
+ )
+ amount_pay = 0.0
+ if self.amount > 0:
amount_pay = (
- invoice.amount_residual
- if self.amount >= invoice.amount_residual
+ invoice_amount_residual
+ if self.amount >= invoice_amount_residual
else self.amount
)
- # TODO: What to do if a line has been finded
+ elif invoice.type == "out_refund":
+ amount_pay = invoice_amount_residual
+ if amount_pay:
if sheet_line:
sheet_line.amount = amount_pay
else:
@@ -91,5 +114,4 @@ def create_sale_invoice_payment_sheet(self):
},
)
]
- self.amount -= amount_pay
- return sheet
+ self.amount -= amount_pay
From 3a8aec0aed1f365aa83d1751f56b0136d0818e83 Mon Sep 17 00:00:00 2001
From: sergio-teruel
Date: Tue, 27 Apr 2021 20:02:43 +0200
Subject: [PATCH 03/20] [ADD] sale_payment_sheet: Add total amount in tree view
TT29429
---
sale_payment_sheet/i18n/es.po | 5 +++--
sale_payment_sheet/i18n/sale_payment_sheet.pot | 5 +++--
sale_payment_sheet/models/sale_payment_sheet.py | 15 ++++++++++++++-
.../tests/test_sale_payment_sheet.py | 1 +
.../views/sale_payment_sheet_views.xml | 1 +
5 files changed, 22 insertions(+), 5 deletions(-)
diff --git a/sale_payment_sheet/i18n/es.po b/sale_payment_sheet/i18n/es.po
index 49475286ea6..a87a3bbba2c 100644
--- a/sale_payment_sheet/i18n/es.po
+++ b/sale_payment_sheet/i18n/es.po
@@ -6,8 +6,8 @@ msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 13.0\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-02-09 08:37+0000\n"
-"PO-Revision-Date: 2021-02-09 09:39+0100\n"
+"POT-Creation-Date: 2021-04-27 17:57+0000\n"
+"PO-Revision-Date: 2021-04-27 19:57+0200\n"
"Last-Translator: Sergio Teruel \n"
"Language-Team: \n"
"Language: es\n"
@@ -456,6 +456,7 @@ msgid "The amount of a cash transaction cannot be 0."
msgstr "El importe de una transacción en efectivo no puede ser 0."
#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__amount_total
#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.view_invoice_tree
#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.view_sale_payment_sheet_form
msgid "Total"
diff --git a/sale_payment_sheet/i18n/sale_payment_sheet.pot b/sale_payment_sheet/i18n/sale_payment_sheet.pot
index a8a5776f85b..99fb5304593 100644
--- a/sale_payment_sheet/i18n/sale_payment_sheet.pot
+++ b/sale_payment_sheet/i18n/sale_payment_sheet.pot
@@ -6,8 +6,8 @@ msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 13.0\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-02-09 08:37+0000\n"
-"PO-Revision-Date: 2021-02-09 08:37+0000\n"
+"POT-Creation-Date: 2021-04-27 17:57+0000\n"
+"PO-Revision-Date: 2021-04-27 17:57+0000\n"
"Last-Translator: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
@@ -453,6 +453,7 @@ msgid "The amount of a cash transaction cannot be 0."
msgstr ""
#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__amount_total
#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.view_invoice_tree
#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.view_sale_payment_sheet_form
msgid "Total"
diff --git a/sale_payment_sheet/models/sale_payment_sheet.py b/sale_payment_sheet/models/sale_payment_sheet.py
index f2888aa2a71..b5b4165da7d 100644
--- a/sale_payment_sheet/models/sale_payment_sheet.py
+++ b/sale_payment_sheet/models/sale_payment_sheet.py
@@ -78,6 +78,17 @@ class SalePaymentSheet(models.Model):
statement_id = fields.Many2one(
comodel_name="account.bank.statement", string="Bank statement"
)
+ amount_total = fields.Monetary(
+ string="Total", store=True, readonly=True, compute="_compute_amount_total"
+ )
+
+ @api.depends("line_ids.amount")
+ def _compute_amount_total(self):
+ """ Summarize total amount lines, this field already is signed
+ depending on invoice type.
+ """
+ for sheet in self:
+ sheet.amount_total = sum(sheet.line_ids.mapped("amount"))
@api.model
def _default_journal(self):
@@ -171,7 +182,9 @@ class SalePaymentSheetLine(models.Model):
)
date = fields.Date(
required=True,
- default=lambda self: self._context.get("date", fields.Date.context_today(self)),
+ default=lambda self: self.env.context.get(
+ "date", fields.Date.context_today(self)
+ ),
)
sheet_id = fields.Many2one(
"sale.payment.sheet",
diff --git a/sale_payment_sheet/tests/test_sale_payment_sheet.py b/sale_payment_sheet/tests/test_sale_payment_sheet.py
index 71cbf35a9ff..1402cbeee28 100644
--- a/sale_payment_sheet/tests/test_sale_payment_sheet.py
+++ b/sale_payment_sheet/tests/test_sale_payment_sheet.py
@@ -62,6 +62,7 @@ def test_payment_wizard(self):
)
self.assertTrue(line_full_payment)
self.assertEqual(line_full_payment.invoice_id, self.invoice1)
+ self.assertEqual(sheet.amount_total, 150.00)
def _create_payment_sheet(self):
with Form(self.SalePaymentSheet) as sheet_form:
diff --git a/sale_payment_sheet/views/sale_payment_sheet_views.xml b/sale_payment_sheet/views/sale_payment_sheet_views.xml
index 310981f4e93..d216005abf0 100644
--- a/sale_payment_sheet/views/sale_payment_sheet_views.xml
+++ b/sale_payment_sheet/views/sale_payment_sheet_views.xml
@@ -8,6 +8,7 @@
+
From 143716b64a6373d4e2bc4f86340df97158c86e2a Mon Sep 17 00:00:00 2001
From: sergio-teruel
Date: Wed, 5 May 2021 16:03:17 +0200
Subject: [PATCH 04/20] [IMP] sale_payment_sheet: Allow to group statement
lines by reference TT29569
---
sale_payment_sheet/i18n/es.po | 14 ++++--
.../i18n/sale_payment_sheet.pot | 11 ++++-
.../models/sale_payment_sheet.py | 48 ++++++++++++++-----
.../views/sale_payment_sheet_views.xml | 1 +
.../wizards/sale_invoice_payment.py | 7 ++-
.../wizards/sale_invoice_payment_view.xml | 1 +
6 files changed, 62 insertions(+), 20 deletions(-)
diff --git a/sale_payment_sheet/i18n/es.po b/sale_payment_sheet/i18n/es.po
index a87a3bbba2c..35e5f94c73f 100644
--- a/sale_payment_sheet/i18n/es.po
+++ b/sale_payment_sheet/i18n/es.po
@@ -6,8 +6,8 @@ msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 13.0\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-04-27 17:57+0000\n"
-"PO-Revision-Date: 2021-04-27 19:57+0200\n"
+"POT-Creation-Date: 2021-05-05 13:54+0000\n"
+"PO-Revision-Date: 2021-05-05 15:58+0200\n"
"Last-Translator: Sergio Teruel \n"
"Language-Team: \n"
"Language: es\n"
@@ -186,6 +186,11 @@ msgstr ""
msgid "Group By"
msgstr "Agrupado por..."
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__group_lines
+msgid "Group statement lines by"
+msgstr "Agrupar Líneas del extracto bancario por"
+
#. module: sale_payment_sheet
#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_invoice_payment_wiz__id
#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__id
@@ -347,8 +352,10 @@ msgid "Payments"
msgstr "Pagos"
#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_invoice_payment_wiz__ref
#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__name
#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet_line__ref
+#: model:ir.model.fields.selection,name:sale_payment_sheet.selection__sale_payment_sheet__group_lines__ref
msgid "Reference"
msgstr "Referencia"
@@ -547,6 +554,3 @@ msgstr "Resumen de pagos de facturas"
#: model:ir.actions.report,name:sale_payment_sheet.action_report_sale_payment_sheet
msgid "sale payment sheet summary"
msgstr "Resumen de pagos de facturas"
-
-#~ msgid "Journal Entries"
-#~ msgstr "Asientos contables"
diff --git a/sale_payment_sheet/i18n/sale_payment_sheet.pot b/sale_payment_sheet/i18n/sale_payment_sheet.pot
index 99fb5304593..f9f1874a0d1 100644
--- a/sale_payment_sheet/i18n/sale_payment_sheet.pot
+++ b/sale_payment_sheet/i18n/sale_payment_sheet.pot
@@ -6,8 +6,8 @@ msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 13.0\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-04-27 17:57+0000\n"
-"PO-Revision-Date: 2021-04-27 17:57+0000\n"
+"POT-Creation-Date: 2021-05-05 13:54+0000\n"
+"PO-Revision-Date: 2021-05-05 13:54+0000\n"
"Last-Translator: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
@@ -183,6 +183,11 @@ msgstr ""
msgid "Group By"
msgstr ""
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__group_lines
+msgid "Group statement lines by"
+msgstr ""
+
#. module: sale_payment_sheet
#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_invoice_payment_wiz__id
#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__id
@@ -344,8 +349,10 @@ msgid "Payments"
msgstr ""
#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_invoice_payment_wiz__ref
#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__name
#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet_line__ref
+#: model:ir.model.fields.selection,name:sale_payment_sheet.selection__sale_payment_sheet__group_lines__ref
msgid "Reference"
msgstr ""
diff --git a/sale_payment_sheet/models/sale_payment_sheet.py b/sale_payment_sheet/models/sale_payment_sheet.py
index b5b4165da7d..181c4a0231c 100644
--- a/sale_payment_sheet/models/sale_payment_sheet.py
+++ b/sale_payment_sheet/models/sale_payment_sheet.py
@@ -81,6 +81,9 @@ class SalePaymentSheet(models.Model):
amount_total = fields.Monetary(
string="Total", store=True, readonly=True, compute="_compute_amount_total"
)
+ group_lines = fields.Selection(
+ selection=[("ref", "Reference")], string="Group statement lines by"
+ )
@api.depends("line_ids.amount")
def _compute_amount_total(self):
@@ -118,6 +121,13 @@ def unlink(self):
)
return super().unlink()
+ @api.model
+ def _statement_line_key(self, line):
+ if self.group_lines == "ref":
+ return (line.partner_id.id, line.ref)
+ else:
+ return (line.id,)
+
def button_confirm_sheet(self):
sheets = self.filtered(lambda r: r.state == "open")
BankStatement = self.env["account.bank.statement"].sudo()
@@ -131,23 +141,37 @@ def button_confirm_sheet(self):
"user_id": sheet.user_id.id,
}
)
+ vals_dic = {}
for line in sheet.line_ids:
- vals = {
- "name": line.name,
- "date": line.date,
- "amount": line.amount,
- "partner_id": line.partner_id.id,
- "ref": line.ref,
- "note": line.note,
- "sequence": line.sequence,
- "statement_id": statement.id,
- }
+ key = self._statement_line_key(line)
+
if line.invoice_id.type == "out_refund" and line.amount > 0.0:
# convert to negative amounts if user pays a refund out
# invoice with a positive amount.
- vals["amount"] = -line.amount
+ amount_line = -line.amount
+ else:
+ amount_line = line.amount
+
+ if key not in vals_dic:
+ vals_dic[key] = {
+ "name": line.name,
+ "date": line.date,
+ "amount": amount_line,
+ "partner_id": line.partner_id.id,
+ "ref": line.ref,
+ "note": line.note,
+ "sequence": line.sequence,
+ "statement_id": statement.id,
+ "payment_sheet_line_ids": line,
+ }
+ else:
+ vals_dic[key]["amount"] += amount_line
+ vals_dic[key]["name"] += " {}".format(line.invoice_id.name)
+ vals_dic[key]["payment_sheet_line_ids"] += line
+ for vals in vals_dic.values():
+ payment_sheet_line_ids = vals.pop("payment_sheet_line_ids", None)
statement_line = BankStatementLine.create(vals)
- line.statement_line_id = statement_line
+ payment_sheet_line_ids.statement_line_id = statement_line
sheet.message_post(
body=_("Sheet %s confirmed, bank statement were created.")
% (statement.name,)
diff --git a/sale_payment_sheet/views/sale_payment_sheet_views.xml b/sale_payment_sheet/views/sale_payment_sheet_views.xml
index d216005abf0..8b8d007afa8 100644
--- a/sale_payment_sheet/views/sale_payment_sheet_views.xml
+++ b/sale_payment_sheet/views/sale_payment_sheet_views.xml
@@ -105,6 +105,7 @@
options="{'no_create': True}"
groups="base.group_multi_company"
/>
+
diff --git a/sale_payment_sheet/wizards/sale_invoice_payment.py b/sale_payment_sheet/wizards/sale_invoice_payment.py
index 6038c6b31e3..ceb380e1273 100644
--- a/sale_payment_sheet/wizards/sale_invoice_payment.py
+++ b/sale_payment_sheet/wizards/sale_invoice_payment.py
@@ -25,6 +25,7 @@ class SaleInvoicePaymentWiz(models.TransientModel):
amount = fields.Monetary(
currency_field="currency_id", string="Amount", required=True,
)
+ ref = fields.Char(string="Reference")
@api.model
def default_get(self, fields_list):
@@ -84,12 +85,15 @@ def create_sale_invoice_payment_sheet(self):
return sheet.get_formview_action()
def _process_invoice(self, sheet, invoice):
- sheet_line = sheet.line_ids.filtered(lambda ln: ln.invoice_id == invoice)
+ all_sheet_lines = sheet.line_ids.filtered(lambda ln: ln.invoice_id == invoice)
+ sheet_line = all_sheet_lines.filtered(lambda ln: ln.ref == self.ref)
+ other_lines = all_sheet_lines - sheet_line
invoice_amount_residual = (
invoice.amount_residual
if invoice.type == "out_invoice"
else -invoice.amount_residual
)
+ invoice_amount_residual -= sum(other_lines.mapped("amount"))
amount_pay = 0.0
if self.amount > 0:
amount_pay = (
@@ -111,6 +115,7 @@ def _process_invoice(self, sheet, invoice):
"amount": amount_pay,
"partner_id": invoice.partner_id.id,
"invoice_id": invoice.id,
+ "ref": self.ref,
},
)
]
diff --git a/sale_payment_sheet/wizards/sale_invoice_payment_view.xml b/sale_payment_sheet/wizards/sale_invoice_payment_view.xml
index 0df6c7f089e..6d1fb372556 100644
--- a/sale_payment_sheet/wizards/sale_invoice_payment_view.xml
+++ b/sale_payment_sheet/wizards/sale_invoice_payment_view.xml
@@ -14,6 +14,7 @@
domain="[('id', 'in', commercial_journal_ids)]"
/>
+
Date: Thu, 8 Jul 2021 15:43:06 +0200
Subject: [PATCH 05/20] [ADD] sale_payment_sheet: Avoid take an invoice that it
already is on other payment_sheet and fully payed TT30929
---
sale_payment_sheet/README.rst | 8 +++++
sale_payment_sheet/i18n/es.po | 16 +++++++--
.../i18n/sale_payment_sheet.pot | 33 +++++++++--------
.../models/sale_payment_sheet.py | 36 +++++++++++++++++--
.../static/description/index.html | 2 ++
.../tests/test_sale_payment_sheet.py | 22 +++++++++---
6 files changed, 90 insertions(+), 27 deletions(-)
diff --git a/sale_payment_sheet/README.rst b/sale_payment_sheet/README.rst
index 2e8af10d759..5178ffa99cc 100644
--- a/sale_payment_sheet/README.rst
+++ b/sale_payment_sheet/README.rst
@@ -106,6 +106,14 @@ 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-sergio-teruel| image:: https://github.com/sergio-teruel.png?size=40px
+ :target: https://github.com/sergio-teruel
+ :alt: sergio-teruel
+
+Current `maintainer `__:
+
+|maintainer-sergio-teruel|
+
This module is part of the `OCA/sale-workflow `_ project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
diff --git a/sale_payment_sheet/i18n/es.po b/sale_payment_sheet/i18n/es.po
index 35e5f94c73f..394e4e7b416 100644
--- a/sale_payment_sheet/i18n/es.po
+++ b/sale_payment_sheet/i18n/es.po
@@ -6,8 +6,8 @@ msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 13.0\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-05-05 13:54+0000\n"
-"PO-Revision-Date: 2021-05-05 15:58+0200\n"
+"POT-Creation-Date: 2021-07-15 23:38+0000\n"
+"PO-Revision-Date: 2021-07-16 01:40+0200\n"
"Last-Translator: Sergio Teruel \n"
"Language-Team: \n"
"Language: es\n"
@@ -462,6 +462,18 @@ msgstr "Impuesto no incluido"
msgid "The amount of a cash transaction cannot be 0."
msgstr "El importe de una transacción en efectivo no puede ser 0."
+#. module: sale_payment_sheet
+#: code:addons/sale_payment_sheet/models/sale_payment_sheet.py:0
+#, python-format
+msgid ""
+"This invoice already has been included in other payment sheet or the amount "
+"payed is greather than residual invoice amount.\n"
+" Invoice: %s Amount payed: %s"
+msgstr ""
+"Esta factura ya se ha incluido en otra hoja de pagos o el importe pagado es "
+"mayor al importe pendiente de la factura.\n"
+" Factura: %s Importe pagado: %s"
+
#. module: sale_payment_sheet
#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__amount_total
#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.view_invoice_tree
diff --git a/sale_payment_sheet/i18n/sale_payment_sheet.pot b/sale_payment_sheet/i18n/sale_payment_sheet.pot
index f9f1874a0d1..4a513abed13 100644
--- a/sale_payment_sheet/i18n/sale_payment_sheet.pot
+++ b/sale_payment_sheet/i18n/sale_payment_sheet.pot
@@ -6,8 +6,6 @@ msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 13.0\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-05-05 13:54+0000\n"
-"PO-Revision-Date: 2021-05-05 13:54+0000\n"
"Last-Translator: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
@@ -147,11 +145,6 @@ msgstr ""
msgid "External Reference"
msgstr ""
-#. module: sale_payment_sheet
-#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__failed_message_ids
-msgid "Failed Messages"
-msgstr ""
-
#. module: sale_payment_sheet
#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__message_follower_ids
msgid "Followers"
@@ -203,6 +196,7 @@ msgstr ""
#. module: sale_payment_sheet
#: model:ir.model.fields,help:sale_payment_sheet.field_sale_payment_sheet__message_has_error
+#: model:ir.model.fields,help:sale_payment_sheet.field_sale_payment_sheet__message_has_sms_error
msgid "If checked, some messages have a delivery error."
msgstr ""
@@ -267,21 +261,11 @@ msgstr ""
msgid "Main Attachment"
msgstr ""
-#. module: sale_payment_sheet
-#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__message_content
-msgid "Message Content"
-msgstr ""
-
#. module: sale_payment_sheet
#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__message_has_error
msgid "Message Delivery error"
msgstr ""
-#. module: sale_payment_sheet
-#: model:ir.model.fields,help:sale_payment_sheet.field_sale_payment_sheet__message_content
-msgid "Message content, to be used only in searches"
-msgstr ""
-
#. module: sale_payment_sheet
#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__message_ids
msgid "Messages"
@@ -372,6 +356,11 @@ msgstr ""
msgid "Responsible"
msgstr ""
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__message_has_sms_error
+msgid "SMS Delivery error"
+msgstr ""
+
#. module: sale_payment_sheet
#: model:ir.model,name:sale_payment_sheet.model_sale_payment_sheet
msgid "Sale Payment Sheet"
@@ -459,6 +448,16 @@ msgstr ""
msgid "The amount of a cash transaction cannot be 0."
msgstr ""
+#. module: sale_payment_sheet
+#: code:addons/sale_payment_sheet/models/sale_payment_sheet.py:0
+#, python-format
+msgid ""
+"This invoice already has been included in other payment sheet or the amount payed is greather than residual invoice amount.\n"
+" Invoice: %s\n"
+" Amount payed: %s\n"
+" Payment sheets: %s"
+msgstr ""
+
#. module: sale_payment_sheet
#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__amount_total
#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.view_invoice_tree
diff --git a/sale_payment_sheet/models/sale_payment_sheet.py b/sale_payment_sheet/models/sale_payment_sheet.py
index 181c4a0231c..24814fd7a60 100644
--- a/sale_payment_sheet/models/sale_payment_sheet.py
+++ b/sale_payment_sheet/models/sale_payment_sheet.py
@@ -250,7 +250,9 @@ class SalePaymentSheetLine(models.Model):
readonly=True,
)
state = fields.Selection(related="sheet_id.state", string="Status", readonly=True)
- invoice_id = fields.Many2one(comodel_name="account.move", string="Invoice")
+ invoice_id = fields.Many2one(
+ comodel_name="account.move", string="Invoice", index=True
+ )
transaction_type = fields.Selection(
[("partial", "Partial payment"), ("full", "Full payment")],
compute="_compute_transaction_type",
@@ -299,14 +301,42 @@ def _inverse_amount(self):
if line.invoice_id.type == "out_refund" and line.amount > 0.0:
line.amount = -line.amount
- @api.constrains("amount")
- def _check_amount(self):
+ @api.constrains("invoice_id", "amount")
+ def _check_invoice(self):
for line in self:
# Allow to enter sheet line with an amount of 0,
if line.journal_currency_id.is_zero(line.amount):
raise ValidationError(
_("The amount of a cash transaction cannot be 0.")
)
+ # Do not allow to enter a invoice totally payed more than one time
+ payment_lines = self.search(
+ [
+ ("invoice_id", "=", line.invoice_id.id),
+ ("sheet_id.state", "=", "open"),
+ ]
+ )
+ amount_payed = sum(payment_lines.mapped("amount"))
+ if (
+ float_compare(
+ amount_payed,
+ line.invoice_id.amount_residual,
+ precision_rounding=line.invoice_id.currency_id.rounding,
+ )
+ == 1
+ ):
+ raise ValidationError(
+ _(
+ "This invoice already has been included in other payment sheet"
+ " or the amount payed is greather than residual invoice amount."
+ "\n Invoice: %s\n Amount payed: %s\n Payment sheets: %s"
+ % (
+ line.invoice_id.name,
+ amount_payed,
+ payment_lines.mapped("sheet_id.name"),
+ )
+ )
+ )
def unlink(self):
if self.filtered("statement_line_id"):
diff --git a/sale_payment_sheet/static/description/index.html b/sale_payment_sheet/static/description/index.html
index 1f638f04519..083aeb1c52d 100644
--- a/sale_payment_sheet/static/description/index.html
+++ b/sale_payment_sheet/static/description/index.html
@@ -450,6 +450,8 @@
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 maintainer :
+
This module is part of the OCA/sale-workflow project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute .
diff --git a/sale_payment_sheet/tests/test_sale_payment_sheet.py b/sale_payment_sheet/tests/test_sale_payment_sheet.py
index 1402cbeee28..f3115beff34 100644
--- a/sale_payment_sheet/tests/test_sale_payment_sheet.py
+++ b/sale_payment_sheet/tests/test_sale_payment_sheet.py
@@ -2,15 +2,19 @@
# Copyright 2020 Tecnativa - Sergio Teruel
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
-from odoo import fields
-from odoo.exceptions import UserError
+from freezegun import freeze_time
+
+from odoo.exceptions import UserError, ValidationError
from odoo.tests import Form, SavepointCase
+@freeze_time("2021-01-01 09:30:00")
class TestSaleInvoicePayment(SavepointCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
+ # Remove time zone from user to avoid to time local representation
+ cls.env.user.partner_id.tz = False
cls.wizard_obj = cls.env["sale.invoice.payment.wiz"]
cls.SalePaymentSheet = cls.env["sale.payment.sheet"]
cls.partner = cls.env["res.partner"].create({"name": "Test partner"})
@@ -101,9 +105,7 @@ def test_manual_payment_sheet(self):
self.assertEqual(
line_partial_payment.name,
"[{}] - {} - {} - ({})".format(
- fields.Datetime.context_timestamp(
- line_partial_payment, line_partial_payment.create_date
- ).strftime("%H:%M"),
+ "09:30",
line_partial_payment.sheet_id.user_id.name,
line_partial_payment.invoice_id.name,
dict(
@@ -137,3 +139,13 @@ def test_payment_sheet_line_unlink(self):
sheet.button_confirm_sheet()
with self.assertRaises(UserError):
sheet.line_ids.unlink()
+
+ def test_payment_sheet_invoice_constraint(self):
+ # You can not add full invoice payed more than one time.
+ sheet = self._create_payment_sheet()
+ with self.assertRaises(ValidationError):
+ with Form(sheet) as sheet_form:
+ with sheet_form.line_ids.new() as line_sheet:
+ line_sheet.partner_id = self.partner
+ line_sheet.invoice_id = self.invoice1
+ sheet_form.save()
From 677df207e5f8816a936620526146389b3f822237 Mon Sep 17 00:00:00 2001
From: Cesar Andres Sanchez
Date: Mon, 6 Jun 2022 22:43:57 +0200
Subject: [PATCH 06/20] [IMP] sale_payment_sheet: black, isort, prettier
---
sale_payment_sheet/models/res_users.py | 3 ++-
sale_payment_sheet/models/sale_payment_sheet.py | 2 +-
sale_payment_sheet/tests/test_sale_payment_sheet.py | 3 ++-
sale_payment_sheet/wizards/sale_invoice_payment.py | 8 ++++++--
4 files changed, 11 insertions(+), 5 deletions(-)
diff --git a/sale_payment_sheet/models/res_users.py b/sale_payment_sheet/models/res_users.py
index dc7e5a3798c..e7c83b6f940 100644
--- a/sale_payment_sheet/models/res_users.py
+++ b/sale_payment_sheet/models/res_users.py
@@ -9,5 +9,6 @@ class ResUsers(models.Model):
_inherit = "res.users"
commercial_journal_ids = fields.Many2many(
- comodel_name="account.journal", string="Allowed journals for commercial",
+ comodel_name="account.journal",
+ string="Allowed journals for commercial",
)
diff --git a/sale_payment_sheet/models/sale_payment_sheet.py b/sale_payment_sheet/models/sale_payment_sheet.py
index 24814fd7a60..a9894245b78 100644
--- a/sale_payment_sheet/models/sale_payment_sheet.py
+++ b/sale_payment_sheet/models/sale_payment_sheet.py
@@ -87,7 +87,7 @@ class SalePaymentSheet(models.Model):
@api.depends("line_ids.amount")
def _compute_amount_total(self):
- """ Summarize total amount lines, this field already is signed
+ """Summarize total amount lines, this field already is signed
depending on invoice type.
"""
for sheet in self:
diff --git a/sale_payment_sheet/tests/test_sale_payment_sheet.py b/sale_payment_sheet/tests/test_sale_payment_sheet.py
index f3115beff34..6c621f5266c 100644
--- a/sale_payment_sheet/tests/test_sale_payment_sheet.py
+++ b/sale_payment_sheet/tests/test_sale_payment_sheet.py
@@ -47,7 +47,8 @@ def _create_invoice(self):
def test_payment_wizard(self):
PaymentWiz = self.env["sale.invoice.payment.wiz"].with_context(
- active_model="account.move", active_ids=(self.invoice1 + self.invoice2).ids,
+ active_model="account.move",
+ active_ids=(self.invoice1 + self.invoice2).ids,
)
with Form(PaymentWiz) as wiz_form:
wiz_form.journal_id = self.bank_journal
diff --git a/sale_payment_sheet/wizards/sale_invoice_payment.py b/sale_payment_sheet/wizards/sale_invoice_payment.py
index ceb380e1273..2227214c718 100644
--- a/sale_payment_sheet/wizards/sale_invoice_payment.py
+++ b/sale_payment_sheet/wizards/sale_invoice_payment.py
@@ -20,10 +20,14 @@ class SaleInvoicePaymentWiz(models.TransientModel):
"res.currency", compute="_compute_currency", string="Currency"
)
journal_id = fields.Many2one(
- comodel_name="account.journal", string="Journal", required=True,
+ comodel_name="account.journal",
+ string="Journal",
+ required=True,
)
amount = fields.Monetary(
- currency_field="currency_id", string="Amount", required=True,
+ currency_field="currency_id",
+ string="Amount",
+ required=True,
)
ref = fields.Char(string="Reference")
From 5f08fbf95b246de9f425a58b32b03409c0c4de7a Mon Sep 17 00:00:00 2001
From: Cesar Andres Sanchez
Date: Mon, 6 Jun 2022 22:48:54 +0200
Subject: [PATCH 07/20] [MIG] sale_payment_sheet: Migration to 15.0
---
sale_payment_sheet/README.rst | 11 ++-
sale_payment_sheet/__manifest__.py | 2 +-
sale_payment_sheet/i18n/es.po | 75 ++++++++-----------
.../i18n/sale_payment_sheet.pot | 30 +++-----
.../models/sale_payment_sheet.py | 33 ++++----
sale_payment_sheet/readme/CONTRIBUTORS.rst | 5 +-
sale_payment_sheet/readme/DESCRIPTION.rst | 5 +-
.../tests/test_sale_payment_sheet.py | 7 +-
.../views/sale_payment_sheet_menu.xml | 1 -
.../views/sale_payment_sheet_views.xml | 5 +-
.../wizards/sale_invoice_payment.py | 20 ++---
11 files changed, 92 insertions(+), 102 deletions(-)
diff --git a/sale_payment_sheet/README.rst b/sale_payment_sheet/README.rst
index 5178ffa99cc..f5d968c643a 100644
--- a/sale_payment_sheet/README.rst
+++ b/sale_payment_sheet/README.rst
@@ -23,10 +23,13 @@ Sale payment sheet
:target: https://runbot.odoo-community.org/runbot/167/13.0
:alt: Try me on Runbot
-|badge1| |badge2| |badge3| |badge4| |badge5|
+|badge1| |badge2| |badge3| |badge4| |badge5|
-This module allows to commercial users register payments in a payment sheet.
-This payment sheet will generate a bank statement when is confirmed.
+This module allows salesmen to register payments in a new document called payment sheet, accessible only with the sales permission.
+
+This sheet includes the paid amount, and an optional reference to which invoice(s) is(are) being paid.
+
+This payment sheet will generate a bank statement when confirmed.
**Table of contents**
@@ -112,7 +115,7 @@ promote its widespread use.
Current `maintainer `__:
-|maintainer-sergio-teruel|
+|maintainer-sergio-teruel|
This module is part of the `OCA/sale-workflow `_ project on GitHub.
diff --git a/sale_payment_sheet/__manifest__.py b/sale_payment_sheet/__manifest__.py
index dc449330ede..a9d69468d8f 100644
--- a/sale_payment_sheet/__manifest__.py
+++ b/sale_payment_sheet/__manifest__.py
@@ -5,7 +5,7 @@
"name": "Sale payment sheet",
"summary": "Allow to create invoice payments to commercial users without "
"accounting permissions",
- "version": "13.0.1.0.0",
+ "version": "15.0.1.0.0",
"development_status": "Beta",
"category": "Account",
"website": "https://github.com/OCA/sale-workflow",
diff --git a/sale_payment_sheet/i18n/es.po b/sale_payment_sheet/i18n/es.po
index 394e4e7b416..dae110b2618 100644
--- a/sale_payment_sheet/i18n/es.po
+++ b/sale_payment_sheet/i18n/es.po
@@ -1,21 +1,22 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
+# * sale_order_type
+#
+# This file contains the translation of the following modules:
# * sale_payment_sheet
#
msgid ""
msgstr ""
-"Project-Id-Version: Odoo Server 13.0\n"
+"Project-Id-Version: Odoo Server 15.0\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-07-15 23:38+0000\n"
-"PO-Revision-Date: 2021-07-16 01:40+0200\n"
-"Last-Translator: Sergio Teruel \n"
+"POT-Creation-Date: 2022-06-28 20:48+0000\n"
+"PO-Revision-Date: 2022-06-28 20:48+0000\n"
+"Last-Translator: César A. Sánchez\n"
"Language-Team: \n"
-"Language: es\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-"X-Generator: Poedit 2.3\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
#. module: sale_payment_sheet
#: model:ir.actions.report,print_report_name:sale_payment_sheet.action_report_sale_payment_sheet
@@ -149,21 +150,11 @@ msgstr "Borrador"
msgid "External Reference"
msgstr "Referencia Externa"
-#. module: sale_payment_sheet
-#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__failed_message_ids
-msgid "Failed Messages"
-msgstr "Mensajes Fallidos"
-
#. module: sale_payment_sheet
#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__message_follower_ids
msgid "Followers"
msgstr "Seguidores"
-#. module: sale_payment_sheet
-#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__message_channel_ids
-msgid "Followers (Channels)"
-msgstr "Seguidores (Canales)"
-
#. module: sale_payment_sheet
#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__message_partner_ids
msgid "Followers (Partners)"
@@ -176,7 +167,8 @@ msgstr "Completo"
#. module: sale_payment_sheet
#: model:ir.model.fields,help:sale_payment_sheet.field_sale_payment_sheet_line__sequence
-msgid "Gives the sequence order when displaying a list of payment sheet lines."
+msgid ""
+"Gives the sequence order when displaying a list of payment sheet lines."
msgstr ""
"Indica el orden de secuencia cuando se muestra una lista de líneas de la "
"hoja de pagos."
@@ -191,6 +183,11 @@ msgstr "Agrupado por..."
msgid "Group statement lines by"
msgstr "Agrupar Líneas del extracto bancario por"
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__has_message
+msgid "Has Message"
+msgstr "Tiene mensaje"
+
#. module: sale_payment_sheet
#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_invoice_payment_wiz__id
#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__id
@@ -206,6 +203,7 @@ msgstr "Si está marcado, hay nuevos mensajes que requieren su atención."
#. module: sale_payment_sheet
#: model:ir.model.fields,help:sale_payment_sheet.field_sale_payment_sheet__message_has_error
+#: model:ir.model.fields,help:sale_payment_sheet.field_sale_payment_sheet__message_has_sms_error
msgid "If checked, some messages have a delivery error."
msgstr "Si se encuentra marcado, algunos mensajes tienen error de envío."
@@ -218,7 +216,6 @@ msgstr "Factura"
#. module: sale_payment_sheet
#: model:ir.actions.act_window,name:sale_payment_sheet.action_invoice_sale_payment_sheet
#: model:ir.ui.menu,name:sale_payment_sheet.sale_payment_invoice
-#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.view_invoice_tree
msgid "Invoices"
msgstr "Facturas"
@@ -270,25 +267,15 @@ msgstr "Última actualización en"
msgid "Main Attachment"
msgstr "Adjuntos principales"
-#. module: sale_payment_sheet
-#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__message_content
-msgid "Message Content"
-msgstr "Contenido del mensaje"
-
#. module: sale_payment_sheet
#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__message_has_error
msgid "Message Delivery error"
msgstr "Error de Envío de Mensaje"
-#. module: sale_payment_sheet
-#: model:ir.model.fields,help:sale_payment_sheet.field_sale_payment_sheet__message_content
-msgid "Message content, to be used only in searches"
-msgstr "Contenido del mensaje, para usarse en búsquedas"
-
#. module: sale_payment_sheet
#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__message_ids
msgid "Messages"
-msgstr "Messages"
+msgstr "Mensajes"
#. module: sale_payment_sheet
#: model:ir.model.fields.selection,name:sale_payment_sheet.selection__sale_payment_sheet__state__open
@@ -375,6 +362,11 @@ msgstr "Reestablecer a Nuevo"
msgid "Responsible"
msgstr "Responsable"
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__message_has_sms_error
+msgid "SMS Delivery error"
+msgstr "Error en la entrega del SMS"
+
#. module: sale_payment_sheet
#: model:ir.model,name:sale_payment_sheet.model_sale_payment_sheet
msgid "Sale Payment Sheet"
@@ -396,14 +388,8 @@ msgstr "Pago de facturas"
msgid "Sale invoice payment wizard"
msgstr "Asistente de pago de factura"
-#. module: sale_payment_sheet
-#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.view_sale_payment_sheet_tree
-msgid "Sale invoice payments"
-msgstr "Pagos de facturas"
-
#. module: sale_payment_sheet
#: model:ir.actions.act_window,name:sale_payment_sheet.action_sale_payment_sheet
-#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.view_sale_payment_sheet_form
msgid "Sale payment sheet"
msgstr "Hoja de pagos"
@@ -435,7 +421,6 @@ msgstr "Hoja %s confirmada, se crearon los extractos bancarios."
#. module: sale_payment_sheet
#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__line_ids
-#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.view_sale_payment_sheet_form
msgid "Sheet lines"
msgstr "Líneas"
@@ -466,14 +451,16 @@ msgstr "El importe de una transacción en efectivo no puede ser 0."
#: code:addons/sale_payment_sheet/models/sale_payment_sheet.py:0
#, python-format
msgid ""
-"This invoice already has been included in other payment sheet or the amount "
-"payed is greather than residual invoice amount.\n"
-" Invoice: %s Amount payed: %s"
+"This invoice already has been included in other payment sheet or the amount payed is greather than residual invoice amount.\n"
+" Invoice: %(invoice_name)s\n"
+" Amount payed: %(amount_payed)s\n"
+" Payment sheets: %(payment_lines_name)s"
msgstr ""
"Esta factura ya se ha incluido en otra hoja de pagos o el importe pagado es "
"mayor al importe pendiente de la factura.\n"
-" Factura: %s Importe pagado: %s"
-
+" Factura: %(invoice_name)s\n"
+" Importe pagado: %(amount_payed)s\n"
+" Hojas de pago: %(payment_lines_name)s"
#. module: sale_payment_sheet
#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__amount_total
#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.view_invoice_tree
@@ -488,7 +475,7 @@ msgstr "Importe total"
#. module: sale_payment_sheet
#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet_line__transaction_type
-msgid "Transaction type"
+msgid "Transaction Type"
msgstr "Tipo de transacción"
#. module: sale_payment_sheet
diff --git a/sale_payment_sheet/i18n/sale_payment_sheet.pot b/sale_payment_sheet/i18n/sale_payment_sheet.pot
index 4a513abed13..a21344eacce 100644
--- a/sale_payment_sheet/i18n/sale_payment_sheet.pot
+++ b/sale_payment_sheet/i18n/sale_payment_sheet.pot
@@ -4,8 +4,10 @@
#
msgid ""
msgstr ""
-"Project-Id-Version: Odoo Server 13.0\n"
+"Project-Id-Version: Odoo Server 15.0\n"
"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2022-06-28 20:47+0000\n"
+"PO-Revision-Date: 2022-06-28 20:47+0000\n"
"Last-Translator: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
@@ -150,11 +152,6 @@ msgstr ""
msgid "Followers"
msgstr ""
-#. module: sale_payment_sheet
-#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__message_channel_ids
-msgid "Followers (Channels)"
-msgstr ""
-
#. module: sale_payment_sheet
#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__message_partner_ids
msgid "Followers (Partners)"
@@ -181,6 +178,11 @@ msgstr ""
msgid "Group statement lines by"
msgstr ""
+#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__has_message
+msgid "Has Message"
+msgstr ""
+
#. module: sale_payment_sheet
#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_invoice_payment_wiz__id
#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__id
@@ -209,7 +211,6 @@ msgstr ""
#. module: sale_payment_sheet
#: model:ir.actions.act_window,name:sale_payment_sheet.action_invoice_sale_payment_sheet
#: model:ir.ui.menu,name:sale_payment_sheet.sale_payment_invoice
-#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.view_invoice_tree
msgid "Invoices"
msgstr ""
@@ -382,14 +383,8 @@ msgstr ""
msgid "Sale invoice payment wizard"
msgstr ""
-#. module: sale_payment_sheet
-#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.view_sale_payment_sheet_tree
-msgid "Sale invoice payments"
-msgstr ""
-
#. module: sale_payment_sheet
#: model:ir.actions.act_window,name:sale_payment_sheet.action_sale_payment_sheet
-#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.view_sale_payment_sheet_form
msgid "Sale payment sheet"
msgstr ""
@@ -421,7 +416,6 @@ msgstr ""
#. module: sale_payment_sheet
#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet__line_ids
-#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.view_sale_payment_sheet_form
msgid "Sheet lines"
msgstr ""
@@ -453,9 +447,9 @@ msgstr ""
#, python-format
msgid ""
"This invoice already has been included in other payment sheet or the amount payed is greather than residual invoice amount.\n"
-" Invoice: %s\n"
-" Amount payed: %s\n"
-" Payment sheets: %s"
+" Invoice: %(invoice_name)s\n"
+" Amount payed:%(amount_payed)s\n"
+" Payment sheets: %(payment_lines_name)s"
msgstr ""
#. module: sale_payment_sheet
@@ -472,7 +466,7 @@ msgstr ""
#. module: sale_payment_sheet
#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet_line__transaction_type
-msgid "Transaction type"
+msgid "Transaction Type"
msgstr ""
#. module: sale_payment_sheet
diff --git a/sale_payment_sheet/models/sale_payment_sheet.py b/sale_payment_sheet/models/sale_payment_sheet.py
index a9894245b78..baf25201f09 100644
--- a/sale_payment_sheet/models/sale_payment_sheet.py
+++ b/sale_payment_sheet/models/sale_payment_sheet.py
@@ -145,7 +145,7 @@ def button_confirm_sheet(self):
for line in sheet.line_ids:
key = self._statement_line_key(line)
- if line.invoice_id.type == "out_refund" and line.amount > 0.0:
+ if line.invoice_id.move_type == "out_refund" and line.amount > 0.0:
# convert to negative amounts if user pays a refund out
# invoice with a positive amount.
amount_line = -line.amount
@@ -158,8 +158,7 @@ def button_confirm_sheet(self):
"date": line.date,
"amount": amount_line,
"partner_id": line.partner_id.id,
- "ref": line.ref,
- "note": line.note,
+ "payment_ref": line.ref,
"sequence": line.sequence,
"statement_id": statement.id,
"payment_sheet_line_ids": line,
@@ -181,10 +180,11 @@ def button_confirm_sheet(self):
def button_reopen(self):
self.ensure_one()
self_sudo = self.sudo()
- if self_sudo.statement_id.line_ids.filtered("journal_entry_ids"):
+ if self_sudo.statement_id.line_ids.filtered("is_reconciled"):
raise UserError(
_("You can not reopen a sheet that has any reconciled line.")
)
+ self_sudo.statement_id.button_reopen()
self_sudo.statement_id.unlink()
self.state = "open"
@@ -256,14 +256,15 @@ class SalePaymentSheetLine(models.Model):
transaction_type = fields.Selection(
[("partial", "Partial payment"), ("full", "Full payment")],
compute="_compute_transaction_type",
- string="Transaction type",
)
@api.depends("amount", "invoice_id")
def _compute_transaction_type(self):
for line in self:
amount = (
- line.amount if line.invoice_id.type == "out_invoice" else -line.amount
+ line.amount
+ if line.invoice_id.move_type == "out_invoice"
+ else -line.amount
)
if float_compare(
amount,
@@ -294,11 +295,13 @@ def _compute_name(self):
def _compute_amount(self):
for line in self:
amount = line.invoice_id.amount_residual
- line.amount = amount if line.invoice_id.type == "out_invoice" else -amount
+ line.amount = (
+ amount if line.invoice_id.move_type == "out_invoice" else -amount
+ )
def _inverse_amount(self):
for line in self:
- if line.invoice_id.type == "out_refund" and line.amount > 0.0:
+ if line.invoice_id.move_type == "out_refund" and line.amount > 0.0:
line.amount = -line.amount
@api.constrains("invoice_id", "amount")
@@ -329,13 +332,15 @@ def _check_invoice(self):
_(
"This invoice already has been included in other payment sheet"
" or the amount payed is greather than residual invoice amount."
- "\n Invoice: %s\n Amount payed: %s\n Payment sheets: %s"
- % (
- line.invoice_id.name,
- amount_payed,
- payment_lines.mapped("sheet_id.name"),
- )
+ "\n Invoice: %(invoice_name)s\n Amount payed: "
+ "%(amount_payed)s\n Payment sheets:"
+ " %(payment_lines_name)s"
)
+ % {
+ "invoice_name": line.invoice_id.name,
+ "amount_payed": amount_payed,
+ "payment_lines_name": payment_lines.mapped("sheet_id.name"),
+ }
)
def unlink(self):
diff --git a/sale_payment_sheet/readme/CONTRIBUTORS.rst b/sale_payment_sheet/readme/CONTRIBUTORS.rst
index 29ec7c3c9da..de3f5c32e0d 100644
--- a/sale_payment_sheet/readme/CONTRIBUTORS.rst
+++ b/sale_payment_sheet/readme/CONTRIBUTORS.rst
@@ -1,4 +1,5 @@
* `Tecnativa `__:
- * Carlos Dauden
- * Sergio Teruel
+ * Carlos Dauden
+ * Sergio Teruel
+ * César A. Sánchez
diff --git a/sale_payment_sheet/readme/DESCRIPTION.rst b/sale_payment_sheet/readme/DESCRIPTION.rst
index bd730118c39..ae5e74be178 100644
--- a/sale_payment_sheet/readme/DESCRIPTION.rst
+++ b/sale_payment_sheet/readme/DESCRIPTION.rst
@@ -1,2 +1,3 @@
-This module allows to commercial users register payments in a payment sheet.
-This payment sheet will generate a bank statement when is confirmed.
+This module allows salesmen to register payments in a new document called payment sheet, accessible only with the sales permission.
+This sheet includes the paid amount, and an optional reference to which invoice(s) is(are) being paid.
+This payment sheet will generate a bank statement when confirmed.
diff --git a/sale_payment_sheet/tests/test_sale_payment_sheet.py b/sale_payment_sheet/tests/test_sale_payment_sheet.py
index 6c621f5266c..e25970dd552 100644
--- a/sale_payment_sheet/tests/test_sale_payment_sheet.py
+++ b/sale_payment_sheet/tests/test_sale_payment_sheet.py
@@ -35,7 +35,7 @@ def setUpClass(cls):
def _create_invoice(self):
with Form(
- self.env["account.move"].with_context(default_type="out_invoice")
+ self.env["account.move"].with_context(default_move_type="out_invoice")
) as invoice_form:
invoice_form.partner_id = self.partner
with invoice_form.invoice_line_ids.new() as line_form:
@@ -76,6 +76,7 @@ def _create_payment_sheet(self):
with sheet_form.line_ids.new() as line_sheet:
line_sheet.partner_id = self.partner
line_sheet.invoice_id = invoice
+ line_sheet.ref = "REF{}".format(line_sheet.id)
# Only write for partial amount payed, by default the
# amount line is total amount residual
if index > 0:
@@ -141,6 +142,10 @@ def test_payment_sheet_line_unlink(self):
with self.assertRaises(UserError):
sheet.line_ids.unlink()
+ def test_button_bank_statement(self):
+ sheet = self._create_payment_sheet()
+ sheet.button_bank_statement()
+
def test_payment_sheet_invoice_constraint(self):
# You can not add full invoice payed more than one time.
sheet = self._create_payment_sheet()
diff --git a/sale_payment_sheet/views/sale_payment_sheet_menu.xml b/sale_payment_sheet/views/sale_payment_sheet_menu.xml
index 0fd2d2a8151..f86373c7e6c 100644
--- a/sale_payment_sheet/views/sale_payment_sheet_menu.xml
+++ b/sale_payment_sheet/views/sale_payment_sheet_menu.xml
@@ -9,7 +9,6 @@
account.move
diff --git a/sale_payment_sheet/views/sale_payment_sheet_views.xml b/sale_payment_sheet/views/sale_payment_sheet_views.xml
index 8b8d007afa8..ecd7fe301dc 100644
--- a/sale_payment_sheet/views/sale_payment_sheet_views.xml
+++ b/sale_payment_sheet/views/sale_payment_sheet_views.xml
@@ -4,7 +4,7 @@
sale.payment.sheet.tree
sale.payment.sheet
-
+
@@ -50,7 +50,7 @@
sale.payment.sheet
1
-
-
+
+ Sale invoice payment
+ sale.invoice.payment.wiz
+
+ form
+ new
+
+
From 1f5de3b714b1911a1d4fdefb4705463d03609d70 Mon Sep 17 00:00:00 2001
From: sergio-teruel
Date: Sun, 21 Aug 2022 12:31:29 +0200
Subject: [PATCH 09/20] [FIX] sale_payment_sheet: Fix to v15
---
sale_payment_sheet/models/sale_payment_sheet.py | 2 +-
sale_payment_sheet/security/ir.model.access.csv | 1 +
sale_payment_sheet/views/sale_payment_sheet_menu.xml | 6 +++---
3 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/sale_payment_sheet/models/sale_payment_sheet.py b/sale_payment_sheet/models/sale_payment_sheet.py
index baf25201f09..2ab1cd54935 100644
--- a/sale_payment_sheet/models/sale_payment_sheet.py
+++ b/sale_payment_sheet/models/sale_payment_sheet.py
@@ -158,7 +158,7 @@ def button_confirm_sheet(self):
"date": line.date,
"amount": amount_line,
"partner_id": line.partner_id.id,
- "payment_ref": line.ref,
+ "payment_ref": line.ref or line.invoice_id.name,
"sequence": line.sequence,
"statement_id": statement.id,
"payment_sheet_line_ids": line,
diff --git a/sale_payment_sheet/security/ir.model.access.csv b/sale_payment_sheet/security/ir.model.access.csv
index 6a4d46846de..c83325ff6f3 100644
--- a/sale_payment_sheet/security/ir.model.access.csv
+++ b/sale_payment_sheet/security/ir.model.access.csv
@@ -3,3 +3,4 @@ access_sale_payment_sheet_salesman,access_sale_payment_sheet_salesman,model_sale
access_sale_payment_sheet_line_salesman,access_sale_payment_sheet_line_salesman,model_sale_payment_sheet_line,sales_team.group_sale_salesman,1,1,1,1
access_sale_payment_sheet_accountant,access_sale_payment_sheet_accountant,model_sale_payment_sheet,account.group_account_invoice,1,1,1,1
access_sale_payment_sheet_line_accountant,access_sale_payment_sheet_line_accountant,model_sale_payment_sheet_line,account.group_account_invoice,1,1,1,1
+access_invoice_payment_wiz,access_invoice_payment_wiz_user,model_sale_invoice_payment_wiz,base.group_user,1,1,1,1
diff --git a/sale_payment_sheet/views/sale_payment_sheet_menu.xml b/sale_payment_sheet/views/sale_payment_sheet_menu.xml
index f86373c7e6c..976863e0dc8 100644
--- a/sale_payment_sheet/views/sale_payment_sheet_menu.xml
+++ b/sale_payment_sheet/views/sale_payment_sheet_menu.xml
@@ -48,10 +48,10 @@
[
('state', '=', 'posted'),
- ('type', 'in', ['out_invoice', 'out_refund'])]
+ ('move_type', 'in', ['out_invoice', 'out_refund'])]
{
- 'default_type':'out_invoice',
- 'type':'out_invoice',
+ 'default_move_type':'out_invoice',
+ 'move_type':'out_invoice',
'journal_type': 'sale',
'search_default_in_payment': True,
'search_default_unpaid': True,
From 7c461d49e88683a23eb6f76f68f0e2b292329941 Mon Sep 17 00:00:00 2001
From: oca-ci
Date: Wed, 24 Aug 2022 07:46:33 +0000
Subject: [PATCH 10/20] [UPD] Update sale_payment_sheet.pot
---
sale_payment_sheet/i18n/sale_payment_sheet.pot | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/sale_payment_sheet/i18n/sale_payment_sheet.pot b/sale_payment_sheet/i18n/sale_payment_sheet.pot
index a21344eacce..f996be997c7 100644
--- a/sale_payment_sheet/i18n/sale_payment_sheet.pot
+++ b/sale_payment_sheet/i18n/sale_payment_sheet.pot
@@ -6,8 +6,6 @@ msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 15.0\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2022-06-28 20:47+0000\n"
-"PO-Revision-Date: 2022-06-28 20:47+0000\n"
"Last-Translator: \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
@@ -203,6 +201,7 @@ msgid "If checked, some messages have a delivery error."
msgstr ""
#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_invoice_payment_wiz__invoice_ids
#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet_line__invoice_id
#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.report_sale_payment_sheet
msgid "Invoice"
@@ -313,6 +312,7 @@ msgid "Partial payment"
msgstr ""
#. module: sale_payment_sheet
+#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_invoice_payment_wiz__partner_id
#: model:ir.model.fields,field_description:sale_payment_sheet.field_sale_payment_sheet_line__partner_id
#: model_terms:ir.ui.view,arch_db:sale_payment_sheet.report_sale_payment_sheet
msgid "Partner"
@@ -448,7 +448,7 @@ msgstr ""
msgid ""
"This invoice already has been included in other payment sheet or the amount payed is greather than residual invoice amount.\n"
" Invoice: %(invoice_name)s\n"
-" Amount payed:%(amount_payed)s\n"
+" Amount payed: %(amount_payed)s\n"
" Payment sheets: %(payment_lines_name)s"
msgstr ""
From 02445c40335877548bb63aa381b5fc87bb6744f5 Mon Sep 17 00:00:00 2001
From: OCA-git-bot
Date: Wed, 24 Aug 2022 07:53:29 +0000
Subject: [PATCH 11/20] [UPD] README.rst
---
sale_payment_sheet/README.rst | 21 +++++++++----------
.../static/description/index.html | 16 +++++++-------
2 files changed, 19 insertions(+), 18 deletions(-)
diff --git a/sale_payment_sheet/README.rst b/sale_payment_sheet/README.rst
index f5d968c643a..5168ee1f834 100644
--- a/sale_payment_sheet/README.rst
+++ b/sale_payment_sheet/README.rst
@@ -14,21 +14,19 @@ Sale payment sheet
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fsale--workflow-lightgray.png?logo=github
- :target: https://github.com/OCA/sale-workflow/tree/13.0/sale_payment_sheet
+ :target: https://github.com/OCA/sale-workflow/tree/15.0/sale_payment_sheet
:alt: OCA/sale-workflow
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
- :target: https://translation.odoo-community.org/projects/sale-workflow-13-0/sale-workflow-13-0-sale_payment_sheet
+ :target: https://translation.odoo-community.org/projects/sale-workflow-15-0/sale-workflow-15-0-sale_payment_sheet
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png
- :target: https://runbot.odoo-community.org/runbot/167/13.0
+ :target: https://runbot.odoo-community.org/runbot/167/15.0
:alt: Try me on Runbot
-|badge1| |badge2| |badge3| |badge4| |badge5|
+|badge1| |badge2| |badge3| |badge4| |badge5|
This module allows salesmen to register payments in a new document called payment sheet, accessible only with the sales permission.
-
This sheet includes the paid amount, and an optional reference to which invoice(s) is(are) being paid.
-
This payment sheet will generate a bank statement when confirmed.
**Table of contents**
@@ -76,7 +74,7 @@ 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 `_.
+`feedback `_.
Do not contact contributors directly about support or help with technical issues.
@@ -93,8 +91,9 @@ Contributors
* `Tecnativa `__:
- * Carlos Dauden
- * Sergio Teruel
+ * Carlos Dauden
+ * Sergio Teruel
+ * César A. Sánchez
Maintainers
~~~~~~~~~~~
@@ -115,8 +114,8 @@ promote its widespread use.
Current `maintainer `__:
-|maintainer-sergio-teruel|
+|maintainer-sergio-teruel|
-This module is part of the `OCA/sale-workflow `_ project on GitHub.
+This module is part of the `OCA/sale-workflow `_ project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
diff --git a/sale_payment_sheet/static/description/index.html b/sale_payment_sheet/static/description/index.html
index 083aeb1c52d..30bd17602bc 100644
--- a/sale_payment_sheet/static/description/index.html
+++ b/sale_payment_sheet/static/description/index.html
@@ -367,9 +367,10 @@ Sale payment sheet
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
-
-This module allows to commercial users register payments in a payment sheet.
-This payment sheet will generate a bank statement when is confirmed.
+
+This module allows salesmen to register payments in a new document called payment sheet, accessible only with the sales permission.
+This sheet includes the paid amount, and an optional reference to which invoice(s) is(are) being paid.
+This payment sheet will generate a bank statement when confirmed.
Table of contents
@@ -422,7 +423,7 @@
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 .
+feedback .
Do not contact contributors directly about support or help with technical issues.
From 3119307c6f0648e1c0915a591986f0e7c042ea01 Mon Sep 17 00:00:00 2001
From: sergio-teruel
Date: Thu, 8 Sep 2022 16:37:10 +0200
Subject: [PATCH 12/20] [IMP] sale_payment_sheet: Display partner shipping as
optional in invoices tree view TT38893
---
sale_payment_sheet/views/sale_payment_sheet_menu.xml | 1 +
1 file changed, 1 insertion(+)
diff --git a/sale_payment_sheet/views/sale_payment_sheet_menu.xml b/sale_payment_sheet/views/sale_payment_sheet_menu.xml
index 976863e0dc8..541fe353914 100644
--- a/sale_payment_sheet/views/sale_payment_sheet_menu.xml
+++ b/sale_payment_sheet/views/sale_payment_sheet_menu.xml
@@ -14,6 +14,7 @@
>
+
From a70f6ea238bb8c655b0e6c8c39429f73d6af2b65 Mon Sep 17 00:00:00 2001
From: OCA-git-bot
Date: Tue, 13 Sep 2022 14:57:21 +0000
Subject: [PATCH 13/20] sale_payment_sheet 15.0.1.1.0
---
sale_payment_sheet/__manifest__.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sale_payment_sheet/__manifest__.py b/sale_payment_sheet/__manifest__.py
index 84ad97e8503..6c3ce3541ab 100644
--- a/sale_payment_sheet/__manifest__.py
+++ b/sale_payment_sheet/__manifest__.py
@@ -5,7 +5,7 @@
"name": "Sale payment sheet",
"summary": "Allow to create invoice payments to commercial users without "
"accounting permissions",
- "version": "15.0.1.0.0",
+ "version": "15.0.1.1.0",
"development_status": "Beta",
"category": "Account",
"website": "https://github.com/OCA/sale-workflow",
From 820b3da79a553759769c8df22b4fa37fe411aba1 Mon Sep 17 00:00:00 2001
From: Christopher Rogos
Date: Tue, 11 Oct 2022 21:25:10 +0200
Subject: [PATCH 14/20] [FIX] Update deprecated unit tests
---
sale_payment_sheet/tests/test_sale_payment_sheet.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/sale_payment_sheet/tests/test_sale_payment_sheet.py b/sale_payment_sheet/tests/test_sale_payment_sheet.py
index e25970dd552..a3e66e4bfd0 100644
--- a/sale_payment_sheet/tests/test_sale_payment_sheet.py
+++ b/sale_payment_sheet/tests/test_sale_payment_sheet.py
@@ -5,11 +5,11 @@
from freezegun import freeze_time
from odoo.exceptions import UserError, ValidationError
-from odoo.tests import Form, SavepointCase
+from odoo.tests import Form, TransactionCase
@freeze_time("2021-01-01 09:30:00")
-class TestSaleInvoicePayment(SavepointCase):
+class TestSaleInvoicePayment(TransactionCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
From b83745272ffdb3beb2e027d3008ddd12285f30dd Mon Sep 17 00:00:00 2001
From: OCA-git-bot
Date: Thu, 20 Oct 2022 16:57:35 +0000
Subject: [PATCH 15/20] sale_payment_sheet 15.0.1.1.1
---
sale_payment_sheet/__manifest__.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sale_payment_sheet/__manifest__.py b/sale_payment_sheet/__manifest__.py
index 6c3ce3541ab..702cf6b0375 100644
--- a/sale_payment_sheet/__manifest__.py
+++ b/sale_payment_sheet/__manifest__.py
@@ -5,7 +5,7 @@
"name": "Sale payment sheet",
"summary": "Allow to create invoice payments to commercial users without "
"accounting permissions",
- "version": "15.0.1.1.0",
+ "version": "15.0.1.1.1",
"development_status": "Beta",
"category": "Account",
"website": "https://github.com/OCA/sale-workflow",
From 9b6358c24be875716a71459d37960f0f7667722a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?V=C3=ADctor=20Mart=C3=ADnez?=
Date: Tue, 29 Nov 2022 09:22:23 +0100
Subject: [PATCH 16/20] [IMP] sale_payment_sheet: Remove redundant default on
related field.
---
sale_payment_sheet/models/sale_payment_sheet.py | 1 -
1 file changed, 1 deletion(-)
diff --git a/sale_payment_sheet/models/sale_payment_sheet.py b/sale_payment_sheet/models/sale_payment_sheet.py
index 2ab1cd54935..3477a7b2568 100644
--- a/sale_payment_sheet/models/sale_payment_sheet.py
+++ b/sale_payment_sheet/models/sale_payment_sheet.py
@@ -60,7 +60,6 @@ class SalePaymentSheet(models.Model):
string="Company",
store=True,
readonly=True,
- default=lambda self: self.env.company,
)
line_ids = fields.One2many(
"sale.payment.sheet.line",
From 342191507af931e4a63d6aa0936ed56037d71450 Mon Sep 17 00:00:00 2001
From: OCA-git-bot
Date: Tue, 29 Nov 2022 08:43:16 +0000
Subject: [PATCH 17/20] sale_payment_sheet 15.0.1.1.2
---
sale_payment_sheet/__manifest__.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sale_payment_sheet/__manifest__.py b/sale_payment_sheet/__manifest__.py
index 702cf6b0375..26a3322ef1b 100644
--- a/sale_payment_sheet/__manifest__.py
+++ b/sale_payment_sheet/__manifest__.py
@@ -5,7 +5,7 @@
"name": "Sale payment sheet",
"summary": "Allow to create invoice payments to commercial users without "
"accounting permissions",
- "version": "15.0.1.1.1",
+ "version": "15.0.1.1.2",
"development_status": "Beta",
"category": "Account",
"website": "https://github.com/OCA/sale-workflow",
From 8a83526ad6467d4ba5fb37a32c96a2ee560c033d Mon Sep 17 00:00:00 2001
From: angelmoya
Date: Tue, 6 Jun 2023 09:14:01 +0000
Subject: [PATCH 18/20] [IMP] sale_payment_sheet: pre-commit stuff
---
setup/sale_payment_sheet/odoo/addons/sale_payment_sheet | 1 +
setup/sale_payment_sheet/setup.py | 6 ++++++
2 files changed, 7 insertions(+)
create mode 120000 setup/sale_payment_sheet/odoo/addons/sale_payment_sheet
create mode 100644 setup/sale_payment_sheet/setup.py
diff --git a/setup/sale_payment_sheet/odoo/addons/sale_payment_sheet b/setup/sale_payment_sheet/odoo/addons/sale_payment_sheet
new file mode 120000
index 00000000000..335a4e77043
--- /dev/null
+++ b/setup/sale_payment_sheet/odoo/addons/sale_payment_sheet
@@ -0,0 +1 @@
+../../../../sale_payment_sheet
\ No newline at end of file
diff --git a/setup/sale_payment_sheet/setup.py b/setup/sale_payment_sheet/setup.py
new file mode 100644
index 00000000000..28c57bb6403
--- /dev/null
+++ b/setup/sale_payment_sheet/setup.py
@@ -0,0 +1,6 @@
+import setuptools
+
+setuptools.setup(
+ setup_requires=['setuptools-odoo'],
+ odoo_addon=True,
+)
From 6fb69894e14c9bc9a48df1e1eeae1eeaa0a57eb2 Mon Sep 17 00:00:00 2001
From: angelmoya
Date: Tue, 6 Jun 2023 11:43:02 +0000
Subject: [PATCH 19/20] [MIG] sale_payment_sheet: Migration to 16.0
---
sale_payment_sheet/README.rst | 8 +++----
sale_payment_sheet/__manifest__.py | 2 +-
sale_payment_sheet/i18n/es.po | 2 +-
.../i18n/sale_payment_sheet.pot | 2 +-
.../models/sale_payment_sheet.py | 4 +---
.../static/description/index.html | 6 ++---
.../tests/test_sale_payment_sheet.py | 23 +++++++++++++++----
7 files changed, 30 insertions(+), 17 deletions(-)
diff --git a/sale_payment_sheet/README.rst b/sale_payment_sheet/README.rst
index 5168ee1f834..6cd8eba377d 100644
--- a/sale_payment_sheet/README.rst
+++ b/sale_payment_sheet/README.rst
@@ -14,13 +14,13 @@ Sale payment sheet
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fsale--workflow-lightgray.png?logo=github
- :target: https://github.com/OCA/sale-workflow/tree/15.0/sale_payment_sheet
+ :target: https://github.com/OCA/sale-workflow/tree/16.0/sale_payment_sheet
:alt: OCA/sale-workflow
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/sale-workflow-15-0/sale-workflow-15-0-sale_payment_sheet
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png
- :target: https://runbot.odoo-community.org/runbot/167/15.0
+ :target: https://runbot.odoo-community.org/runbot/167/16.0
:alt: Try me on Runbot
|badge1| |badge2| |badge3| |badge4| |badge5|
@@ -74,7 +74,7 @@ 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 `_.
+`feedback `_.
Do not contact contributors directly about support or help with technical issues.
@@ -116,6 +116,6 @@ Current `maintainer `__:
|maintainer-sergio-teruel|
-This module is part of the `OCA/sale-workflow `_ project on GitHub.
+This module is part of the `OCA/sale-workflow `_ project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
diff --git a/sale_payment_sheet/__manifest__.py b/sale_payment_sheet/__manifest__.py
index 26a3322ef1b..698f57bb51c 100644
--- a/sale_payment_sheet/__manifest__.py
+++ b/sale_payment_sheet/__manifest__.py
@@ -5,7 +5,7 @@
"name": "Sale payment sheet",
"summary": "Allow to create invoice payments to commercial users without "
"accounting permissions",
- "version": "15.0.1.1.2",
+ "version": "16.0.1.1.2",
"development_status": "Beta",
"category": "Account",
"website": "https://github.com/OCA/sale-workflow",
diff --git a/sale_payment_sheet/i18n/es.po b/sale_payment_sheet/i18n/es.po
index dae110b2618..5f79f47b712 100644
--- a/sale_payment_sheet/i18n/es.po
+++ b/sale_payment_sheet/i18n/es.po
@@ -7,7 +7,7 @@
#
msgid ""
msgstr ""
-"Project-Id-Version: Odoo Server 15.0\n"
+"Project-Id-Version: Odoo Server 16.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2022-06-28 20:48+0000\n"
"PO-Revision-Date: 2022-06-28 20:48+0000\n"
diff --git a/sale_payment_sheet/i18n/sale_payment_sheet.pot b/sale_payment_sheet/i18n/sale_payment_sheet.pot
index f996be997c7..13eb5714e71 100644
--- a/sale_payment_sheet/i18n/sale_payment_sheet.pot
+++ b/sale_payment_sheet/i18n/sale_payment_sheet.pot
@@ -4,7 +4,7 @@
#
msgid ""
msgstr ""
-"Project-Id-Version: Odoo Server 15.0\n"
+"Project-Id-Version: Odoo Server 16.0\n"
"Report-Msgid-Bugs-To: \n"
"Last-Translator: \n"
"Language-Team: \n"
diff --git a/sale_payment_sheet/models/sale_payment_sheet.py b/sale_payment_sheet/models/sale_payment_sheet.py
index 3477a7b2568..9fe96a5c6df 100644
--- a/sale_payment_sheet/models/sale_payment_sheet.py
+++ b/sale_payment_sheet/models/sale_payment_sheet.py
@@ -136,8 +136,6 @@ def button_confirm_sheet(self):
{
"name": sheet.name,
"date": sheet.date,
- "journal_id": sheet.journal_id.id,
- "user_id": sheet.user_id.id,
}
)
vals_dic = {}
@@ -155,6 +153,7 @@ def button_confirm_sheet(self):
vals_dic[key] = {
"name": line.name,
"date": line.date,
+ "journal_id": sheet.journal_id.id,
"amount": amount_line,
"partner_id": line.partner_id.id,
"payment_ref": line.ref or line.invoice_id.name,
@@ -183,7 +182,6 @@ def button_reopen(self):
raise UserError(
_("You can not reopen a sheet that has any reconciled line.")
)
- self_sudo.statement_id.button_reopen()
self_sudo.statement_id.unlink()
self.state = "open"
diff --git a/sale_payment_sheet/static/description/index.html b/sale_payment_sheet/static/description/index.html
index 30bd17602bc..3cca509fc2e 100644
--- a/sale_payment_sheet/static/description/index.html
+++ b/sale_payment_sheet/static/description/index.html
@@ -367,7 +367,7 @@ Sale payment sheet
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
-
+
This module allows salesmen to register payments in a new document called payment sheet, accessible only with the sales permission.
This sheet includes the paid amount, and an optional reference to which invoice(s) is(are) being paid.
This payment sheet will generate a bank statement when confirmed.
@@ -423,7 +423,7 @@
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 .
+feedback .
Do not contact contributors directly about support or help with technical issues.
diff --git a/sale_payment_sheet/tests/test_sale_payment_sheet.py b/sale_payment_sheet/tests/test_sale_payment_sheet.py
index a3e66e4bfd0..936fd8714f1 100644
--- a/sale_payment_sheet/tests/test_sale_payment_sheet.py
+++ b/sale_payment_sheet/tests/test_sale_payment_sheet.py
@@ -15,18 +15,33 @@ def setUpClass(cls):
super().setUpClass()
# Remove time zone from user to avoid to time local representation
cls.env.user.partner_id.tz = False
+ account_group = cls.env.ref("account.group_account_user")
+ cls.env.user.write({"groups_id": [(4, account_group.id)]})
+ no_one_group = cls.env.ref("base.group_no_one")
+ cls.env.user.write({"groups_id": [(4, no_one_group.id)]})
cls.wizard_obj = cls.env["sale.invoice.payment.wiz"]
cls.SalePaymentSheet = cls.env["sale.payment.sheet"]
cls.partner = cls.env["res.partner"].create({"name": "Test partner"})
+ suspense_account = cls.env["account.account"].create(
+ {
+ "code": "assetcurrent",
+ "name": "Test Current Asset",
+ "account_type": "asset_current",
+ }
+ )
cls.bank_journal = cls.env["account.journal"].create(
- {"name": "Bank journal", "type": "bank", "code": "test"}
+ {
+ "name": "Bank journal",
+ "type": "bank",
+ "code": "test",
+ "suspense_account_id": suspense_account.id,
+ }
)
- account_type_income = cls.env.ref("account.data_account_type_revenue")
cls.account_invoice = cls.env["account.account"].create(
{
"code": "test",
"name": "Test account",
- "user_type_id": account_type_income.id,
+ "account_type": "income",
}
)
cls.invoice1 = cls._create_invoice(cls)
@@ -76,7 +91,7 @@ def _create_payment_sheet(self):
with sheet_form.line_ids.new() as line_sheet:
line_sheet.partner_id = self.partner
line_sheet.invoice_id = invoice
- line_sheet.ref = "REF{}".format(line_sheet.id)
+ # line_sheet.ref = "REF{}".format(line_sheet.id)
# Only write for partial amount payed, by default the
# amount line is total amount residual
if index > 0:
From 8b79c7a8a347f3eef437755d49688826028c1e88 Mon Sep 17 00:00:00 2001
From: angelmoya
Date: Wed, 7 Jun 2023 11:41:31 +0000
Subject: [PATCH 20/20] [IMP] sale_payment_sheet: add more tests and fix
version
---
sale_payment_sheet/__manifest__.py | 2 +-
.../tests/test_sale_payment_sheet.py | 70 +++++++++++++++++--
2 files changed, 65 insertions(+), 7 deletions(-)
diff --git a/sale_payment_sheet/__manifest__.py b/sale_payment_sheet/__manifest__.py
index 698f57bb51c..a191cbf86fc 100644
--- a/sale_payment_sheet/__manifest__.py
+++ b/sale_payment_sheet/__manifest__.py
@@ -5,7 +5,7 @@
"name": "Sale payment sheet",
"summary": "Allow to create invoice payments to commercial users without "
"accounting permissions",
- "version": "16.0.1.1.2",
+ "version": "16.0.1.0.0",
"development_status": "Beta",
"category": "Account",
"website": "https://github.com/OCA/sale-workflow",
diff --git a/sale_payment_sheet/tests/test_sale_payment_sheet.py b/sale_payment_sheet/tests/test_sale_payment_sheet.py
index 936fd8714f1..45622f68c60 100644
--- a/sale_payment_sheet/tests/test_sale_payment_sheet.py
+++ b/sale_payment_sheet/tests/test_sale_payment_sheet.py
@@ -46,7 +46,8 @@ def setUpClass(cls):
)
cls.invoice1 = cls._create_invoice(cls)
cls.invoice2 = cls._create_invoice(cls)
- (cls.invoice1 + cls.invoice2).action_post()
+ cls.refund1 = cls._create_refund(cls)
+ (cls.invoice1 + cls.invoice2 + cls.refund1).action_post()
def _create_invoice(self):
with Form(
@@ -60,10 +61,22 @@ def _create_invoice(self):
line_form.price_unit = 100.00
return invoice_form.save()
+ def _create_refund(self):
+ with Form(
+ self.env["account.move"].with_context(default_move_type="out_refund")
+ ) as invoice_form:
+ invoice_form.partner_id = self.partner
+ with invoice_form.invoice_line_ids.new() as line_form:
+ line_form.name = "invoice test"
+ line_form.account_id = self.account_invoice
+ line_form.quantity = 1.0
+ line_form.price_unit = 10.00
+ return invoice_form.save()
+
def test_payment_wizard(self):
PaymentWiz = self.env["sale.invoice.payment.wiz"].with_context(
active_model="account.move",
- active_ids=(self.invoice1 + self.invoice2).ids,
+ active_ids=(self.invoice1 + self.invoice2 + self.refund1).ids,
)
with Form(PaymentWiz) as wiz_form:
wiz_form.journal_id = self.bank_journal
@@ -71,7 +84,7 @@ def test_payment_wizard(self):
wiz = wiz_form.save()
action = wiz.create_sale_invoice_payment_sheet()
sheet = self.SalePaymentSheet.browse(action["res_id"])
- self.assertEqual(len(sheet.line_ids), 2)
+ self.assertEqual(len(sheet.line_ids), 3)
line_partial_payment = sheet.line_ids.filtered(
lambda ln: ln.transaction_type == "partial"
)
@@ -81,7 +94,7 @@ def test_payment_wizard(self):
lambda ln: ln.transaction_type == "full"
)
self.assertTrue(line_full_payment)
- self.assertEqual(line_full_payment.invoice_id, self.invoice1)
+ self.assertEqual(line_full_payment.invoice_id, (self.invoice1 + self.refund1))
self.assertEqual(sheet.amount_total, 150.00)
def _create_payment_sheet(self):
@@ -91,7 +104,6 @@ def _create_payment_sheet(self):
with sheet_form.line_ids.new() as line_sheet:
line_sheet.partner_id = self.partner
line_sheet.invoice_id = invoice
- # line_sheet.ref = "REF{}".format(line_sheet.id)
# Only write for partial amount payed, by default the
# amount line is total amount residual
if index > 0:
@@ -146,6 +158,8 @@ def test_payment_sheet_reopen(self):
self.assertFalse(sheet.statement_id)
def test_payment_sheet_unlink(self):
+ sheet = self._create_payment_sheet()
+ sheet.unlink()
sheet = self._create_payment_sheet()
sheet.button_confirm_sheet()
with self.assertRaises(UserError):
@@ -169,4 +183,48 @@ def test_payment_sheet_invoice_constraint(self):
with sheet_form.line_ids.new() as line_sheet:
line_sheet.partner_id = self.partner
line_sheet.invoice_id = self.invoice1
- sheet_form.save()
+
+ def test_wizard_sale_invoice_payment(self):
+ wiz = (
+ self.env["sale.invoice.payment.wiz"]
+ .with_context(
+ active_model="account.move",
+ active_ids=(self.invoice1 + self.invoice2).ids,
+ )
+ .create(
+ {
+ "journal_id": self.bank_journal.id,
+ "amount": 100.00,
+ }
+ )
+ )
+ action = wiz.create_sale_invoice_payment_sheet()
+ sheet = self.SalePaymentSheet.browse(action["res_id"])
+ self.assertEqual(len(sheet.line_ids), 1)
+ self.assertEqual(sheet.amount_total, 100.00)
+
+ def test_wizard_sale_invoice_payment_wrong(self):
+ wiz = (
+ self.env["sale.invoice.payment.wiz"]
+ .with_context(active_model="account.move", active_ids=[])
+ .create(
+ {
+ "journal_id": self.bank_journal.id,
+ "amount": 100.00,
+ }
+ )
+ )
+ action = wiz.create_sale_invoice_payment_sheet()
+ self.assertFalse(action)
+ wiz = (
+ self.env["sale.invoice.payment.wiz"]
+ .with_context(active_model="account.move.line", active_ids=[])
+ .create(
+ {
+ "journal_id": self.bank_journal.id,
+ "amount": 100.00,
+ }
+ )
+ )
+ action = wiz.create_sale_invoice_payment_sheet()
+ self.assertFalse(action)