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:
Jordi Ballester Alomar
2017-01-19 04:44:30 -07:00
committed by GitHub
9 changed files with 411 additions and 0 deletions

View 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.

View File

@@ -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

View 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",
],
}

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

@@ -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>