diff --git a/pos_order_return/README.rst b/pos_order_return/README.rst new file mode 100644 index 0000000000..bb99665054 --- /dev/null +++ b/pos_order_return/README.rst @@ -0,0 +1,156 @@ +========================== +Point of Sale Order Return +========================== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:29519d20ac1fb1b4f1f67e22a0edd1a4909607663b7c916aee3eae913ad3d074 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png + :target: https://odoo-community.org/page/development-status + :alt: Alpha +.. |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%2Fpos-lightgray.png?logo=github + :target: https://github.com/OCA/pos/tree/18.0/pos_order_return + :alt: OCA/pos +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/pos-18-0/pos-18-0-pos_order_return + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/pos&target_branch=18.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module extends the functionality of odoo Point Of Sale about POS +Order returns. + +.. IMPORTANT:: + This is an alpha version, the data model and design can change at any time without warning. + Only for development or testing purpose, do not use in production. + `More details on development status `_ + +**Table of contents** + +.. contents:: + :local: + +Configuration +============= + +In some cases, you may want to block the possibility to allow negative +quantity in a PoS Order, without mentioning initial order. This can +happen for special products like returnable products, etc. + +In that case, a checkbox is possible on Product Form View to allow such +case + +|image1| + +.. |image1| image:: https://raw.githubusercontent.com/OCA/pos/18.0/pos_order_return/static/description/product_returnable_bottle.png + +Usage +===== + +Select an PoS Order and choose either *Return Products* (full return of +the order) or *Partial Return*. In this case, a wizard allows to select +just some products and quantities to return: + +|image2| + +Register the refund payment to finish the return. If the original order +was invoiced, a refund invoice will be made. + +**Implemented Constraints** + +- User can not return more products than the initial quantity: + +|image3| + +- If a line has been partially refund, only a reduced quantity can be + returned: + +|image4| + +- It is not possible to set a negative quantity if the initial Pos + Order is not indicated: + +|image5| + +.. |image2| image:: https://raw.githubusercontent.com/OCA/pos/18.0/pos_order_return/static/description/partial_return_wizard.png +.. |image3| image:: https://raw.githubusercontent.com/OCA/pos/18.0/pos_order_return/static/description/returned_qty_over_initial.png +.. |image4| image:: https://raw.githubusercontent.com/OCA/pos/18.0/pos_order_return/static/description/sum_returned_qty_over_initial.png +.. |image5| image:: https://raw.githubusercontent.com/OCA/pos/18.0/pos_order_return/static/description/initial_pos_order_required.png + +Known issues / Roadmap +====================== + + + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +------- + +* La Louve +* GRAP +* Tecnativa +* Lambda IS + +Contributors +------------ + +- Sylvain LE GAL +- David Vidal +- Kiril Vangelovski +- Druidoo +- Dhara Solanki +- `Trobz `__: + + - Nguyen Minh Chien + +Other credits +------------- + +Funders +~~~~~~~ + +The development of this module has been financially supported by: + +- La Louve (`www.lalouve.net `__) +- GRAP, Groupement Régional Alimentaire de Proximité + (`www.grap.coop `__) + +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/pos `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/pos_order_return/__init__.py b/pos_order_return/__init__.py new file mode 100644 index 0000000000..9b4296142f --- /dev/null +++ b/pos_order_return/__init__.py @@ -0,0 +1,2 @@ +from . import models +from . import wizard diff --git a/pos_order_return/__manifest__.py b/pos_order_return/__manifest__.py new file mode 100644 index 0000000000..8ec55de3c6 --- /dev/null +++ b/pos_order_return/__manifest__.py @@ -0,0 +1,31 @@ +# Copyright 2016-2018 Sylvain LE GAL (https://twitter.com/legalsylvain) +# Copyright 2018 David Vidal +# Copyright 2018 Lambda IS DOOEL +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +{ + "name": "Point of Sale Order Return", + "version": "18.0.1.0.0", + "category": "Point Of Sale", + "author": "La Louve, " + "GRAP, " + "Tecnativa, " + "Lambda IS, " + "Odoo Community Association (OCA)", + "license": "AGPL-3", + "website": "https://github.com/OCA/pos", + "development_status": "Alpha", + "depends": [ + "point_of_sale", + ], + "data": [ + "security/ir.model.access.csv", + "wizard/pos_partial_return_wizard_view.xml", + "views/pos_order_view.xml", + "views/product_product_view.xml", + ], + "demo": [ + "demo/product_product.xml", + ], + "installable": True, +} diff --git a/pos_order_return/demo/product_product.xml b/pos_order_return/demo/product_product.xml new file mode 100644 index 0000000000..40c02ef19e --- /dev/null +++ b/pos_order_return/demo/product_product.xml @@ -0,0 +1,18 @@ + + + + Returnable Bottle + RET-BOTL + + + + + + + + + diff --git a/pos_order_return/i18n/ca.po b/pos_order_return/i18n/ca.po new file mode 100644 index 0000000000..8494e6e8e0 --- /dev/null +++ b/pos_order_return/i18n/ca.po @@ -0,0 +1,247 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * pos_order_return +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 12.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2022-04-13 11:05+0000\n" +"Last-Translator: Noel estudillo \n" +"Language-Team: none\n" +"Language: ca\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.3.2\n" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_product_product__pos_allow_negative_qty +#: model:ir.model.fields,field_description:pos_order_return.field_product_template__pos_allow_negative_qty +msgid "Allow Negative Quantity on PoS" +msgstr "Permet una quantitat negativa a PoS" + +#. module: pos_order_return +#: model_terms:ir.ui.view,arch_db:pos_order_return.view_partial_return_wizard_form +msgid "Cancel" +msgstr "Cancel · lar" + +#. module: pos_order_return +#: model:ir.model.fields,help:pos_order_return.field_pos_partial_return_wizard_line__max_returnable_qty +msgid "" +"Compute maximum quantity that can be returned for this line, depending of " +"the quantity of the line and other possible refunds." +msgstr "" +"Calculeu la quantitat màxima que es pot retornar per aquesta línia, en " +"funció de la quantitat de la línia i d'altres possibles reembossaments." + +#. module: pos_order_return +#: model_terms:ir.ui.view,arch_db:pos_order_return.view_partial_return_wizard_form +msgid "Confirm" +msgstr "Confirmar" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard__create_uid +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard_line__create_uid +msgid "Created by" +msgstr "Creat per" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard__create_date +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard_line__create_date +msgid "Created on" +msgstr "Creat el" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_order__display_name +#: model:ir.model.fields,field_description:pos_order_return.field_pos_order_line__display_name +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard__display_name +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard_line__display_name +#: model:ir.model.fields,field_description:pos_order_return.field_product_template__display_name +msgid "Display Name" +msgstr "Mostrar Nom" + +#. module: pos_order_return +#: code:addons/pos_order_return/models/pos_order.py:0 +#, python-format +msgid "" +"For legal and traceability reasons, you can not set a negative quantity (%d " +"%s of %s), without using return wizard." +msgstr "" +"Per motius legals i de traçabilitat, no podeu establir una quantitat " +"negativa (%d %s de %s), sense utilitzar l'assistent de retorn." + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_order__id +#: model:ir.model.fields,field_description:pos_order_return.field_pos_order_line__id +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard__id +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard_line__id +#: model:ir.model.fields,field_description:pos_order_return.field_product_template__id +msgid "ID" +msgstr "ID" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard_line__initial_qty +msgid "Initial Quantity" +msgstr "Quantitat inicial" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_order____last_update +#: model:ir.model.fields,field_description:pos_order_return.field_pos_order_line____last_update +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard____last_update +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard_line____last_update +#: model:ir.model.fields,field_description:pos_order_return.field_product_template____last_update +msgid "Last Modified on" +msgstr "Darrera modificació el" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard__write_uid +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard_line__write_uid +msgid "Last Updated by" +msgstr "Darrera actualització per" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard__write_date +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard_line__write_date +msgid "Last Updated on" +msgstr "Darrera actualització el" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard_line__pos_order_line_id +msgid "Line To Return" +msgstr "Línia per tornar" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard__line_ids +#: model_terms:ir.ui.view,arch_db:pos_order_return.view_partial_return_wizard_form +msgid "Lines to Return" +msgstr "Línies per tornar" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard__order_id +msgid "Order to Return" +msgstr "Ordre de retorn" + +#. module: pos_order_return +#: model_terms:ir.ui.view,arch_db:pos_order_return.view_partial_return_wizard_form +#: model_terms:ir.ui.view,arch_db:pos_order_return.view_pos_order_form +msgid "Partial Return" +msgstr "Retorn parcial" + +#. module: pos_order_return +#: model:ir.actions.act_window,name:pos_order_return.action_pos_partial_return_wizard +#: model:ir.model,name:pos_order_return.model_pos_partial_return_wizard +msgid "Partial Return Wizard" +msgstr "Assistent de retorn parcial" + +#. module: pos_order_return +#: model:ir.model,name:pos_order_return.model_pos_partial_return_wizard_line +msgid "Partial Return Wizard Line" +msgstr "Línia d'assistent de retorn parcial" + +#. module: pos_order_return +#: model:ir.model,name:pos_order_return.model_pos_order_line +msgid "Point of Sale Order Lines" +msgstr "Línies de comandes de punt de venda" + +#. module: pos_order_return +#: model:ir.model,name:pos_order_return.model_pos_order +msgid "Point of Sale Orders" +msgstr "Comandes de punt de venda" + +#. module: pos_order_return +#: model:ir.model,name:pos_order_return.model_product_template +msgid "Product Template" +msgstr "Plantilla Producte" + +#. module: pos_order_return +#: model:ir.model.fields,help:pos_order_return.field_pos_partial_return_wizard_line__initial_qty +msgid "Quantity of Product initially sold" +msgstr "Quantitat de producte venut inicialment" + +#. module: pos_order_return +#: model_terms:ir.ui.view,arch_db:pos_order_return.view_pos_order_form +#: model_terms:ir.ui.view,arch_db:pos_order_return.view_pos_order_line_form +msgid "Refund" +msgstr "Devolució" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_order_line__refund_orderline_ids +msgid "Refund Lines" +msgstr "Línies de devolució" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_order__refund_order_ids +msgid "Refund Orders" +msgstr "Ordres de devolució" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_order__refund_order_qty +msgid "Refund Orders Quantity" +msgstr "Quantitat de comandes de devolució" + +#. module: pos_order_return +#: code:addons/pos_order_return/models/pos_order.py:0 +#, python-format +msgid "Return of %s" +msgstr "Retorn de %s" + +#. module: pos_order_return +#: model:product.product,name:pos_order_return.product_product_returnable_bottle +#: model:product.template,name:pos_order_return.product_product_returnable_bottle_product_template +msgid "Returnable Bottle" +msgstr "Ampolla retornable" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard_line__max_returnable_qty +msgid "Returnable Quantity" +msgstr "Quantitat retornable" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_order__returned_order_id +#: model:ir.model.fields,field_description:pos_order_return.field_pos_order_line__refunded_orderline_id +msgid "Returned Order" +msgstr "Comanda retornada" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard_line__qty +msgid "Returned Quantity" +msgstr "Quantitat retornada" + +#. module: pos_order_return +#: model:product.product,uom_name:pos_order_return.product_product_returnable_bottle +#: model:product.template,uom_name:pos_order_return.product_product_returnable_bottle_product_template +msgid "Units" +msgstr "" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard_line__wizard_id +msgid "Wizard" +msgstr "Asistent" + +#. module: pos_order_return +#: code:addons/pos_order_return/models/pos_order.py:0 +#, python-format +msgid "" +"You can not return %d %s of %s because some refunds have already been done.\n" +" Maximum quantity allowed : %d %s." +msgstr "" +"No podeu tornar %d %s de %s perquè ja s'han realitzat algunes devolucions.\n" +" Quantitat màxima permesa: %d %s." + +#. module: pos_order_return +#: code:addons/pos_order_return/models/pos_order.py:0 +#, python-format +msgid "" +"You can not return %d %s of %s because the original Order line only mentions " +"%d %s." +msgstr "" +"No podeu tornar %d %s de %s perquè la línia de comanda original només " +"menciona %d %s." + +#~ msgid "Unit(s)" +#~ msgstr "Unitat(s)" + +#~ msgid "kg" +#~ msgstr "kg" diff --git a/pos_order_return/i18n/es.po b/pos_order_return/i18n/es.po new file mode 100644 index 0000000000..37040b5250 --- /dev/null +++ b/pos_order_return/i18n/es.po @@ -0,0 +1,251 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * pos_order_return +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 10.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2018-05-03 12:50+0000\n" +"PO-Revision-Date: 2024-02-23 14:34+0000\n" +"Last-Translator: Anna Martínez \n" +"Language-Team: \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.17\n" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_product_product__pos_allow_negative_qty +#: model:ir.model.fields,field_description:pos_order_return.field_product_template__pos_allow_negative_qty +msgid "Allow Negative Quantity on PoS" +msgstr "Permitir Cantidades Negativas en PoS" + +#. module: pos_order_return +#: model_terms:ir.ui.view,arch_db:pos_order_return.view_partial_return_wizard_form +msgid "Cancel" +msgstr "Cancelar" + +#. module: pos_order_return +#: model:ir.model.fields,help:pos_order_return.field_pos_partial_return_wizard_line__max_returnable_qty +msgid "" +"Compute maximum quantity that can be returned for this line, depending of " +"the quantity of the line and other possible refunds." +msgstr "" +"Calcula la cantidad máxima que puede ser devuelta para esta línea, " +"dependiendo de la cantidad de la línea y otras devoluciones anteriores." + +#. module: pos_order_return +#: model_terms:ir.ui.view,arch_db:pos_order_return.view_partial_return_wizard_form +msgid "Confirm" +msgstr "Confirmar" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard__create_uid +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard_line__create_uid +msgid "Created by" +msgstr "Creado por" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard__create_date +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard_line__create_date +msgid "Created on" +msgstr "Creado el" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_order__display_name +#: model:ir.model.fields,field_description:pos_order_return.field_pos_order_line__display_name +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard__display_name +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard_line__display_name +#: model:ir.model.fields,field_description:pos_order_return.field_product_template__display_name +msgid "Display Name" +msgstr "Nombre a mostrar" + +#. module: pos_order_return +#: code:addons/pos_order_return/models/pos_order.py:0 +#, python-format +msgid "" +"For legal and traceability reasons, you can not set a negative quantity (%d " +"%s of %s), without using return wizard." +msgstr "" +"Por razones legales y de trazabilidad, no puede establecer una cantidad " +"negativa (%d %s of %s), sin en el asistente de devoluciones." + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_order__id +#: model:ir.model.fields,field_description:pos_order_return.field_pos_order_line__id +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard__id +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard_line__id +#: model:ir.model.fields,field_description:pos_order_return.field_product_template__id +msgid "ID" +msgstr "ID" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard_line__initial_qty +msgid "Initial Quantity" +msgstr "Cantidad inicial" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_order____last_update +#: model:ir.model.fields,field_description:pos_order_return.field_pos_order_line____last_update +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard____last_update +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard_line____last_update +#: model:ir.model.fields,field_description:pos_order_return.field_product_template____last_update +msgid "Last Modified on" +msgstr "Última modificación en" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard__write_uid +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard_line__write_uid +msgid "Last Updated by" +msgstr "Última actualización por" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard__write_date +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard_line__write_date +msgid "Last Updated on" +msgstr "Última actualización el" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard_line__pos_order_line_id +msgid "Line To Return" +msgstr "Línea a devolver" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard__line_ids +#: model_terms:ir.ui.view,arch_db:pos_order_return.view_partial_return_wizard_form +msgid "Lines to Return" +msgstr "Líneas a devolver" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard__order_id +msgid "Order to Return" +msgstr "Pedido a devolver" + +#. module: pos_order_return +#: model_terms:ir.ui.view,arch_db:pos_order_return.view_partial_return_wizard_form +#: model_terms:ir.ui.view,arch_db:pos_order_return.view_pos_order_form +msgid "Partial Return" +msgstr "Devolición parcial" + +#. module: pos_order_return +#: model:ir.actions.act_window,name:pos_order_return.action_pos_partial_return_wizard +#: model:ir.model,name:pos_order_return.model_pos_partial_return_wizard +msgid "Partial Return Wizard" +msgstr "Asistente de devolución parcial" + +#. module: pos_order_return +#: model:ir.model,name:pos_order_return.model_pos_partial_return_wizard_line +msgid "Partial Return Wizard Line" +msgstr "Línea del asistente de devolución parcial" + +#. module: pos_order_return +#: model:ir.model,name:pos_order_return.model_pos_order_line +msgid "Point of Sale Order Lines" +msgstr "Líneas de pedido del TPV" + +#. module: pos_order_return +#: model:ir.model,name:pos_order_return.model_pos_order +msgid "Point of Sale Orders" +msgstr "Pedidos del TPV" + +#. module: pos_order_return +#: model:ir.model,name:pos_order_return.model_product_template +msgid "Product Template" +msgstr "Plantilla de producto" + +#. module: pos_order_return +#: model:ir.model.fields,help:pos_order_return.field_pos_partial_return_wizard_line__initial_qty +msgid "Quantity of Product initially sold" +msgstr "Cantidad de producto vendida inicialmente" + +#. module: pos_order_return +#: model_terms:ir.ui.view,arch_db:pos_order_return.view_pos_order_form +#: model_terms:ir.ui.view,arch_db:pos_order_return.view_pos_order_line_form +msgid "Refund" +msgstr "Factura rectificativa" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_order_line__refund_orderline_ids +msgid "Refund Lines" +msgstr "Líneas de devolución" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_order__refund_order_ids +msgid "Refund Orders" +msgstr "Pedidos de devolución" + +#. module: pos_order_return +#: code:addons/pos_order_return/models/pos_order.py:0 +#, python-format +msgid "Return of %s" +msgstr "Devolución de %s" + +#. module: pos_order_return +#: model:product.product,name:pos_order_return.product_product_returnable_bottle +#: model:product.template,name:pos_order_return.product_product_returnable_bottle_product_template +msgid "Returnable Bottle" +msgstr "Botella retornable" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard_line__max_returnable_qty +msgid "Returnable Quantity" +msgstr "Cantidad retornable" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_order__returned_order_id +#: model:ir.model.fields,field_description:pos_order_return.field_pos_order_line__refunded_orderline_id +msgid "Returned Order" +msgstr "Pedido devuelto" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard_line__qty +msgid "Returned Quantity" +msgstr "Cantidad devuelta" + +#. module: pos_order_return +#: model:product.product,uom_name:pos_order_return.product_product_returnable_bottle +#: model:product.template,uom_name:pos_order_return.product_product_returnable_bottle_product_template +msgid "Units" +msgstr "Unidades" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard_line__wizard_id +msgid "Wizard" +msgstr "Asistente" + +#. module: pos_order_return +#: code:addons/pos_order_return/models/pos_order.py:0 +#, python-format +msgid "" +"You can not return %d %s of %s because some refunds have already been done.\n" +" Maximum quantity allowed : %d %s." +msgstr "" +"No puede devolver %d %s de %s porque ya se ha devuelto una parte.\n" +" Cantidad máxima permitida : %d %s." + +#. module: pos_order_return +#: code:addons/pos_order_return/models/pos_order.py:0 +#, python-format +msgid "" +"You can not return %d %s of %s because the original Order line only mentions " +"%d %s." +msgstr "" +"No puede devolver %d %s de %s porque el pedido original solo menciona %d %s." + +#~ msgid "Unit(s)" +#~ msgstr "Unidad(es)" + +#~ msgid "kg" +#~ msgstr "kg" + +#~ msgid "Lines of Point of Sale Orders" +#~ msgstr "Líneas del Terminal Punto de Venta" + +#~ msgid "pos.partial.return.wizard" +#~ msgstr "pos.partial.return.wizard" + +#~ msgid "pos.partial.return.wizard.line" +#~ msgstr "pos.partial.return.wizard.line" diff --git a/pos_order_return/i18n/fr.po b/pos_order_return/i18n/fr.po new file mode 100644 index 0000000000..64397f7fd7 --- /dev/null +++ b/pos_order_return/i18n/fr.po @@ -0,0 +1,248 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * pos_return_order +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 9.0c\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2016-04-03 23:54+0000\n" +"PO-Revision-Date: 2016-04-03 23:54+0000\n" +"Last-Translator: <>\n" +"Language-Team: \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_product_product__pos_allow_negative_qty +#: model:ir.model.fields,field_description:pos_order_return.field_product_template__pos_allow_negative_qty +msgid "Allow Negative Quantity on PoS" +msgstr "PdV - Autoriser les quantités négatives" + +#. module: pos_order_return +#: model_terms:ir.ui.view,arch_db:pos_order_return.view_partial_return_wizard_form +msgid "Cancel" +msgstr "Annuler" + +#. module: pos_order_return +#: model:ir.model.fields,help:pos_order_return.field_pos_partial_return_wizard_line__max_returnable_qty +msgid "" +"Compute maximum quantity that can be returned for this line, depending of " +"the quantity of the line and other possible refunds." +msgstr "" +"Calcule la quantité maximum qui peut être retournée pour cette ligne, en " +"fonction de la quantité de la ligne original, et des possibles retours." + +#. module: pos_order_return +#: model_terms:ir.ui.view,arch_db:pos_order_return.view_partial_return_wizard_form +msgid "Confirm" +msgstr "Confirmer" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard__create_uid +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard_line__create_uid +msgid "Created by" +msgstr "Créé par" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard__create_date +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard_line__create_date +msgid "Created on" +msgstr "Créé le" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_order__display_name +#: model:ir.model.fields,field_description:pos_order_return.field_pos_order_line__display_name +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard__display_name +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard_line__display_name +#: model:ir.model.fields,field_description:pos_order_return.field_product_template__display_name +msgid "Display Name" +msgstr "Nom affiché" + +#. module: pos_order_return +#: code:addons/pos_order_return/models/pos_order.py:0 +#, python-format +msgid "" +"For legal and traceability reasons, you can not set a negative quantity (%d " +"%s of %s), without using return wizard." +msgstr "" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_order__id +#: model:ir.model.fields,field_description:pos_order_return.field_pos_order_line__id +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard__id +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard_line__id +#: model:ir.model.fields,field_description:pos_order_return.field_product_template__id +msgid "ID" +msgstr "ID" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard_line__initial_qty +msgid "Initial Quantity" +msgstr "Quantité initial" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_order____last_update +#: model:ir.model.fields,field_description:pos_order_return.field_pos_order_line____last_update +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard____last_update +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard_line____last_update +#: model:ir.model.fields,field_description:pos_order_return.field_product_template____last_update +msgid "Last Modified on" +msgstr "Dernière modification le" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard__write_uid +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard_line__write_uid +msgid "Last Updated by" +msgstr "Mis à jour par" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard__write_date +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard_line__write_date +msgid "Last Updated on" +msgstr "Mis à jour le" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard_line__pos_order_line_id +msgid "Line To Return" +msgstr "Ligne à retourner" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard__line_ids +#: model_terms:ir.ui.view,arch_db:pos_order_return.view_partial_return_wizard_form +msgid "Lines to Return" +msgstr "Lignes à retourner" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard__order_id +msgid "Order to Return" +msgstr "Vente à retourner" + +#. module: pos_order_return +#: model_terms:ir.ui.view,arch_db:pos_order_return.view_partial_return_wizard_form +#: model_terms:ir.ui.view,arch_db:pos_order_return.view_pos_order_form +msgid "Partial Return" +msgstr "Retourner partiellement" + +#. module: pos_order_return +#: model:ir.actions.act_window,name:pos_order_return.action_pos_partial_return_wizard +#: model:ir.model,name:pos_order_return.model_pos_partial_return_wizard +msgid "Partial Return Wizard" +msgstr "Assistant de retour partiel" + +#. module: pos_order_return +#: model:ir.model,name:pos_order_return.model_pos_partial_return_wizard_line +#, fuzzy +msgid "Partial Return Wizard Line" +msgstr "Assistant de retour partiel" + +#. module: pos_order_return +#: model:ir.model,name:pos_order_return.model_pos_order_line +#, fuzzy +msgid "Point of Sale Order Lines" +msgstr "Point de vente" + +#. module: pos_order_return +#: model:ir.model,name:pos_order_return.model_pos_order +#, fuzzy +msgid "Point of Sale Orders" +msgstr "Point de vente" + +#. module: pos_order_return +#: model:ir.model,name:pos_order_return.model_product_template +msgid "Product Template" +msgstr "Modèle d'article" + +#. module: pos_order_return +#: model:ir.model.fields,help:pos_order_return.field_pos_partial_return_wizard_line__initial_qty +msgid "Quantity of Product initially sold" +msgstr "Quantité de produit initialement vendue" + +#. module: pos_order_return +#: model_terms:ir.ui.view,arch_db:pos_order_return.view_pos_order_form +#: model_terms:ir.ui.view,arch_db:pos_order_return.view_pos_order_line_form +msgid "Refund" +msgstr "Avoir" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_order_line__refund_orderline_ids +msgid "Refund Lines" +msgstr "Lignes de vente retournées" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_order__refund_order_ids +msgid "Refund Orders" +msgstr "Ventes retournées" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_order__refund_order_qty +msgid "Refund Orders Quantity" +msgstr "Nombre de ventes retournées" + +#. module: pos_order_return +#: code:addons/pos_order_return/models/pos_order.py:0 +#, python-format +msgid "Return of %s" +msgstr "" + +#. module: pos_order_return +#: model:product.product,name:pos_order_return.product_product_returnable_bottle +#: model:product.template,name:pos_order_return.product_product_returnable_bottle_product_template +msgid "Returnable Bottle" +msgstr "Bouteille consignée" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard_line__max_returnable_qty +msgid "Returnable Quantity" +msgstr "Quantité retournable" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_order__returned_order_id +#: model:ir.model.fields,field_description:pos_order_return.field_pos_order_line__refunded_orderline_id +msgid "Returned Order" +msgstr "Vente retournée" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard_line__qty +msgid "Returned Quantity" +msgstr "Quantité retournée" + +#. module: pos_order_return +#: model:product.product,uom_name:pos_order_return.product_product_returnable_bottle +#: model:product.template,uom_name:pos_order_return.product_product_returnable_bottle_product_template +msgid "Units" +msgstr "" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard_line__wizard_id +msgid "Wizard" +msgstr "Assistant" + +#. module: pos_order_return +#: code:addons/pos_order_return/models/pos_order.py:0 +#, python-format +msgid "" +"You can not return %d %s of %s because some refunds have already been done.\n" +" Maximum quantity allowed : %d %s." +msgstr "" + +#. module: pos_order_return +#: code:addons/pos_order_return/models/pos_order.py:0 +#, python-format +msgid "" +"You can not return %d %s of %s because the original Order line only mentions " +"%d %s." +msgstr "" + +#, fuzzy +#~ msgid "Lines of Point of Sale Orders" +#~ msgstr "Lignes de Points de Vente" + +#~ msgid "pos.partial.return.wizard" +#~ msgstr "pos.partial.return.wizard" + +#~ msgid "pos.partial.return.wizard.line" +#~ msgstr "pos.partial.return.wizard.line" diff --git a/pos_order_return/i18n/it.po b/pos_order_return/i18n/it.po new file mode 100644 index 0000000000..0d1b0478d2 --- /dev/null +++ b/pos_order_return/i18n/it.po @@ -0,0 +1,243 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * pos_order_return +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 14.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2023-12-06 15:33+0000\n" +"Last-Translator: mymage \n" +"Language-Team: none\n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.17\n" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_product_product__pos_allow_negative_qty +#: model:ir.model.fields,field_description:pos_order_return.field_product_template__pos_allow_negative_qty +msgid "Allow Negative Quantity on PoS" +msgstr "Consenti quantità negativa su Pos" + +#. module: pos_order_return +#: model_terms:ir.ui.view,arch_db:pos_order_return.view_partial_return_wizard_form +msgid "Cancel" +msgstr "Annulla" + +#. module: pos_order_return +#: model:ir.model.fields,help:pos_order_return.field_pos_partial_return_wizard_line__max_returnable_qty +msgid "" +"Compute maximum quantity that can be returned for this line, depending of " +"the quantity of the line and other possible refunds." +msgstr "" +"Calcola la quantità massima che può essere restituita per questa riga, a " +"seconda della quantità della riga e di altri eventuali rimborsi." + +#. module: pos_order_return +#: model_terms:ir.ui.view,arch_db:pos_order_return.view_partial_return_wizard_form +msgid "Confirm" +msgstr "Conferma" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard__create_uid +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard_line__create_uid +msgid "Created by" +msgstr "Creato da" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard__create_date +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard_line__create_date +msgid "Created on" +msgstr "Creato il" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_order__display_name +#: model:ir.model.fields,field_description:pos_order_return.field_pos_order_line__display_name +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard__display_name +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard_line__display_name +#: model:ir.model.fields,field_description:pos_order_return.field_product_template__display_name +msgid "Display Name" +msgstr "Nome visualizzato" + +#. module: pos_order_return +#: code:addons/pos_order_return/models/pos_order.py:0 +#, python-format +msgid "" +"For legal and traceability reasons, you can not set a negative quantity (%d " +"%s of %s), without using return wizard." +msgstr "" +"Per motivi legali e di tracciabilità, non è possibile impostare una quantità " +"negativa (%d %s of %s), senza utilizzare la procedura guidata di " +"restituzione." + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_order__id +#: model:ir.model.fields,field_description:pos_order_return.field_pos_order_line__id +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard__id +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard_line__id +#: model:ir.model.fields,field_description:pos_order_return.field_product_template__id +msgid "ID" +msgstr "ID" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard_line__initial_qty +msgid "Initial Quantity" +msgstr "Quantità iniziale" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_order____last_update +#: model:ir.model.fields,field_description:pos_order_return.field_pos_order_line____last_update +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard____last_update +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard_line____last_update +#: model:ir.model.fields,field_description:pos_order_return.field_product_template____last_update +msgid "Last Modified on" +msgstr "Ultima modifica il" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard__write_uid +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard_line__write_uid +msgid "Last Updated by" +msgstr "Ultimo aggiornamento di" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard__write_date +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard_line__write_date +msgid "Last Updated on" +msgstr "Ultimo aggiornamento il" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard_line__pos_order_line_id +msgid "Line To Return" +msgstr "Riga da restituire" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard__line_ids +#: model_terms:ir.ui.view,arch_db:pos_order_return.view_partial_return_wizard_form +msgid "Lines to Return" +msgstr "Righe da restituire" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard__order_id +msgid "Order to Return" +msgstr "Ordine di reso" + +#. module: pos_order_return +#: model_terms:ir.ui.view,arch_db:pos_order_return.view_partial_return_wizard_form +#: model_terms:ir.ui.view,arch_db:pos_order_return.view_pos_order_form +msgid "Partial Return" +msgstr "Reso parziale" + +#. module: pos_order_return +#: model:ir.actions.act_window,name:pos_order_return.action_pos_partial_return_wizard +#: model:ir.model,name:pos_order_return.model_pos_partial_return_wizard +msgid "Partial Return Wizard" +msgstr "Procedura guidata reso parziale" + +#. module: pos_order_return +#: model:ir.model,name:pos_order_return.model_pos_partial_return_wizard_line +msgid "Partial Return Wizard Line" +msgstr "Riga procedura guidata reso parziale" + +#. module: pos_order_return +#: model:ir.model,name:pos_order_return.model_pos_order_line +msgid "Point of Sale Order Lines" +msgstr "Righe ordine punto vendita" + +#. module: pos_order_return +#: model:ir.model,name:pos_order_return.model_pos_order +msgid "Point of Sale Orders" +msgstr "Ordini punto vendita" + +#. module: pos_order_return +#: model:ir.model,name:pos_order_return.model_product_template +msgid "Product Template" +msgstr "Modello prodotto" + +#. module: pos_order_return +#: model:ir.model.fields,help:pos_order_return.field_pos_partial_return_wizard_line__initial_qty +msgid "Quantity of Product initially sold" +msgstr "Quantità di prodotto venduta inizialmente" + +#. module: pos_order_return +#: model_terms:ir.ui.view,arch_db:pos_order_return.view_pos_order_form +#: model_terms:ir.ui.view,arch_db:pos_order_return.view_pos_order_line_form +msgid "Refund" +msgstr "Rimborso" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_order_line__refund_orderline_ids +msgid "Refund Lines" +msgstr "Righe rimborso" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_order__refund_order_ids +msgid "Refund Orders" +msgstr "Ordini rimborso" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_order__refund_order_qty +msgid "Refund Orders Quantity" +msgstr "Quantità ordini rimborso" + +#. module: pos_order_return +#: code:addons/pos_order_return/models/pos_order.py:0 +#, python-format +msgid "Return of %s" +msgstr "Reso di %s" + +#. module: pos_order_return +#: model:product.product,name:pos_order_return.product_product_returnable_bottle +#: model:product.template,name:pos_order_return.product_product_returnable_bottle_product_template +msgid "Returnable Bottle" +msgstr "Bottiglia a rendere" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard_line__max_returnable_qty +msgid "Returnable Quantity" +msgstr "Quantità restituibile" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_order__returned_order_id +#: model:ir.model.fields,field_description:pos_order_return.field_pos_order_line__refunded_orderline_id +msgid "Returned Order" +msgstr "Ordine Restituito" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard_line__qty +msgid "Returned Quantity" +msgstr "Quantità restituita" + +#. module: pos_order_return +#: model:product.product,uom_name:pos_order_return.product_product_returnable_bottle +#: model:product.template,uom_name:pos_order_return.product_product_returnable_bottle_product_template +msgid "Units" +msgstr "Unità" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard_line__wizard_id +msgid "Wizard" +msgstr "Procedura guidata" + +#. module: pos_order_return +#: code:addons/pos_order_return/models/pos_order.py:0 +#, python-format +msgid "" +"You can not return %d %s of %s because some refunds have already been done.\n" +" Maximum quantity allowed : %d %s." +msgstr "" +"Non si può restituire %d %s di %s perché alcuni rimborsi sono già stati " +"effettuati.\n" +" Quantità massima consentita : %d %s." + +#. module: pos_order_return +#: code:addons/pos_order_return/models/pos_order.py:0 +#, python-format +msgid "" +"You can not return %d %s of %s because the original Order line only mentions " +"%d %s." +msgstr "" +"Non si può restituire %d %s of %s perché la riga dell'ordine originale " +"menziona solo %d %s." diff --git a/pos_order_return/i18n/pos_order_return.pot b/pos_order_return/i18n/pos_order_return.pot new file mode 100644 index 0000000000..20111b390f --- /dev/null +++ b/pos_order_return/i18n/pos_order_return.pot @@ -0,0 +1,219 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * pos_order_return +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 14.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_product_product__pos_allow_negative_qty +#: model:ir.model.fields,field_description:pos_order_return.field_product_template__pos_allow_negative_qty +msgid "Allow Negative Quantity on PoS" +msgstr "" + +#. module: pos_order_return +#: model_terms:ir.ui.view,arch_db:pos_order_return.view_partial_return_wizard_form +msgid "Cancel" +msgstr "" + +#. module: pos_order_return +#: model:ir.model.fields,help:pos_order_return.field_pos_partial_return_wizard_line__max_returnable_qty +msgid "" +"Compute maximum quantity that can be returned for this line, depending of " +"the quantity of the line and other possible refunds." +msgstr "" + +#. module: pos_order_return +#: model_terms:ir.ui.view,arch_db:pos_order_return.view_partial_return_wizard_form +msgid "Confirm" +msgstr "" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard__create_uid +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard_line__create_uid +msgid "Created by" +msgstr "" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard__create_date +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard_line__create_date +msgid "Created on" +msgstr "" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_order__display_name +#: model:ir.model.fields,field_description:pos_order_return.field_pos_order_line__display_name +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard__display_name +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard_line__display_name +#: model:ir.model.fields,field_description:pos_order_return.field_product_template__display_name +msgid "Display Name" +msgstr "" + +#. module: pos_order_return +#: code:addons/pos_order_return/models/pos_order.py:0 +#, python-format +msgid "" +"For legal and traceability reasons, you can not set a negative quantity (%d " +"%s of %s), without using return wizard." +msgstr "" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_order__id +#: model:ir.model.fields,field_description:pos_order_return.field_pos_order_line__id +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard__id +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard_line__id +#: model:ir.model.fields,field_description:pos_order_return.field_product_template__id +msgid "ID" +msgstr "" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard_line__initial_qty +msgid "Initial Quantity" +msgstr "" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_order____last_update +#: model:ir.model.fields,field_description:pos_order_return.field_pos_order_line____last_update +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard____last_update +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard_line____last_update +#: model:ir.model.fields,field_description:pos_order_return.field_product_template____last_update +msgid "Last Modified on" +msgstr "" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard__write_uid +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard_line__write_uid +msgid "Last Updated by" +msgstr "" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard__write_date +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard_line__write_date +msgid "Last Updated on" +msgstr "" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard_line__pos_order_line_id +msgid "Line To Return" +msgstr "" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard__line_ids +#: model_terms:ir.ui.view,arch_db:pos_order_return.view_partial_return_wizard_form +msgid "Lines to Return" +msgstr "" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard__order_id +msgid "Order to Return" +msgstr "" + +#. module: pos_order_return +#: model_terms:ir.ui.view,arch_db:pos_order_return.view_partial_return_wizard_form +#: model_terms:ir.ui.view,arch_db:pos_order_return.view_pos_order_form +msgid "Partial Return" +msgstr "" + +#. module: pos_order_return +#: model:ir.actions.act_window,name:pos_order_return.action_pos_partial_return_wizard +#: model:ir.model,name:pos_order_return.model_pos_partial_return_wizard +msgid "Partial Return Wizard" +msgstr "" + +#. module: pos_order_return +#: model:ir.model,name:pos_order_return.model_pos_partial_return_wizard_line +msgid "Partial Return Wizard Line" +msgstr "" + +#. module: pos_order_return +#: model:ir.model,name:pos_order_return.model_pos_order_line +msgid "Point of Sale Order Lines" +msgstr "" + +#. module: pos_order_return +#: model:ir.model,name:pos_order_return.model_pos_order +msgid "Point of Sale Orders" +msgstr "" + +#. module: pos_order_return +#: model:ir.model,name:pos_order_return.model_product_template +msgid "Product Template" +msgstr "" + +#. module: pos_order_return +#: model:ir.model.fields,help:pos_order_return.field_pos_partial_return_wizard_line__initial_qty +msgid "Quantity of Product initially sold" +msgstr "" + +#. module: pos_order_return +#: model_terms:ir.ui.view,arch_db:pos_order_return.view_pos_order_form +#: model_terms:ir.ui.view,arch_db:pos_order_return.view_pos_order_line_form +msgid "Refund" +msgstr "" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_order_line__refund_orderline_ids +msgid "Refund Lines" +msgstr "" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_order__refund_order_ids +msgid "Refund Orders" +msgstr "" + +#. module: pos_order_return +#: code:addons/pos_order_return/models/pos_order.py:0 +#, python-format +msgid "Return of %s" +msgstr "" + +#. module: pos_order_return +#: model:product.product,name:pos_order_return.product_product_returnable_bottle +#: model:product.template,name:pos_order_return.product_product_returnable_bottle_product_template +msgid "Returnable Bottle" +msgstr "" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard_line__max_returnable_qty +msgid "Returnable Quantity" +msgstr "" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard_line__qty +msgid "Returned Quantity" +msgstr "" + +#. module: pos_order_return +#: model:product.product,uom_name:pos_order_return.product_product_returnable_bottle +#: model:product.template,uom_name:pos_order_return.product_product_returnable_bottle_product_template +msgid "Units" +msgstr "" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard_line__wizard_id +msgid "Wizard" +msgstr "" + +#. module: pos_order_return +#: code:addons/pos_order_return/models/pos_order.py:0 +#, python-format +msgid "" +"You can not return %d %s of %s because some refunds have already been done.\n" +" Maximum quantity allowed : %d %s." +msgstr "" + +#. module: pos_order_return +#: code:addons/pos_order_return/models/pos_order.py:0 +#, python-format +msgid "" +"You can not return %d %s of %s because the original Order line only mentions" +" %d %s." +msgstr "" diff --git a/pos_order_return/i18n/pt.po b/pos_order_return/i18n/pt.po new file mode 100644 index 0000000000..83e54fe953 --- /dev/null +++ b/pos_order_return/i18n/pt.po @@ -0,0 +1,242 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * pos_order_return +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 14.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2021-09-20 13:34+0000\n" +"Last-Translator: Pedro Castro Silva \n" +"Language-Team: none\n" +"Language: pt\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n > 1;\n" +"X-Generator: Weblate 4.3.2\n" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_product_product__pos_allow_negative_qty +#: model:ir.model.fields,field_description:pos_order_return.field_product_template__pos_allow_negative_qty +msgid "Allow Negative Quantity on PoS" +msgstr "Permitir Quantidade Negativa no PdV" + +#. module: pos_order_return +#: model_terms:ir.ui.view,arch_db:pos_order_return.view_partial_return_wizard_form +msgid "Cancel" +msgstr "Cancelar" + +#. module: pos_order_return +#: model:ir.model.fields,help:pos_order_return.field_pos_partial_return_wizard_line__max_returnable_qty +msgid "" +"Compute maximum quantity that can be returned for this line, depending of " +"the quantity of the line and other possible refunds." +msgstr "" +"Calcular a quantidade máxima que pode ser devolvida para esta linha, " +"dependendo da quantidade da linha e outros possíveis reembolsos." + +#. module: pos_order_return +#: model_terms:ir.ui.view,arch_db:pos_order_return.view_partial_return_wizard_form +msgid "Confirm" +msgstr "Confirmar" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard__create_uid +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard_line__create_uid +msgid "Created by" +msgstr "Criado por" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard__create_date +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard_line__create_date +msgid "Created on" +msgstr "Criado em" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_order__display_name +#: model:ir.model.fields,field_description:pos_order_return.field_pos_order_line__display_name +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard__display_name +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard_line__display_name +#: model:ir.model.fields,field_description:pos_order_return.field_product_template__display_name +msgid "Display Name" +msgstr "Nome a Exibir" + +#. module: pos_order_return +#: code:addons/pos_order_return/models/pos_order.py:0 +#, python-format +msgid "" +"For legal and traceability reasons, you can not set a negative quantity (%d " +"%s of %s), without using return wizard." +msgstr "" +"Por razões legais e de rastreabilidade, você não pode definir uma quantidade " +"negativa (%d %s de %s), sem usar o assistente de retorno." + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_order__id +#: model:ir.model.fields,field_description:pos_order_return.field_pos_order_line__id +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard__id +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard_line__id +#: model:ir.model.fields,field_description:pos_order_return.field_product_template__id +msgid "ID" +msgstr "" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard_line__initial_qty +msgid "Initial Quantity" +msgstr "Quantidade Inicial" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_order____last_update +#: model:ir.model.fields,field_description:pos_order_return.field_pos_order_line____last_update +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard____last_update +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard_line____last_update +#: model:ir.model.fields,field_description:pos_order_return.field_product_template____last_update +msgid "Last Modified on" +msgstr "Última Modificação em" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard__write_uid +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard_line__write_uid +msgid "Last Updated by" +msgstr "Última Atualização por" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard__write_date +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard_line__write_date +msgid "Last Updated on" +msgstr "Última Atualização Em" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard_line__pos_order_line_id +msgid "Line To Return" +msgstr "Linha a Devolver" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard__line_ids +#: model_terms:ir.ui.view,arch_db:pos_order_return.view_partial_return_wizard_form +msgid "Lines to Return" +msgstr "Linhas a Devolver" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard__order_id +msgid "Order to Return" +msgstr "Pedido a Devolver" + +#. module: pos_order_return +#: model_terms:ir.ui.view,arch_db:pos_order_return.view_partial_return_wizard_form +#: model_terms:ir.ui.view,arch_db:pos_order_return.view_pos_order_form +msgid "Partial Return" +msgstr "Devolução Parcial" + +#. module: pos_order_return +#: model:ir.actions.act_window,name:pos_order_return.action_pos_partial_return_wizard +#: model:ir.model,name:pos_order_return.model_pos_partial_return_wizard +msgid "Partial Return Wizard" +msgstr "Assistente de Devolução Parcial" + +#. module: pos_order_return +#: model:ir.model,name:pos_order_return.model_pos_partial_return_wizard_line +msgid "Partial Return Wizard Line" +msgstr "Linha de Assistente de Devolução Parcial" + +#. module: pos_order_return +#: model:ir.model,name:pos_order_return.model_pos_order_line +msgid "Point of Sale Order Lines" +msgstr "Linhas de Pedidos do PdV" + +#. module: pos_order_return +#: model:ir.model,name:pos_order_return.model_pos_order +msgid "Point of Sale Orders" +msgstr "Pedidos do PdV" + +#. module: pos_order_return +#: model:ir.model,name:pos_order_return.model_product_template +msgid "Product Template" +msgstr "Modelo de Produto" + +#. module: pos_order_return +#: model:ir.model.fields,help:pos_order_return.field_pos_partial_return_wizard_line__initial_qty +msgid "Quantity of Product initially sold" +msgstr "Quantidade de Produto Inicialmente Vendida" + +#. module: pos_order_return +#: model_terms:ir.ui.view,arch_db:pos_order_return.view_pos_order_form +#: model_terms:ir.ui.view,arch_db:pos_order_return.view_pos_order_line_form +msgid "Refund" +msgstr "Reembolso" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_order_line__refund_orderline_ids +msgid "Refund Lines" +msgstr "Linhas de Reembolso" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_order__refund_order_ids +msgid "Refund Orders" +msgstr "Pedidos de Reembolso" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_order__refund_order_qty +msgid "Refund Orders Quantity" +msgstr "Quantidade de Pedidos de Reembolso" + +#. module: pos_order_return +#: code:addons/pos_order_return/models/pos_order.py:0 +#, python-format +msgid "Return of %s" +msgstr "Devolução de %s" + +#. module: pos_order_return +#: model:product.product,name:pos_order_return.product_product_returnable_bottle +#: model:product.template,name:pos_order_return.product_product_returnable_bottle_product_template +msgid "Returnable Bottle" +msgstr "Garrafa Retornável" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard_line__max_returnable_qty +msgid "Returnable Quantity" +msgstr "Quantidade Retornável" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_order__returned_order_id +#: model:ir.model.fields,field_description:pos_order_return.field_pos_order_line__refunded_orderline_id +msgid "Returned Order" +msgstr "Ordem Devolvida" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard_line__qty +msgid "Returned Quantity" +msgstr "Quantidade Devolvida" + +#. module: pos_order_return +#: model:product.product,uom_name:pos_order_return.product_product_returnable_bottle +#: model:product.template,uom_name:pos_order_return.product_product_returnable_bottle_product_template +msgid "Units" +msgstr "Unidades" + +#. module: pos_order_return +#: model:ir.model.fields,field_description:pos_order_return.field_pos_partial_return_wizard_line__wizard_id +msgid "Wizard" +msgstr "Assistente" + +#. module: pos_order_return +#: code:addons/pos_order_return/models/pos_order.py:0 +#, python-format +msgid "" +"You can not return %d %s of %s because some refunds have already been done.\n" +" Maximum quantity allowed : %d %s." +msgstr "" +"Você não pode devolver %d %s de %s porque algumas devoluções já foram " +"feitas.\n" +" Quantidade máxima permitida : %d %s." + +#. module: pos_order_return +#: code:addons/pos_order_return/models/pos_order.py:0 +#, python-format +msgid "" +"You can not return %d %s of %s because the original Order line only mentions " +"%d %s." +msgstr "" +"Você não pode retornar %d %s de %s porque a linha da ordem original menciona " +"apenas %d %s." diff --git a/pos_order_return/models/__init__.py b/pos_order_return/models/__init__.py new file mode 100644 index 0000000000..62041b9754 --- /dev/null +++ b/pos_order_return/models/__init__.py @@ -0,0 +1,4 @@ +from . import product_template +from . import pos_order +from . import pos_order_line +from . import stock_picking diff --git a/pos_order_return/models/pos_order.py b/pos_order_return/models/pos_order.py new file mode 100644 index 0000000000..44764b6348 --- /dev/null +++ b/pos_order_return/models/pos_order.py @@ -0,0 +1,54 @@ +# Copyright 2016-2018 Sylvain LE GAL (https://twitter.com/legalsylvain) +# Copyright 2018 David Vidal +# Copyright 2018 Lambda IS DOOEL +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +import logging + +from odoo import api, fields, models +from odoo.exceptions import UserError + +_logger = logging.getLogger(__name__) + + +class PosOrder(models.Model): + _inherit = "pos.order" + + refund_order_ids = fields.Many2many( + comodel_name="pos.order", + string="Refund Orders", + compute="_compute_refund_orders", + ) + + @api.depends("lines.refund_orderline_ids") + def _compute_refund_orders(self): + for order in self: + order.refund_order_ids = order.mapped("lines.refund_orderline_ids.order_id") + + def _action_pos_order_invoice(self): + """Wrap common process""" + self.action_pos_order_invoice() + + def action_pos_order_paid(self): + res = super().action_pos_order_paid() + if self.refunded_order_id.account_move: + # If the original order was invoiced, a refund invoice will be made. + self._action_pos_order_invoice() + return res + + def action_partial_refund(self): + """ + Opens a wizard to process a partial refund of the order. + """ + for order in self: + current_session = order.session_id.config_id.current_session_id + if not current_session: + raise UserError( + self.env._( + "To return product(s), you need to open a session in the POS %s", # noqa: E501 + order.session_id.config_id.display_name, + ) + ) + action = self.env["ir.actions.actions"]._for_xml_id( + "pos_order_return.action_pos_partial_return_wizard" + ) + return action diff --git a/pos_order_return/models/pos_order_line.py b/pos_order_return/models/pos_order_line.py new file mode 100644 index 0000000000..1fab317bdf --- /dev/null +++ b/pos_order_return/models/pos_order_line.py @@ -0,0 +1,57 @@ +# Copyright 2016-2018 Sylvain LE GAL (https://twitter.com/legalsylvain) +# Copyright 2018 David Vidal +# Copyright 2018 Lambda IS DOOEL +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +from odoo import api, models +from odoo.exceptions import ValidationError +from odoo.tools import float_is_zero + + +class PosOrderLine(models.Model): + _inherit = "pos.order.line" + + @api.constrains("refunded_orderline_id", "qty", "product_id") + def _check_return_qty(self): + if self.env.context.get("do_not_check_negative_qty", False): + return True + for line in self: + if ( + not line.refunded_orderline_id + and line.qty < 0 + and not line.product_id.product_tmpl_id.pos_allow_negative_qty + ): + raise ValidationError( + self.env._( + "For legal and traceability reasons, you can not set a" + " negative quantity (%d %s of %s), without using " + "return wizard.", + line.qty, + line.product_uom_id.name, + line.product_id.name, + ) + ) + + def _prepare_refund_data(self, refund_order, PosOrderLineLot): + """ + Update the returned qty by the value input from the return wizard + if it's less than returnable qty + """ + data = super()._prepare_refund_data(refund_order, PosOrderLineLot) + return_wizard = self.env.context.get("partial_return_wizard") + if isinstance(return_wizard, self.env["pos.partial.return.wizard"].__class__): + wizard_line = return_wizard.line_ids.filtered( + lambda _l, order_line=self: _l.pos_order_line_id == order_line + ) + if wizard_line: + data = self._prepare_refund_data_partial_line(data, wizard_line[0]) + + return data + + def _prepare_refund_data_partial_line(self, data, wizard_line): + qty = 0.0 + if not float_is_zero( + wizard_line.qty, precision_rounding=self.product_uom_id.rounding + ): + qty = max(data.get("qty", 0), wizard_line.qty * -1) + data.update({"qty": qty}) + return data diff --git a/pos_order_return/models/product_template.py b/pos_order_return/models/product_template.py new file mode 100644 index 0000000000..5cc802d203 --- /dev/null +++ b/pos_order_return/models/product_template.py @@ -0,0 +1,14 @@ +# Copyright 2016-2018 Sylvain LE GAL (https://twitter.com/legalsylvain) +# Copyright 2018 Lambda IS DOOEL +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import fields, models + + +class ProductTemplate(models.Model): + _inherit = "product.template" + + pos_allow_negative_qty = fields.Boolean( + string="Allow Negative Quantity on PoS", + default=True, + ) diff --git a/pos_order_return/models/stock_picking.py b/pos_order_return/models/stock_picking.py new file mode 100644 index 0000000000..320691491b --- /dev/null +++ b/pos_order_return/models/stock_picking.py @@ -0,0 +1,89 @@ +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +import logging + +from odoo import api, models + +_logger = logging.getLogger(__name__) + + +class StockPicking(models.Model): + _inherit = "stock.picking" + + @api.model + def _create_picking_from_pos_order_lines( + self, location_dest_id, lines, picking_type, partner=False + ): + """Odoo bases return picking if the quantities are negative, but it's + not linked to the original one""" + pickings = self.env["stock.picking"] + orders = lines.mapped("order_id") + # Case of POS Setting: Update qty in stock `in real time` + if len(orders) == 1 and orders.refunded_order_id.picking_ids: + negative_lines = lines.filtered( + lambda _l: _l.product_id.type == "consu" and _l.qty < 0 + ) + if negative_lines: + # Create picking for return order + returned_picking = self._create_return_picking_from_pos_order_lines( + negative_lines, orders.refunded_order_id.picking_ids + ) + if returned_picking: + returned_picking.write( + { + "pos_session_id": orders.session_id.id, + "pos_order_id": orders.id, + "origin": orders.name, + } + ) + pickings |= returned_picking + lines -= negative_lines + + # Case of POS Setting: Update qty in stock `At the session closing` + pickings |= super()._create_picking_from_pos_order_lines( + location_dest_id, lines, picking_type, partner + ) + return pickings + + @api.model + def _create_return_picking_from_pos_order_lines(self, order_lines, pickings): + """ + Create picking for return order by using stock return wizard + """ + wizard = self.env["stock.return.picking"].new( + { + "picking_id": pickings.filtered( + lambda picking: picking.location_dest_id.usage == "customer" + ).id + } + ) + # Discard not returned lines + wizard.product_return_moves.filtered( + lambda x: x.product_id not in order_lines.mapped("product_id") + ).unlink() + + # Sum return qty by product + to_return = {} + for order_line in order_lines: + to_return.setdefault(order_line.product_id, 0) + to_return[order_line.product_id] += abs(order_line.qty) + + # Update return qty of return wizard lines + for move in wizard.product_return_moves: + move.quantity = min(to_return[move.product_id], move.move_quantity) + to_return[move.product_id] -= move.quantity + + picking = self.env["stock.picking"] + # Avoid empty returns which will block the validation + if any(wizard.product_return_moves.mapped("quantity")): + picking = wizard._create_return() + picking.move_ids._add_mls_related_to_order(order_lines, are_qties_done=True) + picking.move_ids.picked = True + self.env.flush_all() + try: + with self.env.cr.savepoint(): + picking._action_done() + except Exception as err: + _logger.error( + "Validating the transfer '%s' failed: '%s'", picking.name, str(err) + ) + return picking diff --git a/pos_order_return/pyproject.toml b/pos_order_return/pyproject.toml new file mode 100644 index 0000000000..4231d0cccb --- /dev/null +++ b/pos_order_return/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/pos_order_return/readme/CONFIGURE.md b/pos_order_return/readme/CONFIGURE.md new file mode 100644 index 0000000000..7b9e15ec2e --- /dev/null +++ b/pos_order_return/readme/CONFIGURE.md @@ -0,0 +1,8 @@ +In some cases, you may want to block the possibility to allow negative +quantity in a PoS Order, without mentioning initial order. This can +happen for special products like returnable products, etc. + +In that case, a checkbox is possible on Product Form View to allow such +case + +![image1](../static/description/product_returnable_bottle.png) diff --git a/pos_order_return/readme/CONTRIBUTORS.md b/pos_order_return/readme/CONTRIBUTORS.md new file mode 100644 index 0000000000..738f725a1e --- /dev/null +++ b/pos_order_return/readme/CONTRIBUTORS.md @@ -0,0 +1,7 @@ +- Sylvain LE GAL \<\> +- David Vidal \<\> +- Kiril Vangelovski \<\> +- Druidoo \<\> +- Dhara Solanki \<\> +- [Trobz](https://www.trobz.com): + - Nguyen Minh Chien \<\> \ No newline at end of file diff --git a/pos_order_return/readme/CREDITS.md b/pos_order_return/readme/CREDITS.md new file mode 100644 index 0000000000..0b7a7ddc36 --- /dev/null +++ b/pos_order_return/readme/CREDITS.md @@ -0,0 +1,6 @@ +## Funders + +The development of this module has been financially supported by: + +- La Louve (www.lalouve.net) +- GRAP, Groupement Régional Alimentaire de Proximité (www.grap.coop) diff --git a/pos_order_return/readme/DESCRIPTION.md b/pos_order_return/readme/DESCRIPTION.md new file mode 100644 index 0000000000..3e76cf1359 --- /dev/null +++ b/pos_order_return/readme/DESCRIPTION.md @@ -0,0 +1,2 @@ +This module extends the functionality of odoo Point Of Sale about POS +Order returns. diff --git a/pos_order_return/readme/ROADMAP.md b/pos_order_return/readme/ROADMAP.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/pos_order_return/readme/USAGE.md b/pos_order_return/readme/USAGE.md new file mode 100644 index 0000000000..b3dcc83342 --- /dev/null +++ b/pos_order_return/readme/USAGE.md @@ -0,0 +1,24 @@ +Select an PoS Order and choose either *Return Products* (full return of +the order) or *Partial Return*. In this case, a wizard allows to select +just some products and quantities to return: + +![image2](../static/description/partial_return_wizard.png) + +Register the refund payment to finish the return. If the original order +was invoiced, a refund invoice will be made. + +**Implemented Constraints** + +- User can not return more products than the initial quantity: + +![image3](../static/description/returned_qty_over_initial.png) + +- If a line has been partially refund, only a reduced quantity can be + returned: + +![image4](../static/description/sum_returned_qty_over_initial.png) + +- It is not possible to set a negative quantity if the initial Pos Order + is not indicated: + +![image5](../static/description/initial_pos_order_required.png) diff --git a/pos_order_return/security/ir.model.access.csv b/pos_order_return/security/ir.model.access.csv new file mode 100644 index 0000000000..0e2ffab716 --- /dev/null +++ b/pos_order_return/security/ir.model.access.csv @@ -0,0 +1,3 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_pos_partial_return_wizard,pos_partial_return_wizard,model_pos_partial_return_wizard,base.group_user,1,1,1,1 +access_pos_partial_return_wizard_line,pos_partial_return_wizard_line,model_pos_partial_return_wizard_line,base.group_user,1,1,1,1 diff --git a/pos_order_return/static/description/icon.png b/pos_order_return/static/description/icon.png new file mode 100644 index 0000000000..3134d33e23 Binary files /dev/null and b/pos_order_return/static/description/icon.png differ diff --git a/pos_order_return/static/description/index.html b/pos_order_return/static/description/index.html new file mode 100644 index 0000000000..aed56ad422 --- /dev/null +++ b/pos_order_return/static/description/index.html @@ -0,0 +1,496 @@ + + + + + +Point of Sale Order Return + + + +
+

