Managing multiple lot id for produced produce.

This commit is contained in:
Cyril Gaudin
2016-04-08 11:14:38 +02:00
parent 2189a00fef
commit 0241328ea9
9 changed files with 212 additions and 0 deletions

View File

@@ -3,3 +3,4 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from . import models
from . import wizards

View File

@@ -18,5 +18,6 @@
"data": [
"views/mrp_bom.xml",
"views/product_template.xml",
"wizards/mrp_product_produce.xml",
],
}

View File

@@ -5,3 +5,4 @@
from . import mrp_bom
from . import product_product
from . import product_template
from . import stock_move

View File

@@ -0,0 +1,26 @@
# -*- coding: utf-8 -*-
# © 2016 Cyril Gaudin (Camptocamp)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from openerp import api, models
class StockMove(models.Model):
_inherit = 'stock.move'
@api.multi
def action_consume(self, product_qty, location_id=False,
restrict_lot_id=False, restrict_partner_id=False,
consumed_for=False):
""" Override restrict_lot_id if user define one for this move's
product in wizard.
"""
# If user define a lot_id for this move's product we override
restrict_lot_id = self.env.context.get('mapping_move_lot', {}).pop(
self.id, restrict_lot_id
)
return super(StockMove, self).action_consume(
product_qty, location_id, restrict_lot_id,
restrict_partner_id, consumed_for
)

View File

@@ -5,4 +5,5 @@
from . import test_bom
from . import test_product
from . import test_product_produce
from . import test_template

View File

@@ -0,0 +1,96 @@
# -*- coding: utf8 -*-
from openerp.tests import TransactionCase
class TestProductProduce(TransactionCase):
def test_produced_products_lots(self):
produce_model = self.env['mrp.product.produce']
product_model = self.env['product.product']
lot_model = self.env['stock.production.lot']
quant_model = self.env['stock.quant']
unit_uom = self.browse_ref('product.product_uom_unit')
wh_main = self.browse_ref('stock.warehouse0')
# Create simple bom with by products
p1 = product_model.create({'name': 'Test P1'})
p2 = product_model.create({'name': 'Test P2'})
p3 = product_model.create({'name': 'Test P3'})
# We have 1 P2 in stock
inventory = self.env['stock.inventory'].create({
'name': 'P2 inventory',
'location_id': wh_main.lot_stock_id.id,
'filter': 'partial'
})
inventory.prepare_inventory()
self.env['stock.inventory.line'].create({
'inventory_id': inventory.id,
'product_id': p2.id,
'location_id': wh_main.lot_stock_id.id,
'product_qty': 1
})
inventory.action_done()
# P1 need P2 and generates one byproduct P3
bom = self.env['mrp.bom'].create({
'product_tmpl_id': p1.product_tmpl_id.id,
'product_id': p1.id,
'product_qty': 1,
'product_uom': unit_uom.id,
})
self.env['mrp.bom.line'].create({
'bom_id': bom.id,
'product_id': p2.id,
'product_qty': 1,
'product_uom': unit_uom.id,
})
self.env['mrp.subproduct'].create({
'bom_id': bom.id,
'product_id': p3.id,
'product_qty': 1,
'product_uom': unit_uom.id,
})
# Create MRP Order
mrp_order_id = bom.create_mrp_production()['res_id']
mrp_order = self.env['mrp.production'].browse(mrp_order_id)
mrp_order.action_confirm()
mrp_order.action_assign()
# Wizard simulation
wizard = produce_model.with_context(active_id=mrp_order_id).create({})
wizard.on_change_product_id()
self.assertEqual(2, len(wizard.move_lot_ids))
self.assertEqual([p1, p3], [x.product_id for x in wizard.move_lot_ids])
lot_p1 = lot_model.create({'name': 'LOT_01', 'product_id': p1.id})
wizard.move_lot_ids[0].lot_id = lot_p1
lot_p3 = lot_model.create({'name': 'LOT_03', 'product_id': p3.id})
wizard.move_lot_ids[1].lot_id = lot_p3
wizard.do_produce()
# Check created move in mrp.production
mrp_order.refresh()
self.assertEqual(lot_p1,
mrp_order.move_created_ids2[0].restrict_lot_id)
self.assertEqual(lot_p3,
mrp_order.move_created_ids2[1].restrict_lot_id)
# Check stock.quants
p1_quants = quant_model.search([('product_id', '=', p1.id)])
self.assertEqual(1, len(p1_quants))
self.assertEqual(lot_p1, p1_quants.lot_id)
self.assertEqual(1, p1_quants.qty)
p3_quants = quant_model.search([('product_id', '=', p3.id)])
self.assertEqual(1, len(p3_quants))
self.assertEqual(1, p3_quants.qty)

View File

@@ -0,0 +1,5 @@
# -*- coding: utf-8 -*-
# © 2016 Cyril Gaudin (Camptocamp)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from . import mrp_product_produce

View File

@@ -0,0 +1,51 @@
# -*- coding: utf-8 -*-
# © 2016 Cyril Gaudin (Camptocamp)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from openerp import api, fields, models
class MrpByProductLine(models.TransientModel):
_name = "mrp.product.produced.line"
produce_id = fields.Many2one('mrp.product.produce', required=True,
string="Produce")
move_id = fields.Many2one('stock.move', required=True)
product_id = fields.Many2one('product.product',
related='move_id.product_id')
lot_id = fields.Many2one('stock.production.lot', string='Lot')
class MrpProductProduce(models.TransientModel):
_inherit = "mrp.product.produce"
move_lot_ids = fields.One2many(
'mrp.product.produced.line',
inverse_name='produce_id',
)
@api.onchange("product_id")
def on_change_product_id(self):
""" Listen to product_id changes just for filling byproducts_lot_ids.
"""
if not self.move_lot_ids:
mrp_prod = self.env["mrp.production"].browse(
self.env.context['active_id']
)
self.move_lot_ids = [
(0, None, {'move_id': move})
for move in mrp_prod.move_created_ids
]
@api.multi
def do_produce(self):
""" Stock produced products lot_id and call parent do_produce
"""
mapping_move_lot = {}
for move_lot in self.move_lot_ids:
if move_lot.lot_id:
mapping_move_lot[move_lot.move_id.id] = move_lot.lot_id.id
super(MrpProductProduce, self.with_context(
mapping_move_lot=mapping_move_lot
)).do_produce()

View File

@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!-- Manage sub products lot_id -->
<record id="view_mrp_product_produce_wizard" model="ir.ui.view">
<field name="name">MRP Product Produce</field>
<field name="model">mrp.product.produce</field>
<field name="inherit_id" ref="mrp.view_mrp_product_produce_wizard"/>
<field name="arch" type="xml">
<!-- Hide lot_id field -->
<field name="lot_id" position="attributes">
<attribute name="invisible">True</attribute>
</field>
<!-- Add produced products list for managing lot_id -->
<xpath expr="//group" position="after">
<group string="Products to produce lots" groups="stock.group_production_lot">
<field name="move_lot_ids" nolabel="1">
<tree editable="bottom" create="false" delete="false">
<field name="move_id" invisible="True"/>
<field name="product_id" readonly="True"/>
<field name="lot_id" domain="[('product_id', '=', product_id)]"
context="{'default_product_id':product_id}"/>
</tree>
</field>
</group>
</xpath>
</field>
</record>
</odoo>