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