diff --git a/pos_full_refund/README.rst b/pos_full_refund/README.rst new file mode 100644 index 0000000000..a7171e5ff0 --- /dev/null +++ b/pos_full_refund/README.rst @@ -0,0 +1,95 @@ +=========================== +Point of Sale - Full Refund +=========================== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:cc92aeed4d5986a6c3a0e7860d32d67c2aceec105975c3a9ffca2caab7ae128f + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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/16.0/pos_full_refund + :alt: OCA/pos +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/pos-16-0/pos-16-0-pos_full_refund + :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=16.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module adds a new button in the ticket screen of refund process to +automatically add every line of the selected order and returns to the +main screen. + +.. 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: + +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 +------- + +* Innovyou + +Contributors +------------ + +- [Innovyou] (https://www.innovyou.it): + + - Lorenzo Carta + - Lorenzo Battistini + - Valerio Paretta + +Maintainers +----------- + +This module is maintained by the OCA. + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +.. |maintainer-LorenzoC0| image:: https://github.com/LorenzoC0.png?size=40px + :target: https://github.com/LorenzoC0 + :alt: LorenzoC0 + +Current `maintainer `__: + +|maintainer-LorenzoC0| + +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_full_refund/__init__.py b/pos_full_refund/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/pos_full_refund/__manifest__.py b/pos_full_refund/__manifest__.py new file mode 100644 index 0000000000..95ee76678b --- /dev/null +++ b/pos_full_refund/__manifest__.py @@ -0,0 +1,22 @@ +{ + "name": "Point of Sale - Full Refund", + "summary": "Add button to easily perform full refunds in Point of Sale", + "author": "Innovyou, Odoo Community Association (OCA)", + "website": "https://github.com/OCA/pos", + "development_status": "Alpha", + "category": "Point of sale", + "maintainers": ["LorenzoC0"], + "version": "16.0.1.0.0", + "license": "AGPL-3", + "installable": True, + "depends": ["point_of_sale"], + "assets": { + "point_of_sale.assets": [ + "pos_full_refund/static/src/js/TicketScreen.esm.js", + "pos_full_refund/static/src/xml/pos_full_refund.xml", + ], + "web.assets_tests": [ + "pos_full_refund/static/tests/tours/PosFullRefund.tour.esm.js", + ], + }, +} diff --git a/pos_full_refund/pyproject.toml b/pos_full_refund/pyproject.toml new file mode 100644 index 0000000000..4231d0cccb --- /dev/null +++ b/pos_full_refund/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/pos_full_refund/readme/CONTRIBUTORS.md b/pos_full_refund/readme/CONTRIBUTORS.md new file mode 100644 index 0000000000..85e9d7f0dd --- /dev/null +++ b/pos_full_refund/readme/CONTRIBUTORS.md @@ -0,0 +1,4 @@ +- [Innovyou] (https://www.innovyou.it): + - Lorenzo Carta + - Lorenzo Battistini + - Valerio Paretta \ No newline at end of file diff --git a/pos_full_refund/readme/DESCRIPTION.md b/pos_full_refund/readme/DESCRIPTION.md new file mode 100644 index 0000000000..57c9eae980 --- /dev/null +++ b/pos_full_refund/readme/DESCRIPTION.md @@ -0,0 +1 @@ +This module adds a new button in the ticket screen of refund process to automatically add every line of the selected order and returns to the main screen. \ No newline at end of file diff --git a/pos_full_refund/static/description/index.html b/pos_full_refund/static/description/index.html new file mode 100644 index 0000000000..4f974ba82a --- /dev/null +++ b/pos_full_refund/static/description/index.html @@ -0,0 +1,438 @@ + + + + + +Point of Sale - Full Refund + + + +
+

Point of Sale - Full Refund

+ + +

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

+

This module adds a new button in the ticket screen of refund process to +automatically add every line of the selected order and returns to the +main screen.

+
+

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

+ +
+

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

+
    +
  • Innovyou
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

This module is maintained by the OCA.

+ +Odoo Community Association + +

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

+

Current maintainer:

+

LorenzoC0

+

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_full_refund/static/src/js/TicketScreen.esm.js b/pos_full_refund/static/src/js/TicketScreen.esm.js new file mode 100644 index 0000000000..1e89a9ba81 --- /dev/null +++ b/pos_full_refund/static/src/js/TicketScreen.esm.js @@ -0,0 +1,27 @@ +/** @odoo-module **/ + +import TicketScreen from "point_of_sale.TicketScreen"; +import {patch} from "@web/core/utils/patch"; + +patch(TicketScreen.prototype, "pos_full_refund.TicketScreen", { + onDoFullRefund() { + const order = this.getSelectedSyncedOrder(); + if (!order) { + return; + } + + // Set all orderlines to be fully refunded + // In Odoo 16, we use env.pos.toRefundLines instead of order.uiState.lineToRefund + for (const line of order.get_orderlines()) { + const refundableQty = line.get_quantity() - line.refunded_qty; + if (refundableQty > 0) { + // Get or create refund detail for this orderline + const toRefundDetail = this._getToRefundDetail(line); + toRefundDetail.qty = refundableQty; + } + } + + // Trigger the refund process + this._onDoRefund(); + }, +}); diff --git a/pos_full_refund/static/src/xml/pos_full_refund.xml b/pos_full_refund/static/src/xml/pos_full_refund.xml new file mode 100644 index 0000000000..2a95f113ad --- /dev/null +++ b/pos_full_refund/static/src/xml/pos_full_refund.xml @@ -0,0 +1,26 @@ + + + + + + + + + + diff --git a/pos_full_refund/static/tests/tours/PosFullRefund.tour.esm.js b/pos_full_refund/static/tests/tours/PosFullRefund.tour.esm.js new file mode 100644 index 0000000000..8d630c34b7 --- /dev/null +++ b/pos_full_refund/static/tests/tours/PosFullRefund.tour.esm.js @@ -0,0 +1,62 @@ +odoo.define("pos_full_refund.tour.PosFullRefundTour", function (require) { + const {ProductScreen} = require("point_of_sale.tour.ProductScreenTourMethods"); + const {PaymentScreen} = require("point_of_sale.tour.PaymentScreenTourMethods"); + const {ReceiptScreen} = require("point_of_sale.tour.ReceiptScreenTourMethods"); + const {TicketScreen} = require("point_of_sale.tour.TicketScreenTourMethods"); + const {getSteps, startSteps} = require("point_of_sale.tour.utils"); + var Tour = require("web_tour.tour"); + + startSteps(); + + // Start POS and open session + ProductScreen.do.confirmOpeningPopup(); + + // Create an order with multiple products + ProductScreen.exec.addOrderline("Desk Pad", "2", "5"); + ProductScreen.exec.addOrderline("Monitor Stand", "3", "4.5"); + ProductScreen.exec.addOrderline("Letter Tray", "1", "5"); + + // Verify the order has multiple lines by checking the selected orderline + ProductScreen.check.selectedOrderlineHas("Letter Tray", "1.0"); + + // Pay for the order + ProductScreen.do.clickPayButton(); + PaymentScreen.do.clickPaymentMethod("Bank"); + PaymentScreen.do.clickValidate(); + ReceiptScreen.check.isShown(); + ReceiptScreen.do.clickNextOrder(); + + // Go to refund mode + ProductScreen.do.clickRefund(); + + // Filter should be automatically 'Paid' + TicketScreen.check.filterIs("Paid"); + + // Select the order we just created + TicketScreen.do.selectOrder("-0001"); + + // Click the "Do Full Refund" button + getSteps().push({ + trigger: "#set_full_refund_button", + run: "click", + }); + + // Verify we're back on product screen with refund order + ProductScreen.check.isShown(); + + // Verify all lines are in the refund order with negative quantities + // We can check by selecting each line and verifying the quantity + ProductScreen.check.selectedOrderlineHas("Letter Tray", "-1.0"); + ProductScreen.do.clickOrderline("Desk Pad", "-2.0"); + ProductScreen.check.selectedOrderlineHas("Desk Pad", "-2.0"); + ProductScreen.do.clickOrderline("Monitor Stand", "-3.0"); + ProductScreen.check.selectedOrderlineHas("Monitor Stand", "-3.0"); + + // Complete the refund by paying + ProductScreen.do.clickPayButton(); + PaymentScreen.do.clickPaymentMethod("Bank"); + PaymentScreen.do.clickValidate(); + ReceiptScreen.check.isShown(); + + Tour.register("PosFullRefundTour", {test: true, url: "/pos/ui"}, getSteps()); +}); diff --git a/pos_full_refund/tests/__init__.py b/pos_full_refund/tests/__init__.py new file mode 100644 index 0000000000..0b3feafb34 --- /dev/null +++ b/pos_full_refund/tests/__init__.py @@ -0,0 +1 @@ +from . import test_pos_full_refund diff --git a/pos_full_refund/tests/test_pos_full_refund.py b/pos_full_refund/tests/test_pos_full_refund.py new file mode 100644 index 0000000000..1515e15e7c --- /dev/null +++ b/pos_full_refund/tests/test_pos_full_refund.py @@ -0,0 +1,35 @@ +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo.tests import tagged + +from odoo.addons.point_of_sale.tests.test_frontend import TestPointOfSaleHttpCommon + + +@tagged("post_install", "-at_install") +class TestPosFullRefund(TestPointOfSaleHttpCommon): + """Test the Full Refund functionality in POS. + + This test verifies that when a user clicks the "Do Full Refund" button + in the ticket screen, all lines from the selected order are automatically + added to a new refund order with their full quantities. + """ + + def test_pos_full_refund(self): + """Test that clicking 'Do Full Refund' creates a refund order with all lines.""" + # Open a POS session + self.main_pos_config.open_ui() + + # Start the tour that will: + # 1. Create an order with multiple products + # (Desk Pad, Monitor Stand, Letter Tray) + # 2. Pay for the order + # 3. Open refund mode + # 4. Select the paid order + # 5. Click "Do Full Refund" button + # 6. Verify all lines are in the refund order with negative quantities + # 7. Complete the refund payment + self.start_tour( + "/pos/ui?config_id=%d" % self.main_pos_config.id, + "PosFullRefundTour", + login="accountman", + ) diff --git a/setup/pos_full_refund/odoo/addons/pos_full_refund b/setup/pos_full_refund/odoo/addons/pos_full_refund new file mode 120000 index 0000000000..eb39aa1289 --- /dev/null +++ b/setup/pos_full_refund/odoo/addons/pos_full_refund @@ -0,0 +1 @@ +../../../../pos_full_refund \ No newline at end of file diff --git a/setup/pos_full_refund/setup.py b/setup/pos_full_refund/setup.py new file mode 100644 index 0000000000..28c57bb640 --- /dev/null +++ b/setup/pos_full_refund/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +)