mirror of
https://github.com/OCA/stock-logistics-warehouse.git
synced 2025-01-21 14:27:28 +02:00
[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:
@@ -0,0 +1 @@
|
||||
../../../../stock_inventory_preparation_filter_pos
|
||||
6
setup/stock_inventory_preparation_filter_pos/setup.py
Normal file
6
setup/stock_inventory_preparation_filter_pos/setup.py
Normal file
@@ -0,0 +1,6 @@
|
||||
import setuptools
|
||||
|
||||
setuptools.setup(
|
||||
setup_requires=['setuptools-odoo'],
|
||||
odoo_addon=True,
|
||||
)
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
1
stock_inventory_preparation_filter_pos/README.rst
Normal file
1
stock_inventory_preparation_filter_pos/README.rst
Normal file
@@ -0,0 +1 @@
|
||||
Will be generated from readme subdir
|
||||
1
stock_inventory_preparation_filter_pos/__init__.py
Normal file
1
stock_inventory_preparation_filter_pos/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from . import models
|
||||
17
stock_inventory_preparation_filter_pos/__manifest__.py
Normal file
17
stock_inventory_preparation_filter_pos/__manifest__.py
Normal 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,
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
from . import stock_inventory
|
||||
@@ -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
|
||||
@@ -0,0 +1 @@
|
||||
* Alexis de Lattre <alexis.delattre@akretion.com>
|
||||
@@ -0,0 +1 @@
|
||||
with this module, when you create an inventory, you can filter the inventory on one or several point of sale categories.
|
||||
3
stock_inventory_preparation_filter_pos/readme/USAGE.rst
Normal file
3
stock_inventory_preparation_filter_pos/readme/USAGE.rst
Normal 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.
|
||||
1
stock_inventory_preparation_filter_pos/tests/__init__.py
Normal file
1
stock_inventory_preparation_filter_pos/tests/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from . import test_preparation_filter_pos
|
||||
@@ -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()
|
||||
@@ -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>
|
||||
Reference in New Issue
Block a user