Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[14.0][IMP] pos_disable_pricelist_selection: selectable pricelists #1110

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 21 additions & 5 deletions pos_disable_pricelist_selection/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Disable Pricelist selection button in POS
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:8f42c1529377cdb9437e7dcee3a0ac4dc559530e373e03662886e03e535f8251
!! source digest: sha256:b6d65b350b4dcc110d420a6ea344d211056ce9420fe3cda7b40f59db9c373ebc
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
Expand All @@ -28,19 +28,27 @@ Disable Pricelist selection button in POS

|badge1| |badge2| |badge3| |badge4| |badge5|

Disable Pricelist selection button in POS
This module allows to restrict POS interface user from selecting any or specific pricelists.

**Table of contents**

.. contents::
:local:

Use Cases / Context
===================

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.

Usage
=====

* 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".

Changelog
=========
Expand Down Expand Up @@ -88,6 +96,14 @@ 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-ilyasprogrammer| image:: https://github.com/ilyasprogrammer.png?size=40px
:target: https://github.com/ilyasprogrammer
:alt: ilyasprogrammer

Current `maintainer <https://odoo-community.org/page/maintainer-role>`__:

|maintainer-ilyasprogrammer|

This module is part of the `OCA/pos <https://github.com/OCA/pos/tree/14.0/pos_disable_pricelist_selection>`_ project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
1 change: 1 addition & 0 deletions pos_disable_pricelist_selection/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"license": "LGPL-3",
"category": "Purchase",
"website": "https://github.com/OCA/pos",
"maintainers": ["ilyasprogrammer"],
"depends": ["point_of_sale"],

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

chore: missing dependency on web_domain_field

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

web_domain_field is not required. Turns out compute domain thing works without web_domain_field. Just need to use Binary field.

Copy link

@aleuffre aleuffre Dec 20, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Huh, that's good to know. Thanks!

"external_dependencies": {},
"demo": [],
Expand Down
69 changes: 68 additions & 1 deletion pos_disable_pricelist_selection/models/pos_config.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,76 @@
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)]

Check warning on line 38 in pos_disable_pricelist_selection/models/pos_config.py

View check run for this annotation

Codecov / codecov/patch

pos_disable_pricelist_selection/models/pos_config.py#L38

Added line #L38 was not covered by tests
else:
rec.pricelist_id_domain = [
("id", "in", rec.selectable_pricelist_ids.ids)
]
Comment on lines +37 to +42

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

chore: Documentation of the web_domain_field recommends using json.dumps to make sure any edge case is handled properly.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couldn't find a way to cause an error, so considering this non-blocking.


@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})

Check warning on line 47 in pos_disable_pricelist_selection/models/pos_config.py

View check run for this annotation

Codecov / codecov/patch

pos_disable_pricelist_selection/models/pos_config.py#L47

Added line #L47 was not covered by tests

@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(

Check warning on line 57 in pos_disable_pricelist_selection/models/pos_config.py

View check run for this annotation

Codecov / codecov/patch

pos_disable_pricelist_selection/models/pos_config.py#L57

Added line #L57 was not covered by tests
{"selectable_pricelist_ids": [(6, 0, self.allowed_pricelist_ids.ids)]}
)

