-
-
Notifications
You must be signed in to change notification settings - Fork 469
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
410 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 8.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/8.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. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
18 changes: 18 additions & 0 deletions
18
mrp_production_raw_material_procurement_group/__openerp__.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
# -*- 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": "8.0.1.0.0", | ||
"category": "Manufacturing", | ||
"website": "https://opensynergy-indonesia.com/", | ||
"author": "OpenSynergy Indonesia, Odoo Community Association (OCA)", | ||
"license": "AGPL-3", | ||
"installable": True, | ||
"depends": [ | ||
"mrp", | ||
], | ||
"data": [ | ||
"views/mrp_production_views.xml", | ||
], | ||
} |
5 changes: 5 additions & 0 deletions
5
mrp_production_raw_material_procurement_group/models/__init__.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
75 changes: 75 additions & 0 deletions
75
mrp_production_raw_material_procurement_group/models/mrp_production.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
# -*- 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 _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({ | ||
"name": self.name}) | ||
|
||
@api.model | ||
def _make_consume_line_from_data( | ||
self, | ||
production, product, uom_id, qty, | ||
uos_id, uos_qty): | ||
|
||
move_id = super(MrpProduction, self)._make_consume_line_from_data( | ||
production, product, uom_id, qty, | ||
uos_id, uos_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 added
BIN
+9.23 KB
mrp_production_raw_material_procurement_group/static/description/icon.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions
5
mrp_production_raw_material_procurement_group/tests/__init__.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
202 changes: 202 additions & 0 deletions
202
mrp_production_raw_material_procurement_group/tests/test_mrp_production.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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_1(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_copy_mo_2(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) |
Oops, something went wrong.