diff --git a/sale_financial_risk_pos_compatibility/README.rst b/sale_financial_risk_pos_compatibility/README.rst new file mode 100644 index 0000000000..e69de29bb2 diff --git a/sale_financial_risk_pos_compatibility/__init__.py b/sale_financial_risk_pos_compatibility/__init__.py new file mode 100644 index 0000000000..0650744f6b --- /dev/null +++ b/sale_financial_risk_pos_compatibility/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/sale_financial_risk_pos_compatibility/__manifest__.py b/sale_financial_risk_pos_compatibility/__manifest__.py new file mode 100644 index 0000000000..36fceb7b61 --- /dev/null +++ b/sale_financial_risk_pos_compatibility/__manifest__.py @@ -0,0 +1,22 @@ +{ + "name": "Sale Financial Risk in POS", + "version": "16.0.1.0.0", + "category": "Sales/Point of Sale", + "summary": "Sale Financial Risk control for Sales Orders created from POS", + "depends": ["sale_financial_risk", "pos_order_to_sale_order"], + "website": "https://github.com/OCA/pos", + "author": "Cetmix,Odoo Community Association (OCA)", + "maintainers": ["geomer198", "CetmixGitDrone"], + "data": ["data/demo.xml"], + "installable": True, + "assets": { + "point_of_sale.assets": [ + "sale_financial_risk_pos_compatibility/static/src/js/*.esm.js", + "sale_financial_risk_pos_compatibility/static/src/xml/*.xml", + ], + "web.assets_tests": [ + "sale_financial_risk_pos_compatibility/static/src/tests/tours/SaleFinancialRiskPosCompatibility.tour.js", # noqa + ], + }, + "license": "AGPL-3", +} diff --git a/sale_financial_risk_pos_compatibility/data/demo.xml b/sale_financial_risk_pos_compatibility/data/demo.xml new file mode 100644 index 0000000000..9e0b7f9462 --- /dev/null +++ b/sale_financial_risk_pos_compatibility/data/demo.xml @@ -0,0 +1,10 @@ + + + + + Test Partner + 1.0 + 1.0 + + + diff --git a/sale_financial_risk_pos_compatibility/models/__init__.py b/sale_financial_risk_pos_compatibility/models/__init__.py new file mode 100644 index 0000000000..f7116e3d45 --- /dev/null +++ b/sale_financial_risk_pos_compatibility/models/__init__.py @@ -0,0 +1 @@ +from . import pos_session diff --git a/sale_financial_risk_pos_compatibility/models/pos_session.py b/sale_financial_risk_pos_compatibility/models/pos_session.py new file mode 100644 index 0000000000..973c7b5c05 --- /dev/null +++ b/sale_financial_risk_pos_compatibility/models/pos_session.py @@ -0,0 +1,13 @@ +from odoo import models + + +class PosSession(models.Model): + _inherit = "pos.session" + + def _get_pos_ui_res_users(self, params): + data = super()._get_pos_ui_res_users(params) + user = self.env["res.users"].browse(data["id"]) + data["has_role_risk_manager"] = user.has_group( + "account_financial_risk.group_overpass_partner_risk_exception", + ) + return data diff --git a/sale_financial_risk_pos_compatibility/readme/DESCRIPTION.rst b/sale_financial_risk_pos_compatibility/readme/DESCRIPTION.rst new file mode 100644 index 0000000000..4b92abe679 --- /dev/null +++ b/sale_financial_risk_pos_compatibility/readme/DESCRIPTION.rst @@ -0,0 +1,2 @@ +This module is a bridging module between **sale_financial_risk** and **pos_order_to_sale_order**. It implements control for the Sale Orders created from POS. +Same warning or blocking message will be displayed in POS as if an order was created from the backend. diff --git a/sale_financial_risk_pos_compatibility/static/img/desktop_table.jpg b/sale_financial_risk_pos_compatibility/static/img/desktop_table.jpg new file mode 100644 index 0000000000..7c8b939694 Binary files /dev/null and b/sale_financial_risk_pos_compatibility/static/img/desktop_table.jpg differ diff --git a/sale_financial_risk_pos_compatibility/static/src/js/ConfirmRiskPopup.esm.js b/sale_financial_risk_pos_compatibility/static/src/js/ConfirmRiskPopup.esm.js new file mode 100644 index 0000000000..66b1690927 --- /dev/null +++ b/sale_financial_risk_pos_compatibility/static/src/js/ConfirmRiskPopup.esm.js @@ -0,0 +1,13 @@ +/** @odoo-module **/ + +import ConfirmPopup from "point_of_sale.ConfirmPopup"; +import Registries from "point_of_sale.Registries"; + +export class ConfirmRiskPopup extends ConfirmPopup {} +ConfirmRiskPopup.template = "ConfirmRiskPopup"; +ConfirmRiskPopup.defaultProps = { + ...ConfirmPopup.defaultProps, + showButton: false, +}; + +Registries.Component.add(ConfirmRiskPopup); diff --git a/sale_financial_risk_pos_compatibility/static/src/js/CreateOrderPopup.esm.js b/sale_financial_risk_pos_compatibility/static/src/js/CreateOrderPopup.esm.js new file mode 100644 index 0000000000..18f20543cf --- /dev/null +++ b/sale_financial_risk_pos_compatibility/static/src/js/CreateOrderPopup.esm.js @@ -0,0 +1,88 @@ +/** @odoo-module **/ + +import CreateOrderPopup from "point_of_sale.CreateOrderPopup"; +import Registries from "point_of_sale.Registries"; +import framework from "web.framework"; + +export const CreateOrderPopupRisk = (CreateOrderPopup) => + class CreateOrderPopupRisk extends CreateOrderPopup { + async _createSaleOrder(order_state) { + if (order_state === "draft") { + return await super._createSaleOrder(order_state); + } + const order = this.env.pos.get_order(); + const risk_amount = + order.get_total_with_tax() + order.get_rounding_applied(); + const [partner] = await this.rpc({ + model: "res.partner", + method: "read", + args: [ + order.partner.id, + [ + "risk_exception", + "risk_sale_order_limit", + "risk_sale_order", + "risk_sale_order_include", + "risk_total", + "credit_limit", + ], + ], + }); + let exception_msg = ""; + if (partner.risk_exception) { + exception_msg = this.env._t("Financial risk exceeded.\n"); + } else if ( + partner.risk_sale_order_limit && + partner.risk_sale_order + risk_amount > partner.risk_sale_order_limit + ) { + exception_msg = this.env._t( + "This sale order exceeds the sales orders risk.\n" + ); + } else if ( + partner.risk_sale_order_include && + partner.risk_total + risk_amount > partner.credit_limit + ) { + exception_msg = this.env._t( + "This sale order exceeds the financial risk.\n" + ); + } else { + return await super._createSaleOrder(order_state); + } + const {confirmed} = await this.showPopup("ConfirmRiskPopup", { + title: "Partner risk exceeded", + body: exception_msg, + showButton: this.env.pos.user.has_role_risk_manager, + }); + if (confirmed) { + return await this._createSaleOrderWithConfirmedError( + order, + order_state + ); + } + } + + async _createSaleOrderWithConfirmedError(order, order_state) { + framework.blockUI(); + await this.rpc({ + model: "sale.order", + method: "create_order_from_pos", + args: [order.export_as_JSON(), order_state], + kwargs: {context: {bypass_risk: true}}, + }) + .catch(function (error) { + throw error; + }) + .finally(function () { + framework.unblockUI(); + }); + + // Delete current order + this.env.pos.removeOrder(order); + this.env.pos.add_new_order(); + + // Close popup + return await super.confirm(); + } + }; + +Registries.Component.extend(CreateOrderPopup, CreateOrderPopupRisk); diff --git a/sale_financial_risk_pos_compatibility/static/src/tests/tours/SaleFinancialRiskPosCompatibility.tour.js b/sale_financial_risk_pos_compatibility/static/src/tests/tours/SaleFinancialRiskPosCompatibility.tour.js new file mode 100644 index 0000000000..23e038721b --- /dev/null +++ b/sale_financial_risk_pos_compatibility/static/src/tests/tours/SaleFinancialRiskPosCompatibility.tour.js @@ -0,0 +1,94 @@ +odoo.define( + "sale_financial_risk_pos_compatibility.SaleFinancialRiskPosCompatibility", + function (require) { + "use strict"; + + const Tour = require("web_tour.tour"); + + const steps = [ + { + content: + "Test sale_financial_risk_pos_compatibility: Waiting for loading to finish", + trigger: "body:not(:has(.loader))", + // eslint-disable-next-line no-empty-function + run: () => {}, + }, + { + content: + "Test sale_financial_risk_pos_compatibility: Close Opening cashbox popup", + trigger: "div.opening-cash-control .button:contains('Open session')", + }, + { + content: + "Test sale_financial_risk_pos_compatibility: Leave category displayed by default", + trigger: ".breadcrumb-home", + // eslint-disable-next-line no-empty-function + run: () => {}, + }, + { + content: + "Test sale_financial_risk_pos_compatibility: Order a 'Whiteboard Pen' (price 3.20)", + trigger: ".product-list .product-name:contains('Whiteboard Pen')", + }, + { + content: + "Test sale_financial_risk_pos_compatibility: Click on 'Customer' Button", + trigger: "button.set-partner", + }, + { + content: + "Test sale_financial_risk_pos_compatibility: Select a customer 'Test Partner'", + trigger: "tr.partner-line td div:contains('Test Partner')", + }, + { + content: + "Test sale_financial_risk_pos_compatibility: Order set count 1", + trigger: ".numpad button.input-button:visible:contains('1')", + }, + { + content: + "Test sale_financial_risk_pos_compatibility: Order set count 0", + trigger: ".numpad button.input-button:visible:contains('0')", + }, + { + content: + "Test sale_financial_risk_pos_compatibility: Order set count 0", + trigger: ".numpad button.input-button:visible:contains('0')", + }, + { + content: + "Test sale_financial_risk_pos_compatibility: Click on 'Create Order' Button", + trigger: "span.control-button span:contains('Create Order')", + }, + { + content: + "Test sale_financial_risk_pos_compatibility: Click on 'Create Confirmed Sale Order' Button", + trigger: + "div.button-sale-order span:contains('Create Confirmed Sale Order')", + }, + { + content: + "Test sale_financial_risk_pos_compatibility: Confirm popup click on 'Ok' Button", + trigger: ".popup-confirm .footer div:contains('Ok')", + }, + { + content: + "Test sale_financial_risk_pos_compatibility: Close the Point of Sale frontend", + trigger: ".header-button", + }, + { + content: + "Test sale_financial_risk_pos_compatibility: Confirm closing the frontend", + trigger: ".header-button", + // eslint-disable-next-line no-empty-function + run: () => {}, + }, + ]; + + Tour.register( + "SaleFinancialRiskPosCompatibility", + {test: true, url: "/pos/ui"}, + steps + ); + } +); diff --git a/sale_financial_risk_pos_compatibility/static/src/xml/ConfirmRiskPopup.xml b/sale_financial_risk_pos_compatibility/static/src/xml/ConfirmRiskPopup.xml new file mode 100644 index 0000000000..b8e8ba6e39 --- /dev/null +++ b/sale_financial_risk_pos_compatibility/static/src/xml/ConfirmRiskPopup.xml @@ -0,0 +1,15 @@ + + + + + + props.showButton + + + + diff --git a/sale_financial_risk_pos_compatibility/tests/__init__.py b/sale_financial_risk_pos_compatibility/tests/__init__.py new file mode 100644 index 0000000000..d9b96c4fa5 --- /dev/null +++ b/sale_financial_risk_pos_compatibility/tests/__init__.py @@ -0,0 +1 @@ +from . import test_module diff --git a/sale_financial_risk_pos_compatibility/tests/test_module.py b/sale_financial_risk_pos_compatibility/tests/test_module.py new file mode 100644 index 0000000000..e99db5d812 --- /dev/null +++ b/sale_financial_risk_pos_compatibility/tests/test_module.py @@ -0,0 +1,15 @@ +from odoo.tests import tagged + +from odoo.addons.point_of_sale.tests.test_frontend import TestPointOfSaleHttpCommon + + +@tagged("post_install", "-at_install") +class TestUI(TestPointOfSaleHttpCommon): + def test_sale_financial_risk_pos_compatibility(self): + self.main_pos_config.open_ui() + + self.start_tour( + f"/pos/ui?config_id={self.main_pos_config.id}", + "SaleFinancialRiskPosCompatibility", + login="accountman", + ) diff --git a/setup/sale_financial_risk_pos_compatibility/odoo/addons/sale_financial_risk_pos_compatibility b/setup/sale_financial_risk_pos_compatibility/odoo/addons/sale_financial_risk_pos_compatibility new file mode 120000 index 0000000000..f494a185ad --- /dev/null +++ b/setup/sale_financial_risk_pos_compatibility/odoo/addons/sale_financial_risk_pos_compatibility @@ -0,0 +1 @@ +../../../../sale_financial_risk_pos_compatibility \ No newline at end of file diff --git a/setup/sale_financial_risk_pos_compatibility/setup.py b/setup/sale_financial_risk_pos_compatibility/setup.py new file mode 100644 index 0000000000..28c57bb640 --- /dev/null +++ b/setup/sale_financial_risk_pos_compatibility/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +) diff --git a/test-requirements.txt b/test-requirements.txt new file mode 100644 index 0000000000..75e3d78932 --- /dev/null +++ b/test-requirements.txt @@ -0,0 +1 @@ +odoo-addon-sale_financial_risk @ git+https://github.com/OCA/credit-control.git@refs/pull/280/head#subdirectory=setup/sale_financial_risk