Point of Sale Order Return

+ + +

Alpha License: AGPL-3 OCA/pos Translate me on Weblate Try me on Runboat

+

This module extends the functionality of odoo Point Of Sale about POS +Order returns.

+
+

Important

+

This is an alpha version, the data model and design can change at any time without warning. +Only for development or testing purpose, do not use in production. +More details on development status

+
+

Table of contents

+ +
+

Configuration

+

In some cases, you may want to block the possibility to allow negative +quantity in a PoS Order, without mentioning initial order. This can +happen for special products like returnable products, etc.

+

In that case, a checkbox is possible on Product Form View to allow such +case

+

image1

+
+
+

Usage

+

Select an PoS Order and choose either Return Products (full return of +the order) or Partial Return. In this case, a wizard allows to select +just some products and quantities to return:

+

image2

+

Register the refund payment to finish the return. If the original order +was invoiced, a refund invoice will be made.

+

Implemented Constraints

+
    +
  • User can not return more products than the initial quantity:
  • +
+

image3

+
    +
  • If a line has been partially refund, only a reduced quantity can be +returned:
  • +
+

image4

+
    +
  • It is not possible to set a negative quantity if the initial Pos +Order is not indicated:
  • +
+

image5

+
+ +
+

Bug Tracker

+

Bugs are tracked on GitHub Issues. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +feedback.

