mirror of
https://github.com/OCA/manufacture.git
synced 2025-01-28 16:37:15 +02:00
Merge pull request #172 from Eficent/9.0-mig-mrp_production_raw_material_procurement_group
[9.0]-[mig]-mrp production raw material procurement group
This commit is contained in:
77
mrp_production_raw_material_procurement_group/README.rst
Normal file
77
mrp_production_raw_material_procurement_group/README.rst
Normal file
@@ -0,0 +1,77 @@
|
||||
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg
|
||||
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
|
||||
:alt: License: AGPL-3
|
||||
|
||||
===============================================
|
||||
Create Procurement Group On Manufacturing Order
|
||||
===============================================
|
||||
|
||||
This module adds ability to group manufacturing order's raw material moves, and
|
||||
other moves created by it's pull flow, by given procurement group.
|
||||
|
||||
Installation
|
||||
============
|
||||
|
||||
To install this module, you need to:
|
||||
|
||||
1. Clone the branch 9.0 of the repository https://github.com/OCA/manufacture
|
||||
2. Add the path to this repository in your configuration (addons-path)
|
||||
3. Update the module list
|
||||
4. Go to menu *Setting -> Modules -> Local Modules*
|
||||
5. Search For *Create Procurement Group On Manufacturing Order*
|
||||
6. Install the module
|
||||
|
||||
|
||||
Usage
|
||||
=====
|
||||
|
||||
To use this module, you need to:
|
||||
|
||||
1. Go to menu *Manufacturing -> Manufacturing -> Manufacturing Orders*
|
||||
2. Create manufacturing order. Do not forget to fill *Raw Material Procurement Group*
|
||||
3. When MO is confirmed. Raw material moves with *make to order* procurement method, and it's
|
||||
other moves created by it's pull flow, will be grouped based on *Raw Material Procurement Group*
|
||||
given
|
||||
|
||||
|
||||
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas
|
||||
:alt: Try me on Runbot
|
||||
:target: https://runbot.odoo-community.org/runbot/129/9.0
|
||||
|
||||
|
||||
Bug Tracker
|
||||
===========
|
||||
|
||||
Bugs are tracked on `GitHub Issues
|
||||
<https://github.com/OCA/manufacture/issues>`_. In case of trouble, please
|
||||
check there if your issue has already been reported. If you spotted it first,
|
||||
help us smashing it by providing a detailed and welcomed feedback.
|
||||
|
||||
Credits
|
||||
=======
|
||||
|
||||
Images
|
||||
------
|
||||
|
||||
* Odoo Community Association: `Icon <https://github.com/OCA/maintainer-tools/blob/master/template/module/static/description/icon.svg>`_.
|
||||
|
||||
Contributors
|
||||
------------
|
||||
|
||||
* Andhitia Rama <andhitia.r@gmail.com>
|
||||
* Lois Rilo <lois.rilo@eficent.com>
|
||||
|
||||
Maintainer
|
||||
----------
|
||||
|
||||
.. image:: https://odoo-community.org/logo.png
|
||||
:alt: Odoo Community Association
|
||||
:target: https://odoo-community.org
|
||||
|
||||
This module is maintained by the OCA.
|
||||
|
||||
OCA, or the Odoo Community Association, is a nonprofit organization whose
|
||||
mission is to support the collaborative development of Odoo features and
|
||||
promote its widespread use.
|
||||
|
||||
To contribute to this module, please visit https://odoo-community.org.
|
||||
@@ -0,0 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2016 OpenSynergy Indonesia
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from . import models
|
||||
19
mrp_production_raw_material_procurement_group/__openerp__.py
Normal file
19
mrp_production_raw_material_procurement_group/__openerp__.py
Normal file
@@ -0,0 +1,19 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2016 OpenSynergy Indonesia
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
{
|
||||
"name": "Create Procurement Group On Manufacturing Order",
|
||||
"version": "9.0.1.0.0",
|
||||
"category": "Manufacturing",
|
||||
"website": "https://opensynergy-indonesia.com/",
|
||||
"author": "OpenSynergy Indonesia, Eficent, Odoo Community Association ("
|
||||
"OCA)",
|
||||
"license": "AGPL-3",
|
||||
"installable": True,
|
||||
"depends": [
|
||||
"mrp",
|
||||
],
|
||||
"data": [
|
||||
"views/mrp_production_views.xml",
|
||||
],
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2016 OpenSynergy Indonesia
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from . import mrp_production
|
||||
@@ -0,0 +1,77 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2016 OpenSynergy Indonesia
|
||||
# Copyright 2016 Eficent Business and IT Consulting Services, S.L.
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from openerp import models, fields, api
|
||||
|
||||
|
||||
class MrpProduction(models.Model):
|
||||
_inherit = "mrp.production"
|
||||
|
||||
raw_material_procurement_group_id = fields.Many2one(
|
||||
string="Raw Material Procurement Group",
|
||||
comodel_name="procurement.group",
|
||||
readonly=True,
|
||||
copy=False,
|
||||
states={
|
||||
"draft": [("readonly", False)],
|
||||
},
|
||||
)
|
||||
auto_create_procurement_group = fields.Boolean(
|
||||
string="Auto Create Procurement Group",
|
||||
readonly=True,
|
||||
states={
|
||||
"draft": [("readonly", False)],
|
||||
},
|
||||
)
|
||||
|
||||
@api.multi
|
||||
def action_confirm(self):
|
||||
for mo in self:
|
||||
mo._create_procurement_group()
|
||||
return super(MrpProduction, self).action_confirm()
|
||||
|
||||
@api.multi
|
||||
def _prepare_procurement_group(self):
|
||||
return {"name": self.name}
|
||||
|
||||
@api.multi
|
||||
def _create_procurement_group(self):
|
||||
self.ensure_one()
|
||||
obj_group = self.env[
|
||||
"procurement.group"]
|
||||
if self.auto_create_procurement_group and \
|
||||
not self.raw_material_procurement_group_id:
|
||||
self.raw_material_procurement_group_id = obj_group.create(
|
||||
self._prepare_procurement_group())
|
||||
|
||||
@api.model
|
||||
def _make_consume_line_from_data(
|
||||
self,
|
||||
production, product, uom_id, qty):
|
||||
|
||||
move_id = super(MrpProduction, self)._make_consume_line_from_data(
|
||||
production, product, uom_id, qty)
|
||||
obj_move = self.env["stock.move"]
|
||||
move = obj_move.browse(move_id)
|
||||
if move.procure_method == "make_to_stock":
|
||||
return move_id
|
||||
if not production.raw_material_procurement_group_id:
|
||||
return move_id
|
||||
move.write(
|
||||
{"group_id": production.raw_material_procurement_group_id.id})
|
||||
return move_id
|
||||
|
||||
@api.model
|
||||
def _create_previous_move(self, move_id, product, source_location_id,
|
||||
dest_location_id):
|
||||
move_id2 = super(MrpProduction, self)._create_previous_move(
|
||||
move_id, product, source_location_id, dest_location_id)
|
||||
move1 = self.env['stock.move'].browse(move_id)
|
||||
move2 = self.env['stock.move'].browse(move_id2)
|
||||
if move1.raw_material_production_id.raw_material_procurement_group_id:
|
||||
move2.group_id = \
|
||||
move1.raw_material_production_id.\
|
||||
raw_material_procurement_group_id
|
||||
return move2.id
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 9.2 KiB |
@@ -0,0 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2016 OpenSynergy Indonesia
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from . import test_mrp_production
|
||||
@@ -0,0 +1,202 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2016 OpenSynergy Indonesia
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from openerp.tests.common import TransactionCase
|
||||
|
||||
|
||||
class MrpProductionCase(TransactionCase):
|
||||
|
||||
def setUp(self, *args, **kwargs):
|
||||
super(MrpProductionCase, self).setUp(*args, **kwargs)
|
||||
|
||||
self.obj_group = self.env["procurement.group"]
|
||||
self.obj_mo = self.env["mrp.production"]
|
||||
|
||||
self.warehouse1 = self.env.ref("stock.warehouse0")
|
||||
self.warehouse2 = self.env["stock.warehouse"].create({
|
||||
"name": "X Warehouse",
|
||||
"code": "X WH",
|
||||
"reception_steps": "one_step",
|
||||
"delivery_steps": "ship_only",
|
||||
"resupply_from_wh": False,
|
||||
"default_resupply_wh_id": False,
|
||||
})
|
||||
self.loc_stock_2 = self.warehouse2.lot_stock_id
|
||||
self.loc_production = self.env.ref(
|
||||
"stock.location_production")
|
||||
self.route = self.env["stock.location.route"].create({
|
||||
"name": "X Route",
|
||||
"sequence": 1,
|
||||
"product_selectable": True,
|
||||
})
|
||||
self.rule = self.env["procurement.rule"].create({
|
||||
"name": "X Production",
|
||||
"location_id": self.loc_production.id,
|
||||
"location_src_id": self.loc_stock_2.id,
|
||||
"procure_method": "make_to_order",
|
||||
"picking_type_id": self.warehouse2.int_type_id.id,
|
||||
"action": "move",
|
||||
"sequence": 1,
|
||||
"route_id": self.route.id,
|
||||
})
|
||||
self.product1 = self.env.ref("product.product_product_18")
|
||||
self.product_raw1 = self.env.ref("product.product_product_17")
|
||||
self.product_raw1.write({
|
||||
"route_ids": [(4, self.route.id)],
|
||||
})
|
||||
self.bom1 = self.env.ref("mrp.mrp_bom_3")
|
||||
self.bom1.write({
|
||||
"routing_id": False})
|
||||
|
||||
def _create_procurement_group(
|
||||
self, name):
|
||||
res = {
|
||||
"name": name,
|
||||
"move_type": "direct"
|
||||
}
|
||||
return self.obj_group.create(res)
|
||||
|
||||
def _create_mo(
|
||||
self,
|
||||
product=False,
|
||||
bom=False,
|
||||
src_loc=False,
|
||||
dest_loc=False,
|
||||
group=False,
|
||||
qty=10.0,
|
||||
auto=False):
|
||||
if not product:
|
||||
product = self.product1
|
||||
uom = product.uom_id
|
||||
if not bom:
|
||||
bom = self.bom1
|
||||
if not src_loc:
|
||||
src_loc = self.loc_stock_2
|
||||
if not dest_loc:
|
||||
dest_loc = self.loc_stock_2
|
||||
res = {
|
||||
"product_id": product.id,
|
||||
"bom_id": bom.id,
|
||||
"location_src_id": src_loc.id,
|
||||
"location_dest_id": dest_loc.id,
|
||||
"raw_material_procurement_group_id": group,
|
||||
"product_qty": qty,
|
||||
"product_uom": uom.id,
|
||||
"auto_create_procurement_group": auto,
|
||||
}
|
||||
return self.obj_mo.create(res)
|
||||
|
||||
def test_no_create_group(self):
|
||||
# Create MO
|
||||
mo = self._create_mo()
|
||||
# Click confirm button
|
||||
mo.signal_workflow("button_confirm")
|
||||
for raw in mo.move_lines:
|
||||
self.assertEqual(
|
||||
raw.location_id,
|
||||
self.loc_stock_2)
|
||||
self.assertEqual(
|
||||
raw.location_dest_id,
|
||||
self.loc_production)
|
||||
self.assertEqual(
|
||||
raw.procure_method,
|
||||
"make_to_order")
|
||||
self.assertEqual(
|
||||
len(raw.group_id),
|
||||
0)
|
||||
|
||||
def test_create_group_manual(self):
|
||||
group1 = self._create_procurement_group(
|
||||
"X 001")
|
||||
# Create MO
|
||||
mo = self._create_mo(
|
||||
group=group1.id)
|
||||
# Click confirm button
|
||||
mo.signal_workflow("button_confirm")
|
||||
for raw in mo.move_lines:
|
||||
self.assertEqual(
|
||||
raw.location_id,
|
||||
self.loc_stock_2)
|
||||
self.assertEqual(
|
||||
raw.location_dest_id,
|
||||
self.loc_production)
|
||||
self.assertEqual(
|
||||
raw.procure_method,
|
||||
"make_to_order")
|
||||
self.assertEqual(
|
||||
raw.group_id,
|
||||
group1)
|
||||
|
||||
def test_create_group_auto(self):
|
||||
mo = self._create_mo(
|
||||
group=False,
|
||||
auto=True)
|
||||
# Click confirm button
|
||||
mo.signal_workflow("button_confirm")
|
||||
for raw in mo.move_lines:
|
||||
self.assertEqual(
|
||||
raw.location_id,
|
||||
self.loc_stock_2)
|
||||
self.assertEqual(
|
||||
raw.location_dest_id,
|
||||
self.loc_production)
|
||||
self.assertEqual(
|
||||
raw.procure_method,
|
||||
"make_to_order")
|
||||
self.assertEqual(
|
||||
raw.group_id,
|
||||
mo.raw_material_procurement_group_id)
|
||||
|
||||
def test_copy_mo(self):
|
||||
# Create MO
|
||||
group1 = self._create_procurement_group(
|
||||
"X 001")
|
||||
mo = self._create_mo(
|
||||
group=group1.id)
|
||||
mo2 = mo.copy()
|
||||
|
||||
self.assertNotEqual(
|
||||
mo.raw_material_procurement_group_id,
|
||||
mo2.raw_material_procurement_group_id)
|
||||
|
||||
self.assertEqual(
|
||||
mo2.raw_material_procurement_group_id.id, False)
|
||||
|
||||
def test_group_name(self):
|
||||
# Create MO
|
||||
mo = self._create_mo(auto=True)
|
||||
# Click confirm button
|
||||
mo.signal_workflow("button_confirm")
|
||||
|
||||
self.assertNotEqual(
|
||||
mo.raw_material_procurement_group_id.id, False)
|
||||
|
||||
self.assertEqual(
|
||||
mo.raw_material_procurement_group_id.name, mo.name)
|
||||
|
||||
def test_routing(self):
|
||||
location = self.env['stock.location'].create({
|
||||
'name': 'Shop floor',
|
||||
})
|
||||
routing = self.env['mrp.routing'].create({
|
||||
'name': 'test',
|
||||
'location_id': location.id,
|
||||
})
|
||||
self.bom1.write({
|
||||
"routing_id": routing.id})
|
||||
# Create MO
|
||||
mo = self._create_mo(auto=True)
|
||||
mo2 = self._create_mo(auto=True)
|
||||
# Click confirm button
|
||||
mo.signal_workflow("button_confirm")
|
||||
mo2.signal_workflow("button_confirm")
|
||||
|
||||
# Check that the pickings are split by procurement group
|
||||
pick = self.env['stock.picking'].search(
|
||||
[('group_id', '=', mo.raw_material_procurement_group_id.id)])
|
||||
self.assertNotEqual(pick, False)
|
||||
|
||||
pick2 = self.env['stock.picking'].search(
|
||||
[('group_id', '=', mo2.raw_material_procurement_group_id.id)])
|
||||
self.assertNotEqual(pick2, False)
|
||||
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright 2016 Opensynergy Indonesia
|
||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -->
|
||||
|
||||
<odoo>
|
||||
|
||||
<record id="mrp_production_view_form" model="ir.ui.view">
|
||||
<field name="name">mrp.production form</field>
|
||||
<field name="model">mrp.production</field>
|
||||
<field name="inherit_id" ref="mrp.mrp_production_form_view"/>
|
||||
<field name="arch" type="xml">
|
||||
<data>
|
||||
<xpath expr="//field[@name='location_src_id']" position="after">
|
||||
<field name="auto_create_procurement_group"/>
|
||||
<field name="raw_material_procurement_group_id"/>
|
||||
</xpath>
|
||||
</data>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
Reference in New Issue
Block a user