def write(self, vals):
for rec in self:
if vals.get("available_pricelist_ids"):
if rec and not vals.get("selectable_pricelist_ids"):
selectable = set(rec.selectable_pricelist_ids.ids)
else:
selectable = set(vals["selectable_pricelist_ids"][0][2])
# leave only ids from available_pricelist_ids
intersection = list(
selectable.intersection(set(vals["available_pricelist_ids"][0][2]))
)
if intersection:
vals["selectable_pricelist_ids"] = [(6, 0, intersection)]
else:
vals["selectable_pricelist_ids"] = vals["available_pricelist_ids"]
return super(PosConfig, self).write(vals)
1 change: 1 addition & 0 deletions pos_disable_pricelist_selection/readme/CONTEXT.rst
Original file line number Diff line number Diff line change
@@ -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.
2 changes: 1 addition & 1 deletion pos_disable_pricelist_selection/readme/DESCRIPTION.rst
Original file line number Diff line number Diff line change
@@ -1 +1 @@
Disable Pricelist selection button in POS
This module allows to restrict POS interface user from selecting any or specific pricelists.
9 changes: 6 additions & 3 deletions pos_disable_pricelist_selection/readme/USAGE.rst
Original file line number Diff line number Diff line change
@@ -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".
52 changes: 29 additions & 23 deletions pos_disable_pricelist_selection/static/description/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -367,75 +367,81 @@ <h1 class="title">Disable Pricelist selection button in POS</h1>
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:8f42c1529377cdb9437e7dcee3a0ac4dc559530e373e03662886e03e535f8251
!! source digest: sha256:b6d65b350b4dcc110d420a6ea344d211056ce9420fe3cda7b40f59db9c373ebc
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/lgpl-3.0-standalone.html"><img alt="License: LGPL-3" src="https://img.shields.io/badge/licence-LGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/pos/tree/14.0/pos_disable_pricelist_selection"><img alt="OCA/pos" src="https://img.shields.io/badge/github-OCA%2Fpos-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/pos-14-0/pos-14-0-pos_disable_pricelist_selection"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/pos&amp;target_branch=14.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
<p>Disable Pricelist selection button in POS</p>
<p>This module allows to restrict POS interface user from selecting any or specific pricelists.</p>
<p><strong>Table of contents</strong></p>
<div class="contents local topic" id="contents">
<ul class="simple">
<li><a class="reference internal" href="#usage" id="toc-entry-1">Usage</a></li>
<li><a class="reference internal" href="#changelog" id="toc-entry-2">Changelog</a><ul>
<li><a class="reference internal" href="#section-1" id="toc-entry-3">14.0.1.0.0</a></li>
<li><a class="reference internal" href="#use-cases-context" id="toc-entry-1">Use Cases / Context</a></li>
<li><a class="reference internal" href="#usage" id="toc-entry-2">Usage</a></li>
<li><a class="reference internal" href="#changelog" id="toc-entry-3">Changelog</a><ul>
<li><a class="reference internal" href="#section-1" id="toc-entry-4">14.0.1.0.0</a></li>
</ul>
</li>
<li><a class="reference internal" href="#bug-tracker" id="toc-entry-4">Bug Tracker</a></li>
<li><a class="reference internal" href="#credits" id="toc-entry-5">Credits</a><ul>
<li><a class="reference internal" href="#authors" id="toc-entry-6">Authors</a></li>
<li><a class="reference internal" href="#contributors" id="toc-entry-7">Contributors</a></li>
<li><a class="reference internal" href="#maintainers" id="toc-entry-8">Maintainers</a></li>
<li><a class="reference internal" href="#bug-tracker" id="toc-entry-5">Bug Tracker</a></li>
<li><a class="reference internal" href="#credits" id="toc-entry-6">Credits</a><ul>
<li><a class="reference internal" href="#authors" id="toc-entry-7">Authors</a></li>
<li><a class="reference internal" href="#contributors" id="toc-entry-8">Contributors</a></li>
<li><a class="reference internal" href="#maintainers" id="toc-entry-9">Maintainers</a></li>
</ul>
</li>
</ul>
</div>
<div class="section" id="use-cases-context">
<h1><a class="toc-backref" href="#toc-entry-1">Use Cases / Context</a></h1>
<p>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.</p>
</div>
<div class="section" id="usage">
<h1><a class="toc-backref" href="#toc-entry-1">Usage</a></h1>
<ul class="simple">
<li>In POS configuration enable multiple pricelists</li>
<li>There will be a checkbox “Hide Pricelist Button”</li>
<li>If checked pricelist selection button will be hidden in POS Screen</li>
</ul>
<h1><a class="toc-backref" href="#toc-entry-2">Usage</a></h1>
<p>In POS configuration, enable advanced pricelists and add all pricelists with reference to pricelists to be used in POS in “Available Pricelists”.</p>
<p>To restrict POS user from selecting any pricelist (therefore only use prices from “Default Pricelist”), enable boolean “Hide Pricelist Button”</p>
<p>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”.</p>
</div>
<div class="section" id="changelog">
<h1><a class="toc-backref" href="#toc-entry-2">Changelog</a></h1>
<h1><a class="toc-backref" href="#toc-entry-3">Changelog</a></h1>
<div class="section" id="section-1">
<h2><a class="toc-backref" href="#toc-entry-3">14.0.1.0.0</a></h2>
<h2><a class="toc-backref" href="#toc-entry-4">14.0.1.0.0</a></h2>
<ul class="simple">
<li>Initial release</li>
</ul>
</div>
</div>
<div class="section" id="bug-tracker">
<h1><a class="toc-backref" href="#toc-entry-4">Bug Tracker</a></h1>
<h1><a class="toc-backref" href="#toc-entry-5">Bug Tracker</a></h1>
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/pos/issues">GitHub Issues</a>.
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
<a class="reference external" href="https://github.com/OCA/pos/issues/new?body=module:%20pos_disable_pricelist_selection%0Aversion:%2014.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
<p>Do not contact contributors directly about support or help with technical issues.</p>
</div>
<div class="section" id="credits">
<h1><a class="toc-backref" href="#toc-entry-5">Credits</a></h1>
<h1><a class="toc-backref" href="#toc-entry-6">Credits</a></h1>
<div class="section" id="authors">
<h2><a class="toc-backref" href="#toc-entry-6">Authors</a></h2>
<h2><a class="toc-backref" href="#toc-entry-7">Authors</a></h2>
<ul class="simple">
<li>Ooops</li>
<li>Cetmix</li>
</ul>
</div>
<div class="section" id="contributors">
<h2><a class="toc-backref" href="#toc-entry-7">Contributors</a></h2>
<h2><a class="toc-backref" href="#toc-entry-8">Contributors</a></h2>
<ul class="simple">
<li>Ooops404 &lt;<a class="reference external" href="https://www.ooops404.com/">https://www.ooops404.com/</a>&gt;</li>
<li>Cetmix &lt;<a class="reference external" href="https://cetmix.com/">https://cetmix.com/</a>&gt;</li>
</ul>
</div>
<div class="section" id="maintainers">
<h2><a class="toc-backref" href="#toc-entry-8">Maintainers</a></h2>
<h2><a class="toc-backref" href="#toc-entry-9">Maintainers</a></h2>
<p>This module is maintained by the OCA.</p>
<a class="reference external image-reference" href="https://odoo-community.org"><img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" /></a>
<p>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.</p>
<p>Current <a class="reference external" href="https://odoo-community.org/page/maintainer-role">maintainer</a>:</p>
<p><a class="reference external image-reference" href="https://github.com/ilyasprogrammer"><img alt="ilyasprogrammer" src="https://github.com/ilyasprogrammer.png?size=40px" /></a></p>
<p>This module is part of the <a class="reference external" href="https://github.com/OCA/pos/tree/14.0/pos_disable_pricelist_selection">OCA/pos</a> project on GitHub.</p>
<p>You are welcome to contribute. To learn how please visit <a class="reference external" href="https://odoo-community.org/page/Contribute">https://odoo-community.org/page/Contribute</a>.</p>
</div>
Expand Down
31 changes: 31 additions & 0 deletions pos_disable_pricelist_selection/static/src/js/PosModel.js
Original file line number Diff line number Diff line change
@@ -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);
},
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
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() {
// Lets use selectable_pricelists instead of pricelists
const original_pricelists = this.env.pos.pricelists;
this.env.pos.pricelists = this.env.pos.selectable_pricelists;
super.onClick();
this.env.pos.pricelists = original_pricelists;
}
};

