mirror of
https://github.com/OCA/stock-logistics-warehouse.git
synced 2025-01-21 14:27:28 +02:00
[MIG] stock_orderpoint_manual_procurement: Migration to 11.0
This commit is contained in:
@@ -19,16 +19,16 @@ procurements from reordering rules', under 'Settings / Users / Users'.
|
||||
Usage
|
||||
=====
|
||||
|
||||
Go to 'Inventory > Inventory Control > Reordering Rules' and review the
|
||||
quantity recommended to be procured. You can now start the procurement for a
|
||||
single or a list of reordering rules.
|
||||
Go to 'Inventory > Master Data > Reordering Rules' and review the quantity
|
||||
recommended to be procured. You can now start the procurement for a single or a
|
||||
list of reordering rules.
|
||||
|
||||
The recommended quantity to procure is adjusted to the procurement unit of
|
||||
measure indicated in the reordering rule.
|
||||
|
||||
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas
|
||||
:alt: Try me on Runbot
|
||||
:target: https://runbot.odoo-community.org/runbot/153/10.0
|
||||
:target: https://runbot.odoo-community.org/runbot/153/11.0
|
||||
|
||||
Bug Tracker
|
||||
===========
|
||||
@@ -51,6 +51,7 @@ Contributors
|
||||
|
||||
* Jordi Ballester Alomar <jordi.ballester@eficent.com>
|
||||
* Lois Rilo Antelo <lois.rilo@eficent.com>
|
||||
* Bhavesh Odedra <bodedra@opensourceintegrators.com>
|
||||
|
||||
Maintainer
|
||||
----------
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from . import models
|
||||
|
||||
@@ -1,23 +1,26 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2016-17 Eficent Business and IT Consulting Services S.L.
|
||||
# (http://www.eficent.com)
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
{
|
||||
"name": "Stock Orderpoint Manual Procurement",
|
||||
"summary": "Allows to create procurement orders from orderpoints instead "
|
||||
"of relying only on the scheduler.",
|
||||
"version": "10.0.1.0.0",
|
||||
"version": "11.0.1.0.0",
|
||||
"author": "Eficent, "
|
||||
"Odoo Community Association (OCA)",
|
||||
"website": "https://github.com/OCA/stock-logistics-warehouse",
|
||||
"category": "Warehouse Management",
|
||||
"depends": [
|
||||
"stock",
|
||||
"purchase",
|
||||
],
|
||||
"demo": [
|
||||
"demo/product.xml",
|
||||
],
|
||||
"data": [
|
||||
"security/stock_orderpoint_manual_procurement_security.xml",
|
||||
"wizards/make_procurement_orderpoint_view.xml",
|
||||
"views/procurement_order_view.xml",
|
||||
"views/stock_warehouse_orderpoint_view.xml",
|
||||
],
|
||||
"license": "AGPL-3",
|
||||
|
||||
10
stock_orderpoint_manual_procurement/demo/product.xml
Normal file
10
stock_orderpoint_manual_procurement/demo/product.xml
Normal file
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0"?>
|
||||
<odoo noupdate="1">
|
||||
<record id="product_supplierinfo_product_7" model="product.supplierinfo">
|
||||
<field name="product_tmpl_id" ref="product.product_product_7"/>
|
||||
<field name="name" ref="base.res_partner_3"/>
|
||||
<field name="delay">3</field>
|
||||
<field name="min_qty">1</field>
|
||||
<field name="price">72</field>
|
||||
</record>
|
||||
</odoo>
|
||||
@@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from . import stock_warehouse_orderpoint
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2016-17 Eficent Business and IT Consulting Services S.L.
|
||||
# (http://www.eficent.com)
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||
@@ -52,13 +51,14 @@ class StockWarehouseOrderpoint(models.Model):
|
||||
@api.multi
|
||||
@api.depends("product_min_qty", "product_id", "qty_multiple")
|
||||
def _compute_procure_recommended(self):
|
||||
op_qtys = self.subtract_procurements_from_orderpoints()
|
||||
op_qtys = self._quantity_in_progress()
|
||||
for op in self:
|
||||
op.procure_recommended_date = op._get_date_planned(
|
||||
datetime.today())
|
||||
qty = 0.0
|
||||
virtual_qty = op.with_context(
|
||||
location=op.location_id.id).product_id.virtual_available
|
||||
if float_compare(virtual_qty, op.product_min_qty,
|
||||
precision_rounding=op.product_uom.rounding) < 0:
|
||||
op.procure_recommended_qty = op._get_procure_recommended_qty(
|
||||
virtual_qty, op_qtys)
|
||||
qty = op._get_procure_recommended_qty(virtual_qty, op_qtys)
|
||||
op.procure_recommended_qty = qty
|
||||
op.procure_recommended_date = op._get_date_planned(
|
||||
qty, datetime.today())
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0"?>
|
||||
<odoo noupdate="1">
|
||||
|
||||
<record id="group_change_orderpoint_procure_qty" model="res.groups">
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from . import test_stock_orderpoint_manual_procurement
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2016-17 Eficent Business and IT Consulting Services S.L.
|
||||
# (http://www.eficent.com)
|
||||
# Copyright 2016 Serpent Consulting Services Pvt. Ltd.
|
||||
@@ -14,6 +13,10 @@ class TestStockWarehouseOrderpoint(common.TransactionCase):
|
||||
|
||||
# Refs
|
||||
self.group_stock_manager = self.env.ref('stock.group_stock_manager')
|
||||
self.group_purchase_manager = self.env.ref(
|
||||
'purchase.group_purchase_manager')
|
||||
self.vendor = self.env.ref(
|
||||
'stock_orderpoint_manual_procurement.product_supplierinfo_product_7') # noqa
|
||||
self.group_change_procure_qty = self.env.ref(
|
||||
'stock_orderpoint_manual_procurement.'
|
||||
'group_change_orderpoint_procure_qty')
|
||||
@@ -22,6 +25,8 @@ class TestStockWarehouseOrderpoint(common.TransactionCase):
|
||||
# Get required Model
|
||||
self.reordering_rule_model = self.env['stock.warehouse.orderpoint']
|
||||
self.product_model = self.env['product.product']
|
||||
self.purchase_model = self.env['purchase.order']
|
||||
self.purchase_line_model = self.env['purchase.order.line']
|
||||
self.user_model = self.env['res.users']
|
||||
self.product_ctg_model = self.env['product.category']
|
||||
self.stock_change_model = self.env['stock.change.product.qty']
|
||||
@@ -31,7 +36,8 @@ class TestStockWarehouseOrderpoint(common.TransactionCase):
|
||||
# Create users
|
||||
self.user = self._create_user('user_1',
|
||||
[self.group_stock_manager,
|
||||
self.group_change_procure_qty],
|
||||
self.group_change_procure_qty,
|
||||
self.group_purchase_manager],
|
||||
self.company1)
|
||||
# Get required Model data
|
||||
self.product_uom = self.env.ref('product.product_uom_unit')
|
||||
@@ -68,7 +74,6 @@ class TestStockWarehouseOrderpoint(common.TransactionCase):
|
||||
"""Create a Product Category."""
|
||||
product_ctg = self.product_ctg_model.create({
|
||||
'name': 'test_product_ctg',
|
||||
'type': 'normal',
|
||||
})
|
||||
return product_ctg
|
||||
|
||||
@@ -79,6 +84,7 @@ class TestStockWarehouseOrderpoint(common.TransactionCase):
|
||||
'categ_id': self.product_ctg.id,
|
||||
'type': 'product',
|
||||
'uom_id': self.product_uom.id,
|
||||
'variant_seller_ids': [(6, 0, [self.vendor.id])],
|
||||
})
|
||||
return product
|
||||
|
||||
@@ -121,13 +127,15 @@ class TestStockWarehouseOrderpoint(common.TransactionCase):
|
||||
# Create Manual Procurement from order-point procured quantity
|
||||
self.create_orderpoint_procurement()
|
||||
|
||||
# As per route configuration, it will create Purchase order
|
||||
# Assert that Procurement is created with the desired quantity
|
||||
self.assertTrue(self.reorder.procurement_ids)
|
||||
self.assertEqual(self.reorder.product_id.id,
|
||||
self.reorder.procurement_ids.product_id.id)
|
||||
self.assertEqual(self.reorder.name,
|
||||
self.reorder.procurement_ids.origin)
|
||||
purchase = self.purchase_model.search(
|
||||
[('origin', 'ilike', self.reorder.name)])
|
||||
self.assertEquals(len(purchase), 1)
|
||||
purchase_line = self.purchase_line_model.search(
|
||||
[('orderpoint_id', '=', self.reorder.id),
|
||||
('order_id', '=', purchase.id)])
|
||||
self.assertEquals(len(purchase_line), 1)
|
||||
self.assertNotEqual(self.reorder.procure_recommended_qty,
|
||||
self.reorder.procurement_ids.product_qty)
|
||||
self.assertEqual(self.reorder.procurement_ids.product_qty,
|
||||
480.0)
|
||||
purchase_line.product_qty)
|
||||
self.assertEqual(purchase_line.product_qty, 480.0)
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<record id="view_procurement_filter" model="ir.ui.view">
|
||||
<field name="name">procurement.order.select</field>
|
||||
<field name="model">procurement.order</field>
|
||||
<field name="inherit_id"
|
||||
ref="procurement.view_procurement_filter"/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="origin" position="after">
|
||||
<field name="orderpoint_id"/>
|
||||
</field>
|
||||
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
@@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0"?>
|
||||
<odoo>
|
||||
|
||||
<record id="view_warehouse_orderpoint_tree" model="ir.ui.view">
|
||||
@@ -8,18 +8,11 @@
|
||||
ref="stock.view_warehouse_orderpoint_tree"/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="product_uom" position="after">
|
||||
<field name="procurement_ids" invisible="1"/>
|
||||
<field name="procure_recommended_qty"/>
|
||||
<field name="procure_recommended_date"/>
|
||||
<button string="Create Procurement"
|
||||
name="%(stock_orderpoint_manual_procurement.act_make_procurement_from_orderpoint)d"
|
||||
icon="fa fa-cogs" type="action"/>
|
||||
<button string="Procurements"
|
||||
name="%(procurement.procurement_action)d"
|
||||
attrs="{'invisible':[('procurement_ids', '=', [])]}"
|
||||
icon="fa fa-folder-open" type="action"
|
||||
domain="[('orderpoint_id','=', active_id)]"
|
||||
context="{'search_default_orderpoint_id': [active_id]}"/>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from . import make_procurement_orderpoint
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2016-17 Eficent Business and IT Consulting Services S.L.
|
||||
# (http://www.eficent.com)
|
||||
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
|
||||
|
||||
from odoo import api, fields, models, _
|
||||
from odoo.exceptions import ValidationError
|
||||
from odoo.exceptions import UserError, ValidationError
|
||||
|
||||
|
||||
class MakeProcurementOrderpoint(models.TransientModel):
|
||||
@@ -20,7 +19,6 @@ class MakeProcurementOrderpoint(models.TransientModel):
|
||||
return {
|
||||
'qty': orderpoint.procure_recommended_qty,
|
||||
'uom_id': orderpoint.product_uom.id,
|
||||
'date_planned': orderpoint.procure_recommended_date,
|
||||
'orderpoint_id': orderpoint.id,
|
||||
'product_id': orderpoint.product_id.id,
|
||||
'warehouse_id': orderpoint.warehouse_id.id,
|
||||
@@ -29,8 +27,7 @@ class MakeProcurementOrderpoint(models.TransientModel):
|
||||
|
||||
@api.model
|
||||
def default_get(self, fields):
|
||||
res = super(MakeProcurementOrderpoint, self).default_get(
|
||||
fields)
|
||||
res = super(MakeProcurementOrderpoint, self).default_get(fields)
|
||||
orderpoint_obj = self.env['stock.warehouse.orderpoint']
|
||||
orderpoint_ids = self.env.context['active_ids'] or []
|
||||
active_model = self.env.context['active_model']
|
||||
@@ -49,20 +46,30 @@ class MakeProcurementOrderpoint(models.TransientModel):
|
||||
@api.multi
|
||||
def make_procurement(self):
|
||||
self.ensure_one()
|
||||
res = []
|
||||
errors = []
|
||||
for item in self.item_ids:
|
||||
data = item._prepare_procurement()
|
||||
procurement = self.env['procurement.order'].create(data)
|
||||
res.append(procurement.id)
|
||||
if not item.qty:
|
||||
raise ValidationError(_("Quantity must be positive."))
|
||||
if not item.orderpoint_id:
|
||||
raise ValidationError(_("No reordering rule found!"))
|
||||
values = item.orderpoint_id._prepare_procurement_values(item.qty)
|
||||
# Run procurement
|
||||
try:
|
||||
self.env['procurement.group'].run(
|
||||
item.orderpoint_id.product_id,
|
||||
item.qty,
|
||||
item.orderpoint_id.product_uom,
|
||||
item.orderpoint_id.location_id,
|
||||
item.orderpoint_id.name,
|
||||
item.orderpoint_id.name,
|
||||
values
|
||||
)
|
||||
except UserError as error:
|
||||
errors.append(error.name)
|
||||
if errors:
|
||||
raise UserError('\n'.join(errors))
|
||||
|
||||
return {
|
||||
'name': _('Created Procurements'),
|
||||
'domain': [('id', 'in', res)],
|
||||
'view_type': 'form',
|
||||
'view_mode': 'tree,form',
|
||||
'res_model': 'procurement.order',
|
||||
'type': 'ir.actions.act_window',
|
||||
}
|
||||
return {'type': 'ir.actions.act_window_close'}
|
||||
|
||||
|
||||
class MakeProcurementOrderpointItem(models.TransientModel):
|
||||
@@ -76,15 +83,15 @@ class MakeProcurementOrderpointItem(models.TransientModel):
|
||||
qty = fields.Float(string='Quantity', required=True)
|
||||
|
||||
uom_id = fields.Many2one(string='Unit of Measure',
|
||||
comodel_name='product.uom', required=True)
|
||||
date_planned = fields.Date(string='Planned Date', required=True)
|
||||
comodel_name='product.uom')
|
||||
date_planned = fields.Date(string='Planned Date', required=False)
|
||||
|
||||
orderpoint_id = fields.Many2one(string='Reordering rule',
|
||||
comodel_name='stock.warehouse.orderpoint',
|
||||
required=True, readonly=True)
|
||||
readonly=False)
|
||||
product_id = fields.Many2one(string='Product',
|
||||
comodel_name='product.product',
|
||||
required=True, readonly=True)
|
||||
readonly=True)
|
||||
warehouse_id = fields.Many2one(string='Warehouse',
|
||||
comodel_name='stock.warehouse',
|
||||
readonly=True)
|
||||
@@ -92,24 +99,6 @@ class MakeProcurementOrderpointItem(models.TransientModel):
|
||||
comodel_name='stock.location',
|
||||
readonly=True)
|
||||
|
||||
@api.multi
|
||||
def _prepare_procurement(self):
|
||||
if not self.qty:
|
||||
raise ValidationError(_("Quantity must be positive."))
|
||||
return {
|
||||
'name': self.orderpoint_id.name,
|
||||
'date_planned': self.date_planned,
|
||||
'product_id': self.product_id.id,
|
||||
'product_qty': self.qty,
|
||||
'product_uom': self.uom_id.id,
|
||||
'warehouse_id': self.warehouse_id.id,
|
||||
'location_id': self.location_id.id,
|
||||
'company_id': self.orderpoint_id.company_id.id,
|
||||
'orderpoint_id': self.orderpoint_id.id,
|
||||
'origin': self.orderpoint_id.name,
|
||||
'group_id': self.orderpoint_id.group_id.id,
|
||||
}
|
||||
|
||||
@api.multi
|
||||
@api.onchange('uom_id')
|
||||
def onchange_uom_id(self):
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0"?>
|
||||
<odoo>
|
||||
|
||||
<!-- Make Procurement -->
|
||||
@@ -18,12 +18,11 @@
|
||||
<field name="item_ids" nolabel="1">
|
||||
<tree string="Items" nocreate="1" editable="top">
|
||||
<field name="orderpoint_id" invisible="True"/>
|
||||
<field name="warehouse_id" groups="stock.group_locations"/>
|
||||
<field name="location_id" groups="stock.group_locations"/>
|
||||
<field name="warehouse_id" groups="stock.group_stock_multi_locations"/>
|
||||
<field name="location_id" groups="stock.group_stock_multi_locations"/>
|
||||
<field name="product_id"/>
|
||||
<field name="qty" groups="stock_orderpoint_manual_procurement.group_change_orderpoint_procure_qty"/>
|
||||
<field name="uom_id" groups="product.group_uom"/>
|
||||
<field name="date_planned"/>
|
||||
</tree>
|
||||
</field>
|
||||
</group>
|
||||
@@ -42,20 +41,10 @@
|
||||
id="act_make_procurement_from_orderpoint">
|
||||
<field name="name">Request Procurement</field>
|
||||
<field name="res_model">make.procurement.orderpoint</field>
|
||||
<field name="src_model">stock.warehouse.orderpoint</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="target">new</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.values"
|
||||
id="stock_warehouse_orderpoint_make_procurement">
|
||||
<field name="model_id"
|
||||
ref="stock.model_stock_warehouse_orderpoint" />
|
||||
<field name="name">Request Procurement</field>
|
||||
<field name="key2">client_action_multi</field>
|
||||
<field name="value" eval="'ir.actions.act_window,' + str(ref('act_make_procurement_from_orderpoint'))" />
|
||||
<field name="key">action</field>
|
||||
<field name="model">stock.warehouse.orderpoint</field>
|
||||
<field name="binding_model_id"
|
||||
ref="stock.model_stock_warehouse_orderpoint"/>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
||||
Reference in New Issue
Block a user