[ADD] stock_inventory_preparation_filter_pos: filter inventory on POS categs

This module replaces the module stock_inventory_pos_category proposed in
this PR for odoo v10: https://github.com/OCA/stock-logistics-warehouse/pull/393

Adapt stock_inventory_preparation_filter to allow inheritance by adding
a prepare method
This commit is contained in:
Alexis de Lattre
2021-08-25 15:24:35 +02:00
parent dfbe5ac7e8
commit 6bc9fa515f
15 changed files with 192 additions and 13 deletions

View File

@@ -0,0 +1 @@
../../../../stock_inventory_preparation_filter_pos

View File

@@ -0,0 +1,6 @@
import setuptools
setuptools.setup(
setup_requires=['setuptools-odoo'],
odoo_addon=True,
)

View File

@@ -52,18 +52,26 @@ class StockInventory(models.Model):
product_domain = fields.Char("Domain", default=[("name", "ilike", "")])
def _action_start(self):
Product = self.env["product.product"]
for inventory in self:
products = Product.browse()
if inventory.state != "draft":
continue
if inventory.filter == "categories":
products = Product.search([("categ_id", "in", inventory.categ_ids.ids)])
if inventory.filter == "lots":
products = inventory.lot_ids.mapped("product_id")
if inventory.filter == "domain":
domain = safe_eval(inventory.product_domain)
products = Product.search(domain)
if products:
inventory.product_ids = [(6, 0, products.ids)]
if inventory.filter:
products = inventory._prepare_inventory_filter()
if products:
inventory.product_ids = [(6, 0, products.ids)]
return super()._action_start()
def _prepare_inventory_filter(self):
# This method is designed to be inherited by other modules
# such as the OCA module stock_inventory_preparation_filter_pos
self.ensure_one()
Product = self.env["product.product"]
products = Product
if self.filter == "categories":
products = Product.search([("categ_id", "in", self.categ_ids.ids)])
elif self.filter == "lots":
products = self.lot_ids.product_id
elif self.filter == "domain":
domain = safe_eval(self.product_domain)
products = Product.search(domain)
return products

View File

@@ -34,12 +34,12 @@
<field
name="categ_ids"
widget="many2many_tags"
attrs="{'invisible':[('filter','!=','categories')]}"
attrs="{'invisible':[('filter','!=','categories')], 'required': [('filter','=','categories')]}"
/>
<field
name="lot_ids"
widget="many2many_tags"
attrs="{'invisible':[('filter','!=','lots')]}"
attrs="{'invisible':[('filter','!=','lots')], 'required': [('filter','=','lots')]}"
/>
</field>
</field>

View File

@@ -0,0 +1 @@
Will be generated from readme subdir

View File

@@ -0,0 +1 @@
from . import models

View File

@@ -0,0 +1,17 @@
# Copyright 2021 Akretion France (http://www.akretion.com/)
# @author: Alexis de Lattre <alexis.delattre@akretion.com>
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
{
"name": "Inventory Preparation Filters POS",
"version": "14.0.1.0.0",
"license": "AGPL-3",
"summary": "Add POS category filter on inventory adjustments",
"depends": ["stock_inventory_preparation_filter", "point_of_sale"],
"author": "Akretion, Odoo Community Association (OCA)",
"maintainers": ["alexis-via"],
"category": "Inventory, Logistic, Storage",
"website": "https://github.com/OCA/stock-logistics-warehouse",
"data": ["views/stock_inventory.xml"],
"installable": True,
}

View File

@@ -0,0 +1 @@
from . import stock_inventory

View File

@@ -0,0 +1,32 @@
# Copyright 2021 Akretion France (http://www.akretion.com/)
# @author: Alexis de Lattre <alexis.delattre@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import _, api, fields, models
class StockInventory(models.Model):
_inherit = "stock.inventory"
pos_categ_ids = fields.Many2many(
"pos.category",
string="Point of Sale Categories",
readonly=True,
states={"draft": [("readonly", False)]},
)
@api.model
def _selection_filter(self):
res_filter = super()._selection_filter()
res_filter.insert(
-1, ("pos_categories", _("Selected Point of Sale Categories"))
)
return res_filter
def _prepare_inventory_filter(self):
products = super()._prepare_inventory_filter()
if self.filter == "pos_categories":
products = self.env["product.product"].search(
[("pos_categ_id", "child_of", self.pos_categ_ids.ids)]
)
return products

