diff --git a/pos_disable_pricelist_selection/models/pos_config.py b/pos_disable_pricelist_selection/models/pos_config.py index 50931cfba1..185f2a9e80 100644 --- a/pos_disable_pricelist_selection/models/pos_config.py +++ b/pos_disable_pricelist_selection/models/pos_config.py @@ -1,9 +1,75 @@ -from odoo import fields, models +from odoo import api, fields, models class PosConfig(models.Model): _inherit = "pos.config" + def _default_pricelist(self): + return self.env["product.pricelist"].search( + [ + ("company_id", "in", (False, self.env.company.id)), + ("currency_id", "=", self.env.company.currency_id.id), + ], + limit=1, + ) + hide_pricelist_button = fields.Boolean( default=False, ) + selectable_pricelist_ids = fields.Many2many( + "product.pricelist", + string="Selectable Pricelists", + domain="[('id', 'in', available_pricelist_ids)]", + relation="pos_conf_selectable_pricelist_rel", + default=_default_pricelist, + ) + pricelist_id_domain = fields.Binary( + compute="_compute_pricelist_id_domain", + readonly=True, + store=False, + ) + + @api.depends( + "hide_pricelist_button", "allowed_pricelist_ids", "selectable_pricelist_ids" + ) + def _compute_pricelist_id_domain(self): + for rec in self: + if rec.hide_pricelist_button: + rec.pricelist_id_domain = [("id", "in", rec.allowed_pricelist_ids.ids)] + else: + rec.pricelist_id_domain = [ + ("id", "in", rec.selectable_pricelist_ids.ids) + ] + + @api.onchange("selectable_pricelist_ids") + def onchange_selectable_pricelist_ids(self): + if self.pricelist_id.id not in self.selectable_pricelist_ids.ids: + self.update({"pricelist_id": self.selectable_pricelist_ids[0].id}) + + @api.onchange("available_pricelist_ids") + def onchange_available_pricelist_ids(self): + self.update( + {"selectable_pricelist_ids": [(6, 0, self.allowed_pricelist_ids.ids)]} + ) + + @api.onchange("hide_pricelist_button") + def onchange_hide_pricelist_button(self): + self.update( + {"selectable_pricelist_ids": [(6, 0, self.allowed_pricelist_ids.ids)]} + ) + + def write(self, vals): + if vals.get("available_pricelist_ids"): + if self and not vals.get("selectable_pricelist_ids"): + selectable = set(self.selectable_pricelist_ids.ids) + else: + selectable = set(vals["selectable_pricelist_ids"][0][2]) + # leave only ids from available_pricelist_ids + diff = list( + selectable.intersection(set(vals["available_pricelist_ids"][0][2])) + ) + if diff: + vals["selectable_pricelist_ids"] = [(6, 0, diff)] + else: + vals["selectable_pricelist_ids"] = vals["available_pricelist_ids"] + return super(PosConfig, self).write(vals) diff --git a/pos_disable_pricelist_selection/readme/CONTEXT.rst b/pos_disable_pricelist_selection/readme/CONTEXT.rst new file mode 100644 index 0000000000..b9b54049db --- /dev/null +++ b/pos_disable_pricelist_selection/readme/CONTEXT.rst @@ -0,0 +1 @@ +In case there is a structure of pricelists with lines using "Formula: Based on" (eg: Pricelist 3 is based on Pricelist 2 which is based on Pricelist 1) they all need to be added in "Available pricelists" for POS to load correctly. diff --git a/pos_disable_pricelist_selection/readme/DESCRIPTION.rst b/pos_disable_pricelist_selection/readme/DESCRIPTION.rst index 7261337ab1..32ec7c81fb 100644 --- a/pos_disable_pricelist_selection/readme/DESCRIPTION.rst +++ b/pos_disable_pricelist_selection/readme/DESCRIPTION.rst @@ -1 +1 @@ -Disable Pricelist selection button in POS +This module allows to restrict POS interface user from selecting any or specific pricelists. diff --git a/pos_disable_pricelist_selection/readme/USAGE.rst b/pos_disable_pricelist_selection/readme/USAGE.rst index e4ee197bca..96d094d178 100644 --- a/pos_disable_pricelist_selection/readme/USAGE.rst +++ b/pos_disable_pricelist_selection/readme/USAGE.rst @@ -1,3 +1,6 @@ -* In POS configuration enable multiple pricelists -* There will be a checkbox "Hide Pricelist Button" -* If checked pricelist selection button will be hidden in POS Screen +In POS configuration, enable advanced pricelists and add all pricelists with reference to pricelists to be used in POS in "Available Pricelists". + +To restrict POS user from selecting any pricelist (therefore only use prices from "Default Pricelist"), enable boolean "Hide Pricelist Button" + +To restrict POS user's pricelist selection to a set of pricelists, add them to "Selectable Pricelists". +Note: make sure "Default Pricelist" is among "Selectable Pricelists". diff --git a/pos_disable_pricelist_selection/static/src/js/PosModel.js b/pos_disable_pricelist_selection/static/src/js/PosModel.js new file mode 100644 index 0000000000..c43ea44652 --- /dev/null +++ b/pos_disable_pricelist_selection/static/src/js/PosModel.js @@ -0,0 +1,31 @@ +odoo.define("pos_disable_pricelist_selection.PosModel", function (require) { + "use strict"; + + var models = require("point_of_sale.models"); + var posmodel_super = models.PosModel.prototype; + + models.PosModel = models.PosModel.extend({ + load_server_data: function () { + this.models.push({ + model: "product.pricelist", + fields: ["name", "display_name", "discount_policy"], + domain: function (self) { + if (self.config.use_pricelist) { + if (self.config.hide_pricelist_button) { + return [["id", "in", self.config.available_pricelist_ids]]; + } + return [["id", "in", self.config.selectable_pricelist_ids]]; + } + return [["id", "=", self.config.pricelist_id[0]]]; + }, + loaded: function (self, pricelists) { + _.map(pricelists, function (pricelist) { + pricelist.items = []; + }); + self.selectable_pricelists = pricelists; + }, + }); + return posmodel_super.load_server_data.apply(this, arguments); + }, + }); +}); diff --git a/pos_disable_pricelist_selection/static/src/js/SetPricelistButton.js b/pos_disable_pricelist_selection/static/src/js/SetPricelistButton.js new file mode 100644 index 0000000000..3c3270443e --- /dev/null +++ b/pos_disable_pricelist_selection/static/src/js/SetPricelistButton.js @@ -0,0 +1,37 @@ +odoo.define("pos_disable_pricelist_selection.SetPricelistButton", function (require) { + "use strict"; + + const SetPricelistButton = require("point_of_sale.SetPricelistButton"); + const Registries = require("point_of_sale.Registries"); + + const SetPricelistButtonSelect = (SetPricelistButton) => + class extends SetPricelistButton { + async onClick() { + // Replaced to use selectable_pricelists instead of pricelists + const selectionList = this.env.pos.selectable_pricelists.map( + (pricelist) => ({ + id: pricelist.id, + label: pricelist.name, + isSelected: pricelist.id === this.currentOrder.pricelist.id, + item: pricelist, + }) + ); + + const {confirmed, payload: selectedPricelist} = await this.showPopup( + "SelectionPopup", + { + title: this.env._t("Select the pricelist"), + list: selectionList, + } + ); + + if (confirmed) { + this.currentOrder.set_pricelist(selectedPricelist); + } + } + }; + + Registries.Component.extend(SetPricelistButton, SetPricelistButtonSelect); + + return SetPricelistButtonSelect; +}); diff --git a/pos_disable_pricelist_selection/views/assets.xml b/pos_disable_pricelist_selection/views/assets.xml index e4cde6aab1..71c8a04a1b 100644 --- a/pos_disable_pricelist_selection/views/assets.xml +++ b/pos_disable_pricelist_selection/views/assets.xml @@ -6,6 +6,14 @@ type="text/javascript" src="/pos_disable_pricelist_selection/static/src/js/ProductScreen.js" /> + + diff --git a/pos_disable_pricelist_selection/views/pos_config_view.xml b/pos_disable_pricelist_selection/views/pos_config_view.xml index ae6a5c24ec..ef053f4092 100644 --- a/pos_disable_pricelist_selection/views/pos_config_view.xml +++ b/pos_disable_pricelist_selection/views/pos_config_view.xml @@ -18,6 +18,34 @@ + + + + + + + Make sure Default Pricelist is within selectable pricelists. + + + + + + + pricelist_id_domain +