[11.0][MIG] mrp_production_request

This commit is contained in:
Lois Rilo
2018-09-13 15:55:07 +02:00
committed by Chandresh Thakkar
parent 4269e2771c
commit 423183102f
25 changed files with 490 additions and 299 deletions

View File

@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Copyright 2017-18 Eficent Business and IT Consulting Services S.L.
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
@@ -11,7 +10,7 @@ class MrpProductionRequest(models.Model):
_name = "mrp.production.request"
_description = "Manufacturing Request"
_inherit = "mail.thread"
_order = "id DESC"
_order = "date_planned_start desc, id desc"
@api.model
def _company_get(self):
@@ -22,59 +21,6 @@ class MrpProductionRequest(models.Model):
def _get_default_requested_by(self):
return self.env.user
@api.multi
def _subscribe_assigned_user(self, vals):
self.ensure_one()
if vals.get('assigned_to'):
self.message_subscribe_users(user_ids=[self.assigned_to.id])
@api.model
def _create_sequence(self, vals):
if not vals.get('name') or vals.get('name') == '/':
vals['name'] = self.env['ir.sequence'].next_by_code(
'mrp.production.request') or '/'
return vals
@api.model
def create(self, vals):
"""Add sequence if name is not defined and subscribe to the thread
the user assigned to the request."""
vals = self._create_sequence(vals)
res = super(MrpProductionRequest, self).create(vals)
res._subscribe_assigned_user(vals)
return res
@api.multi
def write(self, vals):
res = super(MrpProductionRequest, self).write(vals)
for request in self:
request._subscribe_assigned_user(vals)
return res
@api.onchange('product_id')
def _onchange_product_id(self):
self.product_uom_id = self.product_id.uom_id
self.bom_id = self.env['mrp.bom']._bom_find(
product=self.product_id, company_id=self.company_id.id,
picking_type=self.picking_type_id)
@api.model
def _get_mo_valid_states(self):
return ['draft', 'confirmed', 'ready', 'in_production', 'done']
@api.multi
@api.depends('mrp_production_ids', 'mrp_production_ids.state', 'state')
def _compute_manufactured_qty(self):
valid_states = self._get_mo_valid_states()
for req in self:
done_mo = req.mrp_production_ids.filtered(
lambda mo: mo.state in 'done').mapped('product_qty')
req.done_qty = sum(done_mo)
valid_mo = req.mrp_production_ids.filtered(
lambda mo: mo.state in valid_states).mapped('product_qty')
req.manufactured_qty = sum(valid_mo)
req.pending_qty = max(req.product_qty - req.manufactured_qty, 0.0)
name = fields.Char(
default="/", required=True,
readonly=True, states={'draft': [('readonly', False)]})
@@ -89,7 +35,10 @@ class MrpProductionRequest(models.Model):
assigned_to = fields.Many2one(
comodel_name='res.users', string='Approver',
track_visibility='onchange',
readonly=True, states={'draft': [('readonly', False)]})
readonly=True, states={'draft': [('readonly', False)]},
domain=lambda self: [('groups_id', 'in', self.env.ref(
'mrp_production_request.'
'group_mrp_production_request_manager').id)])
description = fields.Text('Description')
date_planned_start = fields.Datetime(
'Deadline Start', copy=False, default=fields.Datetime.now,
@@ -105,6 +54,10 @@ class MrpProductionRequest(models.Model):
mrp_production_ids = fields.One2many(
comodel_name="mrp.production", string="Manufacturing Orders",
inverse_name="mrp_production_request_id", readonly=True)
mrp_production_count = fields.Integer(
compute="_compute_mrp_production_count",
string="MO's Count",
)
state = fields.Selection(
selection=[("draft", "Draft"),
("to_approve", "To Be Approved"),
@@ -117,21 +70,11 @@ class MrpProductionRequest(models.Model):
string='Procurement Group',
comodel_name='procurement.group',
copy=False)
procurement_ids = fields.One2many(
string='Related Procurements',
comodel_name='procurement.order',
inverse_name='mrp_production_request_id')
propagate = fields.Boolean(
'Propagate cancel and split',
help='If checked, when the previous move of the move '
'(which was generated by a next procurement) is cancelled '
'or split, the move generated by this move will too')
procurement_id = fields.Many2one(
comodel_name="procurement.order", string="Procurement Order",
readonly=True)
procurement_state = fields.Selection(
related='procurement_id.state',
store=True, readonly=True, string="Procurement State")
product_id = fields.Many2one(
comodel_name="product.product", string="Product", required=True,
domain=[('type', 'in', ['product', 'consu'])],
@@ -142,7 +85,7 @@ class MrpProductionRequest(models.Model):
related='product_id.product_tmpl_id')
product_qty = fields.Float(
string="Required Quantity", required=True, track_visibility='onchange',
digits=dp.get_precision('Product Unit of Measure'),
digits=dp.get_precision('Product Unit of Measure'), default=1.0,
readonly=True, states={'draft': [('readonly', False)]})
product_uom_id = fields.Many2one(
comodel_name='product.uom', string='Unit of Measure',
@@ -151,16 +94,16 @@ class MrpProductionRequest(models.Model):
category_uom_id = fields.Many2one(related="product_uom_id.category_id")
manufactured_qty = fields.Float(
string="Quantity in Manufacturing Orders",
compute=_compute_manufactured_qty, store=True, readonly=True,
compute="_compute_manufactured_qty", store=True, readonly=True,
digits=dp.get_precision('Product Unit of Measure'),
help="Sum of the quantities in Manufacturing Orders (in any state).")
done_qty = fields.Float(
string="Quantity Done", store=True, readonly=True,
compute=_compute_manufactured_qty,
compute="_compute_manufactured_qty",
digits=dp.get_precision('Product Unit of Measure'),
help="Sum of the quantities in all done Manufacturing Orders.")
pending_qty = fields.Float(
string="Pending Quantity", compute=_compute_manufactured_qty,
string="Pending Quantity", compute="_compute_manufactured_qty",
store=True, digits=dp.get_precision('Product Unit of Measure'),
readonly=True,
help="Quantity pending to add to Manufacturing Orders "
@@ -191,6 +134,76 @@ class MrpProductionRequest(models.Model):
default=lambda self: self.env['stock.picking.type'].browse(
self.env['mrp.production']._get_default_picking_type()),
required=True, readonly=True, states={'draft': [('readonly', False)]})
move_dest_ids = fields.One2many(
comodel_name='stock.move',
inverse_name='created_mrp_production_request_id',
string="Stock Movements of Produced Goods")
orderpoint_id = fields.Many2one(
comodel_name='stock.warehouse.orderpoint',
string='Orderpoint')
_sql_constraints = [
('name_uniq', 'unique(name, company_id)',
'Reference must be unique per Company!'),
]
@api.model
def _get_mo_valid_states(self):
return ['planned', 'confirmed', 'progress', 'done']
@api.multi
@api.depends('mrp_production_ids', 'mrp_production_ids.state', 'state')
def _compute_manufactured_qty(self):
valid_states = self._get_mo_valid_states()
for req in self:
done_mo = req.mrp_production_ids.filtered(
lambda mo: mo.state in 'done').mapped('product_qty')
req.done_qty = sum(done_mo)
valid_mo = req.mrp_production_ids.filtered(
lambda mo: mo.state in valid_states).mapped('product_qty')
req.manufactured_qty = sum(valid_mo)
req.pending_qty = max(req.product_qty - req.manufactured_qty, 0.0)
@api.multi
def _compute_mrp_production_count(self):
for rec in self:
rec.mrp_production_count = len(rec.mrp_production_ids)
@api.onchange('product_id')
def _onchange_product_id(self):
self.product_uom_id = self.product_id.uom_id
self.bom_id = self.env['mrp.bom']._bom_find(
product=self.product_id, company_id=self.company_id.id,
picking_type=self.picking_type_id)
@api.multi
def _subscribe_assigned_user(self, vals):
self.ensure_one()
if vals.get('assigned_to'):
self.message_subscribe_users(user_ids=[self.assigned_to.id])
@api.model
def _create_sequence(self, vals):
if not vals.get('name') or vals.get('name') == '/':
vals['name'] = self.env['ir.sequence'].next_by_code(
'mrp.production.request') or '/'
return vals
@api.model
def create(self, vals):
"""Add sequence if name is not defined and subscribe to the thread
the user assigned to the request."""
vals = self._create_sequence(vals)
res = super(MrpProductionRequest, self).create(vals)
res._subscribe_assigned_user(vals)
return res
@api.multi
def write(self, vals):
res = super(MrpProductionRequest, self).write(vals)
for request in self:
request._subscribe_assigned_user(vals)
return res
@api.multi
def button_to_approve(self):
@@ -205,8 +218,6 @@ class MrpProductionRequest(models.Model):
@api.multi
def button_done(self):
self.write({'state': 'done'})
if self.mapped('procurement_id'):
self.mapped('procurement_id').write({'state': 'done'})
return True
@api.multi
@@ -216,11 +227,6 @@ class MrpProductionRequest(models.Model):
raise UserError(
_("You cannot reset a manufacturing request if the related "
"manufacturing orders are not cancelled."))
if any([s in ['done', 'cancel'] for s in self.mapped(
'procurement_id.state')]):
raise UserError(
_("You cannot reset a manufacturing request related to "
"done or cancelled procurement orders."))
@api.multi
def button_draft(self):
@@ -230,8 +236,7 @@ class MrpProductionRequest(models.Model):
@api.multi
def _check_cancel_allowed(self):
if any([s == 'done' for s in self.mapped(
'procurement_id.state')]):
if any([s == 'done' for s in self.mapped('state')]):
raise UserError(
_('You cannot reject a manufacturing request related to '
'done procurement orders.'))
@@ -240,15 +245,21 @@ class MrpProductionRequest(models.Model):
def button_cancel(self):
self._check_cancel_allowed()
self.write({'state': 'cancel'})
self.mapped('procurement_id').with_context(
from_mrp_production_request=True).cancel()
if not self.env.context.get('cancel_procurement'):
procurements = self.mapped('procurement_id')
procurements.filtered(lambda r: r.state not in (
'cancel', 'exception') and not r.rule_id.propagate).write(
{'state': 'exception'})
moves = procurements.filtered(
lambda r: r.rule_id.propagate).mapped(
'move_dest_id')
moves.filtered(lambda r: r.state != 'cancel').action_cancel()
self.mapped('move_dest_ids').filtered(
lambda r: r.state != 'cancel')._action_cancel()
return True
@api.multi
def action_view_mrp_productions(self):
action = self.env.ref('mrp.mrp_production_action')
result = action.read()[0]
result['context'] = {}
mos = self.mapped('mrp_production_ids')
# choose the view_mode accordingly
if len(mos) != 1:
result['domain'] = [('id', 'in', mos.ids)]
elif len(mos) == 1:
form = self.env.ref('mrp.mrp_production_form_view', False)
result['views'] = [(form and form.id or False, 'form')]
result['res_id'] = mos[0].id
return result