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

[16.0] [ADD] pos_product_available - Available products for each POS #1194

Open
wants to merge 9 commits into
base: 16.0
Choose a base branch
from
Open
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
48 changes: 48 additions & 0 deletions pos_product_available/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
===============================================
Point of Sale - Products Available for each POS
===============================================

Description
===========

This module is responsible for assigning the products available for sale to each Point of Sale.
To assign the products to each Point of Sale, a new configuration has been added to the products to set the Points of Sale where they can be sold.

Configuration
=============

In the configuration of each product, in the Point of Sale section, there is a new option where you can assign all the Points of Sale where it should be available.
To configure each Point of Sale to only display the products that have been assigned to it, you will need to go into the Point of Sale settings and activate the option called "Available products". Once activated, all the products that are configured to appear at that Point of Sale will be listed below.

Credits
=======

Authors
~~~~~~~

* Carlos Franco Cifuentes, Esment

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-legalsylvain| image:: https://github.com/cfrancoae.png?size=40px
:target: https://github.com/cfrancoae
:alt: cfrancoae

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

|maintainer-legalsylvain|

This module is part of the `OCA/pos <https://github.com/OCA/pos/tree/16.0/pos_minimize_menu>`_ 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_product_available/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import models
19 changes: 19 additions & 0 deletions pos_product_available/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"name": "Point of Sale Products Available",
"summary": """Visible products for each different Point of Sale""",
"category": "Point Of Sale",
"author": "Carlos Franco Cifuentes, Esment, Odoo Community Association (OCA)",
"website": "https://github.com/OCA/pos",
"version": "16.0.0.1.0",
"license": "AGPL-3",
"depends": ["product", "point_of_sale"],
"data": [
"views/product_view.xml",
"views/res_config_settings_view.xml",
],
"assets": {
"point_of_sale.assets": [
"pos_product_available/static/src/js/Screens/ProductScreen/ProductsWidget.js",
],
},
}
49 changes: 49 additions & 0 deletions pos_product_available/i18n/es.po
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * pos_product_available
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 13.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-11-16 10:17+0000\n"
"PO-Revision-Date: 2023-11-16 11:18+0100\n"
"Last-Translator: \n"
"Language-Team: \n"
"Language: es\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Poedit 3.4\n"

#. module: pos_product_available
#: model:ir.model.fields,field_description:pos_product_available.field_pos_config__available_product
msgid "Available Product"
msgstr "Productos Disponibles"

#. module: pos_product_available
#: model:ir.model.fields,field_description:pos_product_available.field_product_product__pos_center_ids
#: model:ir.model.fields,field_description:pos_product_available.field_product_template__pos_center_ids
msgid "POS Available"
msgstr "PDV Disponibles"

#. module: pos_product_available
#: model:ir.model,name:pos_product_available.model_pos_config
msgid "Point of Sale Config Visible Products"
msgstr ""

#. module: pos_product_available
#: model:ir.model,name:pos_product_available.model_product_template
msgid "Point of Sale Visible Product"
msgstr ""

#. module: pos_product_available
#: model_terms:ir.ui.view,arch_db:pos_product_available.pos_config_view_form
msgid "Products available for this Point of Sale"
msgstr "Productos disponibles para este Punto de Venta"

#. module: pos_product_available
#: model:ir.model.fields,field_description:pos_product_available.field_pos_config__available_product_ids
msgid "Restrict products for this point of sale"
msgstr "Restringir productos para este punto de venta"
3 changes: 3 additions & 0 deletions pos_product_available/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from . import product
from . import res_config_settings
from . import pos_session
23 changes: 23 additions & 0 deletions pos_product_available/models/pos_session.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from odoo import models
from odoo.osv.expression import AND


class PosSession(models.Model):
_inherit = "pos.session"

def _loader_params_product_product(self):
result = super(PosSession, self)._loader_params_product_product()
if self.config_id.available_product and self.config_id.available_product_ids:
result["search_params"]["domain"] = AND(
[
result["search_params"]["domain"],
[
(
"product_tmpl_id",
"in",
self.config_id.available_product_ids.ids,
)
],
]
)
return result
8 changes: 8 additions & 0 deletions pos_product_available/models/product.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from odoo import fields, models


class ProductTemplate(models.Model):
_inherit = "product.template"
_description = "Point of Sale Visible Product"

pos_center_ids = fields.Many2many("pos.config", string="POS Available", store=True)
37 changes: 37 additions & 0 deletions pos_product_available/models/res_config_settings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
from odoo import api, fields, models


class PosConfig(models.Model):
_inherit = "pos.config"

available_product = fields.Boolean()
available_product_ids = fields.Many2many(
comodel_name="product.template",
string="Restrict products for this point of sale",
)


class ResConfigSettings(models.TransientModel):
_inherit = "res.config.settings"
_description = "Point of Sale Config Visible Products"

pos_available_product = fields.Boolean(
related="pos_config_id.available_product", readonly=False
)
pos_available_product_ids = fields.Many2many(
"product.template",
string="Restrict products for this point of sale",
compute="_compute_pos_available_product_ids",
readonly=False,
store=True,
)