Registries.Component.extend(SetPricelistButton, SetPricelistButtonSelect);

return SetPricelistButtonSelect;
});
8 changes: 8 additions & 0 deletions pos_disable_pricelist_selection/views/assets.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@
type="text/javascript"
src="/pos_disable_pricelist_selection/static/src/js/ProductScreen.js"
/>
<script
type="text/javascript"
src="/pos_disable_pricelist_selection/static/src/js/PosModel.js"
/>
<script
type="text/javascript"
src="/pos_disable_pricelist_selection/static/src/js/SetPricelistButton.js"
/>
</xpath>
</template>
</odoo>
28 changes: 28 additions & 0 deletions pos_disable_pricelist_selection/views/pos_config_view.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,34 @@
<field name="hide_pricelist_button" />
</div>
</xpath>
<xpath expr="//field[@name='available_pricelist_ids']/.." position="after">
<div
class="row mt16"
attrs="{'invisible': [('hide_pricelist_button','=', True)]}"
>
<label
for="selectable_pricelist_ids"
class="col-lg-3 o_light_label"
/>
<field
name="selectable_pricelist_ids"
widget="many2many_tags"
attrs="{'required': [('hide_pricelist_button','=', False)]}"
/>
</div>
<div
class="text-muted"
attrs="{'invisible': [('hide_pricelist_button','=', True)]}"
>
Make sure Default Pricelist is within selectable pricelists.
</div>
</xpath>
<field name="pricelist_id" position="before">
<field name="pricelist_id_domain" invisible="1" />
</field>
<field name="pricelist_id" position="attributes">
<attribute name="domain">pricelist_id_domain</attribute>
</field>
</field>
</record>
</odoo>
Loading