mirror of
https://github.com/OCA/stock-logistics-warehouse.git
synced 2025-01-21 14:27:28 +02:00
[ADD] procurement_auto_create_group_by_product
This commit is contained in:
1
procurement_auto_create_group_by_product/README.rst
Normal file
1
procurement_auto_create_group_by_product/README.rst
Normal file
@@ -0,0 +1 @@
|
|||||||
|
will be generated by the boat
|
||||||
1
procurement_auto_create_group_by_product/__init__.py
Normal file
1
procurement_auto_create_group_by_product/__init__.py
Normal file
@@ -0,0 +1 @@
|
|||||||
|
from . import models
|
||||||
17
procurement_auto_create_group_by_product/__manifest__.py
Normal file
17
procurement_auto_create_group_by_product/__manifest__.py
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
# Copyright 2023 Jacques-Etienne Baudoux (BCIM) <je@bcim.be>
|
||||||
|
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||||
|
{
|
||||||
|
"name": "Procurement Auto Create Group By Product",
|
||||||
|
"version": "14.0.1.0.0",
|
||||||
|
"license": "AGPL-3",
|
||||||
|
"summary": "Generate one picking per product on the procurement run.",
|
||||||
|
"author": "BCIM, Odoo Community Association (OCA)",
|
||||||
|
"website": "https://github.com/OCA/stock-logistics-warehouse",
|
||||||
|
"category": "Warehouse",
|
||||||
|
"depends": ["procurement_auto_create_group"],
|
||||||
|
"data": [
|
||||||
|
"views/stock_rule.xml",
|
||||||
|
"views/procurement_group.xml",
|
||||||
|
],
|
||||||
|
"installable": True,
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
from . import stock_rule
|
||||||
|
from . import procurement_group
|
||||||
|
from . import product_product
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
# Copyright 2023 Jacques-Etienne Baudoux (BCIM) <je@bcim.be>
|
||||||
|
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||||
|
|
||||||
|
from odoo import fields, models
|
||||||
|
|
||||||
|
|
||||||
|
class ProcurementGroup(models.Model):
|
||||||
|
_inherit = "procurement.group"
|
||||||
|
|
||||||
|
product_id = fields.Many2one("product.product", index=True)
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
# Copyright 2023 Jacques-Etienne Baudoux (BCIM) <je@bcim.be>
|
||||||
|
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||||
|
|
||||||
|
from odoo import fields, models
|
||||||
|
|
||||||
|
|
||||||
|
class ProductProduct(models.Model):
|
||||||
|
_inherit = "product.product"
|
||||||
|
|
||||||
|
auto_create_procurement_group_ids = fields.One2many(
|
||||||
|
"procurement.group", "product_id"
|
||||||
|
)
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
# Copyright 2023 Jacques-Etienne Baudoux (BCIM) <je@bcim.be>
|
||||||
|
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||||
|
|
||||||
|
from odoo import fields, models
|
||||||
|
|
||||||
|
|
||||||
|
class StockRule(models.Model):
|
||||||
|
_inherit = "stock.rule"
|
||||||
|
|
||||||
|
auto_create_group_by_product = fields.Boolean(string="Procurement Group by Product")
|
||||||
|
|
||||||
|
def _get_auto_procurement_group(self, product):
|
||||||
|
if self.auto_create_group_by_product:
|
||||||
|
if product.auto_create_procurement_group_ids:
|
||||||
|
return fields.first(product.auto_create_procurement_group_ids)
|
||||||
|
return super()._get_auto_procurement_group(product)
|
||||||
|
|
||||||
|
def _prepare_auto_procurement_group_data(self, product):
|
||||||
|
result = super()._prepare_auto_procurement_group_data(product)
|
||||||
|
if self.auto_create_group_by_product:
|
||||||
|
result["product_id"] = product.id
|
||||||
|
result["partner_id"] = False
|
||||||
|
return result
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
#. Go to *Inventory / Configuration / Settings* and check the option
|
||||||
|
'Multi-Step Routes' and press the 'Save' button.
|
||||||
|
#. Activate the developer mode.
|
||||||
|
#. Go to *Inventory / Configuration / Warehouse Management / Routes*
|
||||||
|
and select the route you want to change. Select the rule you wish
|
||||||
|
to change, and in case of a Pull rule or Push & Pull rule Select
|
||||||
|
'Propagation of Procurement Group': 'Propagate'. The checkbox
|
||||||
|
'Auto-create Procurement Group' will then appear and you can set
|
||||||
|
it if you want to procurement group to be automatically created.
|
||||||
|
Activate also the checkbox 'Procurement Group by Product'.
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
* Jacques-Etienne Baudoux (BCIM) <je@bcim.be>
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
Allow to have one picking per product by using a procurement group per product
|
||||||
|
during the procurement run.
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
from . import test_auto_create_by_product
|
||||||
@@ -0,0 +1,110 @@
|
|||||||
|
# Copyright 2023 Jacques-Etienne Baudoux (BCIM) <je@bcim.be>
|
||||||
|
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||||
|
|
||||||
|
from odoo.addons.procurement_auto_create_group.tests.test_auto_create import (
|
||||||
|
TestProcurementAutoCreateGroup,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class TestProcurementAutoCreateGroupByProduct(TestProcurementAutoCreateGroup):
|
||||||
|
def test_pull_push_auto_create_group_not_by_product(self):
|
||||||
|
"""Test pull flow that without option to group by product"""
|
||||||
|
self.pull_push_rule_auto.auto_create_group_by_product = False
|
||||||
|
# Behavior should be the same
|
||||||
|
super(
|
||||||
|
TestProcurementAutoCreateGroupByProduct, self
|
||||||
|
).test_02_pull_push_auto_create_group()
|
||||||
|
|
||||||
|
def test_pull_push_auto_create_group_by_product(self):
|
||||||
|
"""Test pull flow that with option to group by product"""
|
||||||
|
self.pull_push_rule_auto.auto_create_group_by_product = True
|
||||||
|
move = self.move_obj.search([("product_id", "=", self.prod_auto_pull_push.id)])
|
||||||
|
self.assertFalse(move)
|
||||||
|
group = self.group_obj.search(
|
||||||
|
[("product_id", "=", self.prod_auto_pull_push.id)]
|
||||||
|
)
|
||||||
|
self.assertFalse(move)
|
||||||
|
self._procure(self.prod_auto_pull_push)
|
||||||
|
move = self.move_obj.search([("product_id", "=", self.prod_auto_pull_push.id)])
|
||||||
|
self.assertTrue(move)
|
||||||
|
self.assertTrue(move.group_id, "Procurement Group not assigned.")
|
||||||
|
self.assertEqual(
|
||||||
|
move.group_id.product_id,
|
||||||
|
self.prod_auto_pull_push,
|
||||||
|
"Procurement Group product missing.",
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
move.product_uom_qty,
|
||||||
|
5.0,
|
||||||
|
"Move invalid quantity.",
|
||||||
|
)
|
||||||
|
self._procure(self.prod_auto_pull_push)
|
||||||
|
group = self.group_obj.search(
|
||||||
|
[("product_id", "=", self.prod_auto_pull_push.id)]
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
len(group),
|
||||||
|
1,
|
||||||
|
"Procurement Group per product should be unique.",
|
||||||
|
)
|
||||||
|
# The second move should be merged with the previous one
|
||||||
|
self.assertEqual(
|
||||||
|
move.product_uom_qty,
|
||||||
|
10.0,
|
||||||
|
"Move invalid quantity.",
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_push_auto_create_group_not_by_product(self):
|
||||||
|
"""Test push flow that without option to group by product"""
|
||||||
|
self.push_rule_auto.auto_create_group_by_product = False
|
||||||
|
super(
|
||||||
|
TestProcurementAutoCreateGroupByProduct, self
|
||||||
|
).test_05_push_auto_create_group()
|
||||||
|
|
||||||
|
def test_push_auto_create_group_by_product(self):
|
||||||
|
"""Test push flow that with option to group by product"""
|
||||||
|
self.push_rule_auto.auto_create_group_by_product = True
|
||||||
|
move = self.move_obj.search(
|
||||||
|
[
|
||||||
|
("product_id", "=", self.prod_auto_push.id),
|
||||||
|
("location_dest_id", "=", self.loc_components.id),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
self.assertFalse(move)
|
||||||
|
self._push_trigger(self.prod_auto_push)
|
||||||
|
move = self.move_obj.search(
|
||||||
|
[
|
||||||
|
("product_id", "=", self.prod_auto_push.id),
|
||||||
|
("location_dest_id", "=", self.loc_components.id),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
self.assertTrue(move)
|
||||||
|
self.assertTrue(move.group_id, "Procurement Group not assigned.")
|
||||||
|
self.assertEqual(
|
||||||
|
move.group_id.product_id,
|
||||||
|
self.prod_auto_push,
|
||||||
|
"Procurement Group product missing.",
|
||||||
|
)
|
||||||
|
self._push_trigger(self.prod_auto_push)
|
||||||
|
group = self.group_obj.search([("product_id", "=", self.prod_auto_push.id)])
|
||||||
|
self.assertEqual(
|
||||||
|
len(group),
|
||||||
|
1,
|
||||||
|
"Procurement Group per product should be unique.",
|
||||||
|
)
|
||||||
|
move = self.move_obj.search(
|
||||||
|
[
|
||||||
|
("product_id", "=", self.prod_auto_push.id),
|
||||||
|
("location_dest_id", "=", self.loc_components.id),
|
||||||
|
]
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
len(move),
|
||||||
|
1,
|
||||||
|
"Invalid amount of moves.",
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
move.group_id.product_id,
|
||||||
|
self.prod_auto_push,
|
||||||
|
"Procurement Group product missing.",
|
||||||
|
)
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<odoo>
|
||||||
|
<record id="procurement_group_form_view" model="ir.ui.view">
|
||||||
|
<field name="name">procurement_auto_create_group_by_product</field>
|
||||||
|
<field name="model">procurement.group</field>
|
||||||
|
<field name="inherit_id" ref="stock.procurement_group_form_view" />
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<field name="move_type" position="after">
|
||||||
|
<field name="product_id" />
|
||||||
|
</field>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
</odoo>
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<odoo>
|
||||||
|
<record model="ir.ui.view" id="view_stock_rule_form">
|
||||||
|
<field
|
||||||
|
name="name"
|
||||||
|
>stock.rule.form - procurement_auto_create_group_by_product</field>
|
||||||
|
<field name="model">stock.rule</field>
|
||||||
|
<field
|
||||||
|
name="inherit_id"
|
||||||
|
ref="procurement_auto_create_group.view_stock_rule_form"
|
||||||
|
/>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<xpath
|
||||||
|
expr="//group[@name='propagation_group']/field[@name='auto_create_group']"
|
||||||
|
position="after"
|
||||||
|
>
|
||||||
|
<field
|
||||||
|
name="auto_create_group_by_product"
|
||||||
|
attrs="{'invisible':['|', ('auto_create_group','!=',True),('group_propagation_option','!=','propagate')]}"
|
||||||
|
/>
|
||||||
|
</xpath>
|
||||||
|
<xpath
|
||||||
|
expr="//group[field[@name='auto']]/field[@name='auto_create_group']"
|
||||||
|
position="after"
|
||||||
|
>
|
||||||
|
<field
|
||||||
|
name="auto_create_group_by_product"
|
||||||
|
attrs="{'invisible':['|',('auto_create_group','!=',True),('action','!=','push')]}"
|
||||||
|
/>
|
||||||
|
</xpath>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
</odoo>
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
../../../../procurement_auto_create_group_by_product
|
||||||
6
setup/procurement_auto_create_group_by_product/setup.py
Normal file
6
setup/procurement_auto_create_group_by_product/setup.py
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
import setuptools
|
||||||
|
|
||||||
|
setuptools.setup(
|
||||||
|
setup_requires=['setuptools-odoo'],
|
||||||
|
odoo_addon=True,
|
||||||
|
)
|
||||||
Reference in New Issue
Block a user