@api.depends("pos_available_product", "pos_config_id")
def _compute_pos_available_product_ids(self):
for res_config in self:
if not res_config.pos_available_product:
res_config.pos_available_product_ids = False
else:
res_config.pos_available_product_ids = (
res_config.pos_config_id.available_product_ids
)
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
../../../../pos_product_available
6 changes: 6 additions & 0 deletions pos_product_available/pos_product_available/setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import setuptools

setuptools.setup(
setup_requires=["setuptools-odoo"],
odoo_addon=True,
)
1 change: 1 addition & 0 deletions pos_product_available/readme/CONTRIBUTORS.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* Carlos Franco Cifuentes ([email protected])
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
odoo.define("pos_product_available.ProductsWidget", function (require) {
"use strict";

var ProductsWidget = require("point_of_sale.ProductsWidget");
const Registries = require("point_of_sale.Registries");

const PosProductsAvailableWidget = (ProductsWidget) =>
class extends ProductsWidget {
get productsToDisplay() {
let list = [];
let products = [];
const available_product = this.env.pos.config.available_product;
console.log(available_product);
const available_product_ids = this.env.pos.config.available_product_ids;
if (this.searchWord !== "") {
if (available_product == true) {
products = this.env.pos.db.search_product_in_category(
this.selectedCategoryId,
this.searchWord
);
products.forEach(function (product) {
available_product_ids.forEach(function (product_available) {
if (product.product_tmpl_id == product_available) {
list.push(product);
}
});
});
} else {
list = this.env.pos.db.search_product_in_category(
this.selectedCategoryId,
this.searchWord
);
}
} else if (available_product == true) {
products = this.env.pos.db.get_product_by_category(
this.selectedCategoryId
);
list = products.filter((product) =>
available_product_ids.includes(product.product_tmpl_id)
);
} else {
list = this.env.pos.db.get_product_by_category(
this.selectedCategoryId
);
}
return list.sort(function (a, b) {
return a.display_name.localeCompare(b.display_name);
});
}
};

Registries.Component.extend(ProductsWidget, PosProductsAvailableWidget);

return ProductsWidget;
});
1 change: 1 addition & 0 deletions pos_product_available/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import test_pos_session, test_product, test_res_config_settings
52 changes: 52 additions & 0 deletions pos_product_available/tests/test_pos_session.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
from odoo.tests.common import TransactionCase


class TestPosSession(TransactionCase):
def setUp(self):
super(TestPosSession, self).setUp()

# Create a test product template
self.product_template = self.env["product.template"].create(
{
"name": "Test Product",
}
)

# Create test POS configurations
self.pos_config_1 = self.env["pos.config"].create(
{
"name": "POS Config 1",
"available_product": True,
"available_product_ids": [(6, 0, [self.product_template.id])],
}
)

# Create a test POS session
self.pos_session = self.env["pos.session"].create(
{
"config_id": self.pos_config_1.id,
}
)

def test__loader_params_product_product_with_available_product(self):
"""Test the _loader_params_product_product method when available_product is True."""
result = self.pos_session._loader_params_product_product()

# Check if the domain is set correctly
self.assertIn(
("product_tmpl_id", "in", self.pos_config_1.available_product_ids.ids),
result["search_params"]["domain"],
)

def test__loader_params_product_product_without_available_product(self):
"""Test the _loader_params_product_product method when available_product is False."""
# Set available_product to False
self.pos_config_1.available_product = False

result = self.pos_session._loader_params_product_product()

# Check if the domain is not modified
self.assertNotIn(
("product_tmpl_id", "in", self.pos_config_1.available_product_ids.ids),
result["search_params"]["domain"],
)
42 changes: 42 additions & 0 deletions pos_product_available/tests/test_product.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
from odoo.tests.common import TransactionCase


class TestProductTemplate(TransactionCase):
def setUp(self):
super(TestProductTemplate, self).setUp()

# Create a test product template
self.product_template = self.env["product.template"].create(
{
"name": "Test Product",
}
)

# Create test POS configurations
self.pos_config_1 = self.env["pos.config"].create(
{
"name": "POS Config 1",
}
)
self.pos_config_2 = self.env["pos.config"].create(
{
"name": "POS Config 2",
}
)

def test_pos_center_ids_field_exists(self):
"""Test the pos_center_ids field exists in the product.template model."""
self.assertIn("pos_center_ids", self.product_template._fields)

def test_pos_center_ids_field_empty_by_default(self):
"""Test the pos_center_ids field is empty by default."""
self.assertFalse(self.product_template.pos_center_ids)

def test_pos_center_ids_field_can_be_set(self):
"""Test the pos_center_ids field can be set."""
self.product_template.pos_center_ids = [
(6, 0, [self.pos_config_1.id, self.pos_config_2.id])
]
self.assertEqual(
self.product_template.pos_center_ids, self.pos_config_1 | self.pos_config_2
)
Loading
Loading