+

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

+
+
+

Credits

+
+

Authors

+
    +
  • La Louve
  • +
  • GRAP
  • +
  • Tecnativa
  • +
  • Lambda IS
  • +
+
+
+

Contributors

+ +
+
+

Other credits

+
+

Funders

+

The development of this module has been financially supported by:

+ +
+
+
+

Maintainers

+

This module is maintained by the OCA.

+ +Odoo Community Association + +

OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use.

+

This module is part of the OCA/pos project on GitHub.

+

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

+
+
+
+ + diff --git a/pos_order_return/static/description/initial_pos_order_required.png b/pos_order_return/static/description/initial_pos_order_required.png new file mode 100644 index 0000000000..78ba8155b6 Binary files /dev/null and b/pos_order_return/static/description/initial_pos_order_required.png differ diff --git a/pos_order_return/static/description/partial_return_wizard.png b/pos_order_return/static/description/partial_return_wizard.png new file mode 100644 index 0000000000..7b266a2d4d Binary files /dev/null and b/pos_order_return/static/description/partial_return_wizard.png differ diff --git a/pos_order_return/static/description/product_returnable_bottle.png b/pos_order_return/static/description/product_returnable_bottle.png new file mode 100644 index 0000000000..fdb13d0e10 Binary files /dev/null and b/pos_order_return/static/description/product_returnable_bottle.png differ diff --git a/pos_order_return/static/description/returned_qty_over_initial.png b/pos_order_return/static/description/returned_qty_over_initial.png new file mode 100644 index 0000000000..089b76faf5 Binary files /dev/null and b/pos_order_return/static/description/returned_qty_over_initial.png differ diff --git a/pos_order_return/static/description/sum_returned_qty_over_initial.png b/pos_order_return/static/description/sum_returned_qty_over_initial.png new file mode 100644 index 0000000000..3c8bf079b6 Binary files /dev/null and b/pos_order_return/static/description/sum_returned_qty_over_initial.png differ diff --git a/pos_order_return/static/img/product_returnable_bottle-image.jpg b/pos_order_return/static/img/product_returnable_bottle-image.jpg new file mode 100644 index 0000000000..ff47420440 Binary files /dev/null and b/pos_order_return/static/img/product_returnable_bottle-image.jpg differ diff --git a/pos_order_return/tests/__init__.py b/pos_order_return/tests/__init__.py new file mode 100644 index 0000000000..3c43fd5674 --- /dev/null +++ b/pos_order_return/tests/__init__.py @@ -0,0 +1 @@ +from . import test_pos_order_return diff --git a/pos_order_return/tests/test_pos_order_return.py b/pos_order_return/tests/test_pos_order_return.py new file mode 100644 index 0000000000..d8fb558312 --- /dev/null +++ b/pos_order_return/tests/test_pos_order_return.py @@ -0,0 +1,306 @@ +# Copyright 2018 Tecnativa - David Vidal +# Copyright 2018 Lambda IS DOOEL +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +from odoo.tests import common, tagged + + +@tagged("post_install", "-at_install") +class TestPOSOrderReturn(common.TransactionCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.pricelist = cls.env["product.pricelist"].create( + { + "name": "Test pricelist", + "item_ids": [ + ( + 0, + 0, + { + "applied_on": "3_global", + "compute_price": "formula", + "base": "list_price", + }, + ) + ], + } + ) + cls.partner = cls.env["res.partner"].create( + { + "name": "Mr. Odoo", + "property_product_pricelist": cls.pricelist.id, + } + ) + cls.product_1 = cls.env["product.product"].create( + { + "name": "Test product 1", + "standard_price": 1.0, + "is_storable": True, + "pos_allow_negative_qty": False, + "taxes_id": False, + } + ) + cls.product_2 = cls.env["product.product"].create( + { + "name": "Test product 2", + "standard_price": 1.0, + "is_storable": True, + "pos_allow_negative_qty": True, + "taxes_id": False, + } + ) + cls.product_3 = cls.env["product.product"].create( + { + "name": "Test product 3", + "standard_price": 1.0, + "is_storable": True, + "pos_allow_negative_qty": True, + "taxes_id": False, + } + ) + cls.PosOrder = cls.env["pos.order"] + cls.PosOrderLine = cls.env["pos.order.line"] + cls.pos_config = cls.env.ref("point_of_sale.pos_config_main") + cls.pos_config.write( + { + "available_pricelist_ids": [(6, 0, cls.pricelist.ids)], + "pricelist_id": cls.pricelist.id, + } + ) + cls.pos_config.company_id.point_of_sale_update_stock_quantities = False + cls.pos_config.open_ui() + cls.pos_order = cls.PosOrder.create( + { + "session_id": cls.pos_config.current_session_id.id, + "partner_id": cls.partner.id, + "pricelist_id": cls.partner.property_product_pricelist.id, + "amount_tax": 0, + "amount_total": 1350, + "amount_paid": 1350, + "amount_return": 0, + "lines": [ + ( + 0, + 0, + { + "name": "POSLINE/0001", + "product_id": cls.product_1.id, + "price_unit": 225, + "price_subtotal": 450, + "price_subtotal_incl": 450, + "qty": 2.0, + }, + ), + ( + 0, + 0, + { + "name": "POSLINE/0002", + "product_id": cls.product_2.id, + "price_unit": 225, + "price_subtotal": 450, + "price_subtotal_incl": 450, + "qty": 2.0, + }, + ), + ( + 0, + 0, + { + "name": "POSLINE/0003", + "product_id": cls.product_1.id, + "price_unit": 225, + "price_subtotal": 450, + "price_subtotal_incl": 450, + "qty": 2.0, + }, + ), + ], + } + ) + pos_make_payment = ( + cls.env["pos.make.payment"] + .with_context( + **{ + "active_ids": [cls.pos_order.id], + "active_id": cls.pos_order.id, + } + ) + .create({}) + ) + pos_make_payment.with_context(active_id=cls.pos_order.id).check() + res = cls.pos_order.action_pos_order_invoice() + cls.invoice = cls.env["account.move"].browse(res["res_id"]) + + def test_pos_order_full_refund(self): + self.pos_order.refund() + refund_order = self.pos_order.refund_order_ids + self.assertEqual(len(refund_order), 1) + pos_make_payment = ( + self.env["pos.make.payment"] + .with_context( + **{ + "active_ids": refund_order.ids, + "active_id": refund_order.id, + } + ) + .create({}) + ) + pos_make_payment.with_context(active_id=refund_order.id).check() + refund_invoice = refund_order.account_move + refund_order.action_pos_order_invoice() + self.assertEqual(refund_invoice.reversed_entry_id, self.invoice) + # Partner balance is 0 + self.assertEqual(sum(self.partner.mapped("invoice_ids.amount_total_signed")), 0) + + def test_pos_order_partial_refund(self): + partial_refund = ( + self.env["pos.partial.return.wizard"] + .with_context( + **{ + "active_model": self.pos_order._name, + "active_ids": self.pos_order.ids, + "active_id": self.pos_order.id, + } + ) + .create({}) + ) + # Return just 1 item from line POSLINE/0001 + partial_refund.line_ids[0].qty = 1 + # Return 2 items from line POSLINE/0003 + partial_refund.line_ids[1].qty = 2 + partial_refund.confirm() + refund_order = self.pos_order.refund_order_ids + self.assertEqual(len(refund_order), 1) + self.assertEqual(len(refund_order.lines), 2) + pos_make_payment = ( + self.env["pos.make.payment"] + .with_context( + **{ + "active_ids": refund_order.ids, + "active_id": refund_order.id, + } + ) + .create({}) + ) + pos_make_payment.with_context(active_id=refund_order.id).check() + # Partner balance is 1350 + self.assertEqual( + sum(self.partner.mapped("invoice_ids.amount_total_signed")), 675.0 + ) + + def __new_sale(self, qty, lines_qty_to_return, new_product): + partial_refund = ( + self.env["pos.partial.return.wizard"] + .with_context( + **{ + "active_model": self.pos_order._name, + "active_ids": self.pos_order.ids, + "active_id": self.pos_order.id, + } + ) + .create({}) + ) + for line_index, return_qty in lines_qty_to_return: + partial_refund.line_ids[line_index].qty = return_qty + partial_refund.confirm() + refund_order = self.pos_order.refund_order_ids + # Customer exchanges 3 items for another product POSLINE/0004 + self.PosOrderLine.create( + { + "name": "POSLINE/0004", + "order_id": refund_order.id, + "product_id": new_product.id, + "price_unit": 225, + "price_subtotal": 225 * qty, + "price_subtotal_incl": 225 * qty, + "qty": qty, + } + ) + refund_order._onchange_amount_all() + pos_make_payment = ( + self.env["pos.make.payment"] + .with_context( + **{ + "active_ids": refund_order.ids, + "active_id": refund_order.id, + } + ) + .create({}) + ) + pos_make_payment.with_context(active_id=refund_order.id).check() + return refund_order + + def test_pos_order_full_refund_and_new_equal_sale(self): + # The customer exchanges 3 items for the same quantity of another product. + refund_order = self.__new_sale( + 3.0, + [ + (0, 1.0), # POSLINE/0001 + (2, 2.0), # POSLINE/0003 + ], + self.product_2, + ) + self.assertEqual(len(refund_order), 1) + self.assertEqual(len(refund_order.lines), 3) + self.assertEqual( + sum(self.partner.mapped("invoice_ids.amount_total_signed")), 1350.0 + ) + + def test_pos_order_full_refund_and_new_lower_sale(self): + # Customer exchanges 3 items for 2 of another product + refund_order = self.__new_sale( + 2.0, + [ + (0, 1.0), # POSLINE/0001 + (2, 2.0), # POSLINE/0003 + ], + self.product_2, + ) + self.assertEqual(len(refund_order), 1) + self.assertEqual(len(refund_order.lines), 3) + self.assertEqual( + sum(self.partner.mapped("invoice_ids.amount_total_signed")), 1125.0 + ) + + def test_pos_order_full_refund_and_new_higher_sale(self): + # Customer exchanges 3 items for 4 of another product. + refund_order = self.__new_sale( + 4.0, + [ + (0, 1.0), # POSLINE/0001 + (2, 2.0), # POSLINE/0003 + ], + self.product_2, + ) + self.assertEqual(len(refund_order), 1) + self.assertEqual(len(refund_order.lines), 3) + self.assertEqual( + sum(self.partner.mapped("invoice_ids.amount_total_signed")), 1575.0 + ) + + def test_pos_order_several_refund_and_new_sale(self): + # The customer refund an order placed through a previous refund. + refund_order = self.__new_sale( + 3.0, + [ + (0, 1.0), # POSLINE/0001 + (2, 2.0), # POSLINE/0003 + ], + self.product_2, + ) + self.assertEqual(len(refund_order), 1) + self.assertEqual(len(refund_order.lines), 3) + self.pos_order = self.PosOrder.search([], limit=1, order="id desc") + refund_order = self.__new_sale( + 5.0, + [ + (2, 3.0), # POSLINE/0004 + ], + self.product_3, + ) + self.assertEqual(len(refund_order), 1) + self.assertEqual(len(refund_order.lines), 2) + self.assertEqual( + sum(self.partner.mapped("invoice_ids.amount_total_signed")), 1800.0 + ) diff --git a/pos_order_return/views/pos_order_view.xml b/pos_order_return/views/pos_order_view.xml new file mode 100644 index 0000000000..b2262f102f --- /dev/null +++ b/pos_order_return/views/pos_order_view.xml @@ -0,0 +1,38 @@ + + + + + pos.order + + + + + + + + + + + + + + pos.order.line + + + + + + + + + + + diff --git a/pos_order_return/views/product_product_view.xml b/pos_order_return/views/product_product_view.xml new file mode 100644 index 0000000000..eeadcb9804 --- /dev/null +++ b/pos_order_return/views/product_product_view.xml @@ -0,0 +1,14 @@ + + + + + product.template + + + + + + + + diff --git a/pos_order_return/wizard/__init__.py b/pos_order_return/wizard/__init__.py new file mode 100644 index 0000000000..986e15d639 --- /dev/null +++ b/pos_order_return/wizard/__init__.py @@ -0,0 +1,2 @@ +from . import pos_partial_return_wizard +from . import pos_partial_return_wizard_line diff --git a/pos_order_return/wizard/pos_partial_return_wizard.py b/pos_order_return/wizard/pos_partial_return_wizard.py new file mode 100644 index 0000000000..f52994e038 --- /dev/null +++ b/pos_order_return/wizard/pos_partial_return_wizard.py @@ -0,0 +1,74 @@ +# Copyright 2016-2018 Sylvain LE GAL (https://twitter.com/legalsylvain) +# Copyright 2018 Lambda IS DOOEL +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import api, fields, models +from odoo.tools import float_is_zero + + +class PosPartialReturnWizard(models.TransientModel): + _name = "pos.partial.return.wizard" + _description = "Partial Return Wizard" + + order_id = fields.Many2one( + comodel_name="pos.order", + string="Order to Return", + ) + line_ids = fields.One2many( + comodel_name="pos.partial.return.wizard.line", + inverse_name="wizard_id", + string="Lines to Return", + ) + + def confirm(self): + # Set the context partial_return_wizard + # which is used in def _prepare_refund_data(..) + self.ensure_one() + refund_res = self.order_id.with_context(partial_return_wizard=self).refund() + + # Unlink the lines which are not selected from the wizard or zero qty + returned_order = self.env["pos.order"].browse(refund_res.get("res_id")) + if returned_order.exists(): + returned_lines = self.mapped("line_ids.pos_order_line_id") + lines = returned_order.lines.filtered( + lambda _l, rlines=returned_lines: ( + _l.refunded_orderline_id not in rlines + or float_is_zero( + _l.qty, precision_rounding=_l.product_uom_id.rounding + ) + ) + ) + if lines: + lines.unlink() + returned_order._compute_prices() + + return refund_res + + @api.model + def default_get(self, fields): + res = super().default_get(fields) + # Check to make sure the active_model is pos.order + if self.env.context.get("active_model") != "pos.order": + return res + + order = self.env["pos.order"].browse(self.env.context.get("active_id")) + if order.exists(): + line_ids = [] + for line in order.lines: + # Don't add the line which fully returned + if float_is_zero( + line.qty - line.refunded_qty, + precision_rounding=line.product_uom_id.rounding, + ): + continue + line_ids.append( + ( + 0, + 0, + { + "pos_order_line_id": line.id, + }, + ) + ) + res.update({"order_id": order.id, "line_ids": line_ids}) + return res diff --git a/pos_order_return/wizard/pos_partial_return_wizard_line.py b/pos_order_return/wizard/pos_partial_return_wizard_line.py new file mode 100644 index 0000000000..92969032a0 --- /dev/null +++ b/pos_order_return/wizard/pos_partial_return_wizard_line.py @@ -0,0 +1,82 @@ +# Copyright 2016-2018 Sylvain LE GAL (https://twitter.com/legalsylvain) +# Copyright 2018 Lambda IS DOOEL +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import api, fields, models +from odoo.exceptions import ValidationError +from odoo.tools import float_is_zero + + +class PosPartialReturnWizardLine(models.TransientModel): + _name = "pos.partial.return.wizard.line" + _description = "Partial Return Wizard Line" + + wizard_id = fields.Many2one( + comodel_name="pos.partial.return.wizard", + string="Wizard", + ) + pos_order_line_id = fields.Many2one( + comodel_name="pos.order.line", + required=True, + readonly=True, + string="Line To Return", + ) + initial_qty = fields.Float( + string="Initial Quantity", + digits="Product Unit of Measure", + help="Quantity of Product initially sold", + related="pos_order_line_id.qty", + ) + max_returnable_qty = fields.Float( + string="Returnable Quantity", + digits="Product Unit of Measure", + help="Compute maximum quantity that can be returned for this line, " + "depending of the quantity of the line and other possible " + "refunds.", + compute="_compute_max_returnable_qty", + ) + qty = fields.Float( + string="Returned Quantity", + digits="Product Unit of Measure", + ) + + @api.depends("pos_order_line_id") + def _compute_max_returnable_qty(self): + for line in self: + order_line = line.pos_order_line_id + line.max_returnable_qty = order_line.qty - order_line.refunded_qty + + @api.constrains("pos_order_line_id", "qty") + def _check_return_qty(self): + for line in self: + order_line = line.pos_order_line_id + if float_is_zero( + line.qty, precision_rounding=order_line.product_uom_id.rounding + ): + continue + + if line.qty > line.initial_qty: + raise ValidationError( + self.env._( + "You can not return %d %s of %s because the original " + "Order line only mentions %d %s.", + line.qty, + order_line.product_uom_id.name, + order_line.product_id.name, + line.initial_qty, + order_line.product_uom_id.name, + ) + ) + if line.qty > line.max_returnable_qty: + raise ValidationError( + self.env._( + "You can not return %d %s of %s because some refunds" + " have already been done.\n Maximum quantity allowed :" + " %d %s.", + line.qty, + order_line.product_uom_id.name, + order_line.product_id.name, + line.max_returnable_qty, + order_line.product_uom_id.name, + ) + ) diff --git a/pos_order_return/wizard/pos_partial_return_wizard_view.xml b/pos_order_return/wizard/pos_partial_return_wizard_view.xml new file mode 100644 index 0000000000..9cda604f0d --- /dev/null +++ b/pos_order_return/wizard/pos_partial_return_wizard_view.xml @@ -0,0 +1,36 @@ + + + + + pos.partial.return.wizard + +
+ + + + + + + + +
+
+
+
+
+ + Partial Return Wizard + ir.actions.act_window + pos.partial.return.wizard + form + new + +