View File

@@ -0,0 +1 @@
* Alexis de Lattre <alexis.delattre@akretion.com>

View File

@@ -0,0 +1 @@
with this module, when you create an inventory, you can filter the inventory on one or several point of sale categories.

View File

@@ -0,0 +1,3 @@
Go to the menu *Inventory > Operations > Inventory Adjustments*, create a new inventory, choose **Selected Point of Sale Categories** and then select the point of sale categories that you want to filter on.
Note that, if you select a parent point of sale category, Odoo will also select the products attached to the children point of sale categories.

View File

@@ -0,0 +1 @@
from . import test_preparation_filter_pos

View File

@@ -0,0 +1,80 @@
# Copyright 2021 Akretion France (http://www.akretion.com/)
# @author: Alexis de Lattre <alexis.delattre@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo.tests import common
class TestStockInventoryPreparationFilterPos(common.TransactionCase):
def setUp(self):
super().setUp()
self.location = self.env.ref("stock.stock_location_stock")
ppo = self.env["product.product"]
pcateg_id = self.env["product.category"].create({"name": "Test1"}).id
self.pos_categ1 = self.env["pos.category"].create({"name": "Test POS Categ"})
self.pos_categ2 = self.env["pos.category"].create(
{"name": "Test POS Categ2", "parent_id": self.pos_categ1.id}
)
# Create products
self.product1 = ppo.create(
{
"name": "Product POS test1",
"type": "product",
"categ_id": pcateg_id,
"pos_categ_id": self.pos_categ1.id,
}
)
self.product2 = ppo.create(
{
"name": "Product POS test2",
"type": "product",
"categ_id": pcateg_id,
"pos_categ_id": self.pos_categ1.id,
}
)
self.product3 = ppo.create(
{
"name": "Product POS test3",
"type": "product",
"categ_id": pcateg_id,
"pos_categ_id": self.pos_categ2.id,
}
)
# Add stock levels for these products
self.env["stock.quant"].create(
[
{
"product_id": self.product1.id,
"product_uom_id": self.product1.uom_id.id,
"location_id": self.location.id,
"quantity": 42.0,
},
{
"product_id": self.product2.id,
"product_uom_id": self.product2.uom_id.id,
"location_id": self.location.id,
"quantity": 43.0,
},
{
"product_id": self.product3.id,
"product_uom_id": self.product3.uom_id.id,
"location_id": self.location.id,
"quantity": 44.0,
},
]
)
def test_inventory_filter_pos(self):
inventory = self.env["stock.inventory"].create(
{
"name": "Test POS filter",
"filter": "pos_categories",
"pos_categ_ids": [(6, 0, self.pos_categ1.ids)],
}
)
inventory.action_start()
# We make sure that the products of children categs are also included
self.assertEqual(len(inventory.product_ids), 3)
self.assertEqual(len(inventory.line_ids), 3)
inventory.action_cancel_draft()

View File

@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8" ?>
<!--
Copyright 2021 Akretion France (http://www.akretion.com/)
@author: Alexis de Lattre <alexis.delattre@akretion.com>
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
-->
<odoo>
<record id="view_inventory_form" model="ir.ui.view">
<field name="model">stock.inventory</field>
<field
name="inherit_id"
ref="stock_inventory_preparation_filter.view_inventory_form"
/>
<field name="arch" type="xml">
<field name="categ_ids" position="after">
<field
name="pos_categ_ids"
widget="many2many_tags"
attrs="{'invisible': [('filter', '!=', 'pos_categories')], 'required': [('filter', '=', 'pos_categories')]}"
/>
</field>
</field>
</record>
</odoo>