mirror of
https://github.com/OCA/stock-logistics-warehouse.git
synced 2025-01-21 14:27:28 +02:00
[IMP] stock_orderpoint_route: black, isort
This commit is contained in:
@@ -2,20 +2,13 @@
|
||||
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).
|
||||
{
|
||||
"name": "Stock Orderpoint Route",
|
||||
"summary": "Allows to force a route to be used when procuring from "
|
||||
"orderpoints",
|
||||
"summary": "Allows to force a route to be used when procuring from orderpoints",
|
||||
"version": "12.0.1.0.0",
|
||||
"license": "LGPL-3",
|
||||
"website": "https://github.com/stock-logistics-warehouse",
|
||||
"author": "Eficent, "
|
||||
"Camptocamp, "
|
||||
"Odoo Community Association (OCA)",
|
||||
"author": "Eficent, Camptocamp, Odoo Community Association (OCA)",
|
||||
"category": "Warehouse",
|
||||
"depends": [
|
||||
"stock",
|
||||
],
|
||||
"data": [
|
||||
"views/stock_warehouse_orderpoint_views.xml",
|
||||
],
|
||||
"depends": ["stock"],
|
||||
"data": ["views/stock_warehouse_orderpoint_views.xml"],
|
||||
"installable": True,
|
||||
}
|
||||
|
||||
@@ -5,30 +5,29 @@ from odoo import api, fields, models
|
||||
|
||||
|
||||
class StockWarehouseOrderpoint(models.Model):
|
||||
_inherit = 'stock.warehouse.orderpoint'
|
||||
_inherit = "stock.warehouse.orderpoint"
|
||||
|
||||
route_ids = fields.Many2many(
|
||||
'stock.location.route', string='Allowed routes',
|
||||
compute='_compute_route_ids',
|
||||
"stock.location.route", string="Allowed routes", compute="_compute_route_ids"
|
||||
)
|
||||
route_id = fields.Many2one(
|
||||
"stock.location.route",
|
||||
string="Route",
|
||||
domain="[('id', 'in', route_ids)]",
|
||||
ondelete="restrict",
|
||||
)
|
||||
route_id = fields.Many2one('stock.location.route', string='Route',
|
||||
domain="[('id', 'in', route_ids)]",
|
||||
ondelete='restrict')
|
||||
|
||||
@api.depends('product_id', 'warehouse_id',
|
||||
'warehouse_id.route_ids', 'location_id')
|
||||
@api.depends("product_id", "warehouse_id", "warehouse_id.route_ids", "location_id")
|
||||
def _compute_route_ids(self):
|
||||
route_obj = self.env['stock.location.route']
|
||||
for wh in self.mapped('warehouse_id'):
|
||||
route_obj = self.env["stock.location.route"]
|
||||
for wh in self.mapped("warehouse_id"):
|
||||
wh_routes = wh.route_ids
|
||||
for record in self.filtered(lambda r: r.warehouse_id == wh):
|
||||
routes = route_obj.browse()
|
||||
if record.product_id:
|
||||
routes += record.product_id.mapped(
|
||||
'route_ids'
|
||||
) | record.product_id.mapped(
|
||||
'categ_id'
|
||||
).mapped('total_route_ids')
|
||||
"route_ids"
|
||||
) | record.product_id.mapped("categ_id").mapped("total_route_ids")
|
||||
if record.warehouse_id:
|
||||
routes |= wh_routes
|
||||
parents = record.get_parents()
|
||||
@@ -36,8 +35,8 @@ class StockWarehouseOrderpoint(models.Model):
|
||||
lambda route: any(
|
||||
p.location_id in parents
|
||||
for p in route.rule_ids.filtered(
|
||||
lambda rule: rule.action in ('pull', 'pull_push')
|
||||
).mapped('location_src_id')
|
||||
lambda rule: rule.action in ("pull", "pull_push")
|
||||
).mapped("location_src_id")
|
||||
)
|
||||
)
|
||||
|
||||
@@ -49,10 +48,7 @@ class StockWarehouseOrderpoint(models.Model):
|
||||
result |= location
|
||||
return result
|
||||
|
||||
def _prepare_procurement_values(self, product_qty, date=False,
|
||||
group=False):
|
||||
res = super()._prepare_procurement_values(
|
||||
product_qty, date=date, group=group
|
||||
)
|
||||
res['route_ids'] = self.route_id
|
||||
def _prepare_procurement_values(self, product_qty, date=False, group=False):
|
||||
res = super()._prepare_procurement_values(product_qty, date=date, group=group)
|
||||
res["route_ids"] = self.route_id
|
||||
return res
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
This module allows to restrict a specific route to be used in the
|
||||
reordering rules. This route will be used instead of the default determined by
|
||||
default.
|
||||
default.
|
||||
|
||||
@@ -10,148 +10,169 @@ class TestStockOrderpointRoute(common.SavepointCase):
|
||||
super().setUpClass()
|
||||
|
||||
# common models
|
||||
cls.orderpoint_model = cls.env[
|
||||
'stock.warehouse.orderpoint']
|
||||
cls.procurement_group_model = cls.env['procurement.group']
|
||||
cls.orderpoint_model = cls.env["stock.warehouse.orderpoint"]
|
||||
cls.procurement_group_model = cls.env["procurement.group"]
|
||||
# refs
|
||||
cls.stock_manager_group = \
|
||||
cls.env.ref('stock.group_stock_manager')
|
||||
cls.stock_multi_locations_group_group = \
|
||||
cls.env.ref('stock.group_stock_multi_locations')
|
||||
cls.main_company = cls.env.ref('base.main_company')
|
||||
cls.warehouse = cls.env.ref('stock.warehouse0')
|
||||
cls.categ_unit = cls.env.ref('uom.product_uom_categ_unit')
|
||||
cls.virtual_loc = cls.env.ref('stock.stock_location_customers')
|
||||
cls.stock_manager_group = cls.env.ref("stock.group_stock_manager")
|
||||
cls.stock_multi_locations_group_group = cls.env.ref(
|
||||
"stock.group_stock_multi_locations"
|
||||
)
|
||||
cls.main_company = cls.env.ref("base.main_company")
|
||||
cls.warehouse = cls.env.ref("stock.warehouse0")
|
||||
cls.categ_unit = cls.env.ref("uom.product_uom_categ_unit")
|
||||
cls.virtual_loc = cls.env.ref("stock.stock_location_customers")
|
||||
|
||||
# common data
|
||||
cls.stock_manager = cls._create_user(
|
||||
'stock_manager',
|
||||
[cls.stock_manager_group.id,
|
||||
cls.stock_multi_locations_group_group.id],
|
||||
[cls.main_company.id])
|
||||
cls.product = cls._create_product('SH', 'Shoes', False)
|
||||
"stock_manager",
|
||||
[cls.stock_manager_group.id, cls.stock_multi_locations_group_group.id],
|
||||
[cls.main_company.id],
|
||||
)
|
||||
cls.product = cls._create_product("SH", "Shoes", False)
|
||||
|
||||
cls.ressuply_loc = cls.env['stock.location'].create({
|
||||
'name': 'Ressuply',
|
||||
'location_id': cls.warehouse.view_location_id.id,
|
||||
})
|
||||
cls.ressuply_loc = cls.env["stock.location"].create(
|
||||
{"name": "Ressuply", "location_id": cls.warehouse.view_location_id.id}
|
||||
)
|
||||
|
||||
cls.ressuply_loc2 = cls.env['stock.location'].create({
|
||||
'name': 'Ressuply2',
|
||||
'location_id': cls.warehouse.view_location_id.id,
|
||||
})
|
||||
cls.ressuply_loc2 = cls.env["stock.location"].create(
|
||||
{"name": "Ressuply2", "location_id": cls.warehouse.view_location_id.id}
|
||||
)
|
||||
|
||||
cls.route = cls.env['stock.location.route'].create({
|
||||
'name': 'Transfer',
|
||||
'product_categ_selectable': False,
|
||||
'product_selectable': True,
|
||||
'company_id': cls.main_company.id,
|
||||
'sequence': 10,
|
||||
})
|
||||
cls.route2 = cls.env['stock.location.route'].create({
|
||||
'name': 'Transfer',
|
||||
'product_categ_selectable': False,
|
||||
'product_selectable': True,
|
||||
'company_id': cls.main_company.id,
|
||||
'sequence': 10,
|
||||
})
|
||||
cls.route = cls.env["stock.location.route"].create(
|
||||
{
|
||||
"name": "Transfer",
|
||||
"product_categ_selectable": False,
|
||||
"product_selectable": True,
|
||||
"company_id": cls.main_company.id,
|
||||
"sequence": 10,
|
||||
}
|
||||
)
|
||||
cls.route2 = cls.env["stock.location.route"].create(
|
||||
{
|
||||
"name": "Transfer",
|
||||
"product_categ_selectable": False,
|
||||
"product_selectable": True,
|
||||
"company_id": cls.main_company.id,
|
||||
"sequence": 10,
|
||||
}
|
||||
)
|
||||
|
||||
cls.uom_dozen = cls.env['uom.uom'].create({
|
||||
'name': 'Test-DozenA',
|
||||
'category_id': cls.categ_unit.id,
|
||||
'factor_inv': 12,
|
||||
'uom_type': 'bigger',
|
||||
'rounding': 0.001})
|
||||
cls.uom_dozen = cls.env["uom.uom"].create(
|
||||
{
|
||||
"name": "Test-DozenA",
|
||||
"category_id": cls.categ_unit.id,
|
||||
"factor_inv": 12,
|
||||
"uom_type": "bigger",
|
||||
"rounding": 0.001,
|
||||
}
|
||||
)
|
||||
|
||||
cls.env['stock.rule'].create({
|
||||
'name': 'Transfer',
|
||||
'route_id': cls.route.id,
|
||||
'location_src_id': cls.ressuply_loc.id,
|
||||
'location_id': cls.warehouse.lot_stock_id.id,
|
||||
'action': 'pull',
|
||||
'picking_type_id': cls.warehouse.int_type_id.id,
|
||||
'procure_method': 'make_to_stock',
|
||||
'warehouse_id': cls.warehouse.id,
|
||||
'company_id': cls.main_company.id,
|
||||
'propagate': 'False',
|
||||
})
|
||||
cls.env["stock.rule"].create(
|
||||
{
|
||||
"name": "Transfer",
|
||||
"route_id": cls.route.id,
|
||||
"location_src_id": cls.ressuply_loc.id,
|
||||
"location_id": cls.warehouse.lot_stock_id.id,
|
||||
"action": "pull",
|
||||
"picking_type_id": cls.warehouse.int_type_id.id,
|
||||
"procure_method": "make_to_stock",
|
||||
"warehouse_id": cls.warehouse.id,
|
||||
"company_id": cls.main_company.id,
|
||||
"propagate": "False",
|
||||
}
|
||||
)
|
||||
|
||||
cls.env['stock.rule'].create({
|
||||
'name': 'Transfer 2',
|
||||
'route_id': cls.route2.id,
|
||||
'location_src_id': cls.ressuply_loc2.id,
|
||||
'location_id': cls.warehouse.lot_stock_id.id,
|
||||
'action': 'pull',
|
||||
'picking_type_id': cls.warehouse.int_type_id.id,
|
||||
'procure_method': 'make_to_stock',
|
||||
'warehouse_id': cls.warehouse.id,
|
||||
'company_id': cls.main_company.id,
|
||||
'propagate': 'False',
|
||||
})
|
||||
cls.env["stock.rule"].create(
|
||||
{
|
||||
"name": "Transfer 2",
|
||||
"route_id": cls.route2.id,
|
||||
"location_src_id": cls.ressuply_loc2.id,
|
||||
"location_id": cls.warehouse.lot_stock_id.id,
|
||||
"action": "pull",
|
||||
"picking_type_id": cls.warehouse.int_type_id.id,
|
||||
"procure_method": "make_to_stock",
|
||||
"warehouse_id": cls.warehouse.id,
|
||||
"company_id": cls.main_company.id,
|
||||
"propagate": "False",
|
||||
}
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def _create_user(cls, name, group_ids, company_ids):
|
||||
return cls.env['res.users'].with_context(
|
||||
{'no_reset_password': True}).create(
|
||||
{'name': name,
|
||||
'password': 'demo',
|
||||
'login': name,
|
||||
'email': '@'.join([name, '@test.com']),
|
||||
'groups_id': [(6, 0, group_ids)],
|
||||
'company_ids': [(6, 0, company_ids)]
|
||||
})
|
||||
return (
|
||||
cls.env["res.users"]
|
||||
.with_context({"no_reset_password": True})
|
||||
.create(
|
||||
{
|
||||
"name": name,
|
||||
"password": "demo",
|
||||
"login": name,
|
||||
"email": "@".join([name, "@test.com"]),
|
||||
"groups_id": [(6, 0, group_ids)],
|
||||
"company_ids": [(6, 0, company_ids)],
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def _create_product(cls, default_code, name, company_id, **vals):
|
||||
return cls.env['product.product'].create(dict(
|
||||
name=name,
|
||||
default_code=default_code,
|
||||
uom_id=cls.env.ref('uom.product_uom_unit').id,
|
||||
company_id=company_id,
|
||||
type='product',
|
||||
**vals
|
||||
))
|
||||
return cls.env["product.product"].create(
|
||||
dict(
|
||||
name=name,
|
||||
default_code=default_code,
|
||||
uom_id=cls.env.ref("uom.product_uom_unit").id,
|
||||
company_id=company_id,
|
||||
type="product",
|
||||
**vals
|
||||
)
|
||||
)
|
||||
|
||||
def test_orderpoint_route_01(self):
|
||||
self.product.route_ids = [(6, 0, [self.route.id, self.route2.id])]
|
||||
vals = {
|
||||
'product_id': self.product.id,
|
||||
'product_min_qty': 10.0,
|
||||
'product_max_qty': 100.0,
|
||||
'company_id': self.main_company.id,
|
||||
'warehouse_id': self.warehouse.id,
|
||||
'location_id': self.warehouse.lot_stock_id.id,
|
||||
"product_id": self.product.id,
|
||||
"product_min_qty": 10.0,
|
||||
"product_max_qty": 100.0,
|
||||
"company_id": self.main_company.id,
|
||||
"warehouse_id": self.warehouse.id,
|
||||
"location_id": self.warehouse.lot_stock_id.id,
|
||||
}
|
||||
|
||||
orderpoint = self.orderpoint_model.sudo(
|
||||
self.stock_manager).create(vals)
|
||||
orderpoint = self.orderpoint_model.sudo(self.stock_manager).create(vals)
|
||||
self.assertIn(self.route, orderpoint.route_ids)
|
||||
self.assertIn(self.route2, orderpoint.route_ids)
|
||||
orderpoint.route_id = self.route.id
|
||||
self.procurement_group_model.run_scheduler()
|
||||
move = self.env['stock.move'].search(
|
||||
[('product_id', '=', self.product.id),
|
||||
('location_id', '=', self.ressuply_loc.id)], limit=1)
|
||||
move = self.env["stock.move"].search(
|
||||
[
|
||||
("product_id", "=", self.product.id),
|
||||
("location_id", "=", self.ressuply_loc.id),
|
||||
],
|
||||
limit=1,
|
||||
)
|
||||
self.assertEqual(len(move), 1)
|
||||
|
||||
def test_orderpoint_route_02(self):
|
||||
self.product.route_ids = [(6, 0, [self.route.id, self.route2.id])]
|
||||
vals = {
|
||||
'product_id': self.product.id,
|
||||
'product_min_qty': 10.0,
|
||||
'product_max_qty': 100.0,
|
||||
'company_id': self.main_company.id,
|
||||
'warehouse_id': self.warehouse.id,
|
||||
'location_id': self.warehouse.lot_stock_id.id,
|
||||
"product_id": self.product.id,
|
||||
"product_min_qty": 10.0,
|
||||
"product_max_qty": 100.0,
|
||||
"company_id": self.main_company.id,
|
||||
"warehouse_id": self.warehouse.id,
|
||||
"location_id": self.warehouse.lot_stock_id.id,
|
||||
}
|
||||
|
||||
orderpoint = self.orderpoint_model.sudo(
|
||||
self.stock_manager).create(vals)
|
||||
orderpoint = self.orderpoint_model.sudo(self.stock_manager).create(vals)
|
||||
self.assertIn(self.route, orderpoint.route_ids)
|
||||
self.assertIn(self.route2, orderpoint.route_ids)
|
||||
orderpoint.route_id = self.route2.id
|
||||
self.procurement_group_model.run_scheduler()
|
||||
move = self.env['stock.move'].search(
|
||||
[('product_id', '=', self.product.id),
|
||||
('location_id', '=', self.ressuply_loc2.id)], limit=1)
|
||||
move = self.env["stock.move"].search(
|
||||
[
|
||||
("product_id", "=", self.product.id),
|
||||
("location_id", "=", self.ressuply_loc2.id),
|
||||
],
|
||||
limit=1,
|
||||
)
|
||||
self.assertEqual(len(move), 1)
|
||||
|
||||
Reference in New Issue
Block a user