1# -*- coding: utf-8 -*-
2# Part of Odoo. See LICENSE file for full copyright and licensing details.
3
4from odoo import _, api, fields, models
5from odoo.exceptions import UserError
6from odoo.tools import float_compare
7
8
9class MrpImmediateProductionLine(models.TransientModel):
10    _name = 'mrp.immediate.production.line'
11    _description = 'Immediate Production Line'
12
13    immediate_production_id = fields.Many2one('mrp.immediate.production', 'Immediate Production', required=True)
14    production_id = fields.Many2one('mrp.production', 'Production', required=True)
15    to_immediate = fields.Boolean('To Process')
16
17
18class MrpImmediateProduction(models.TransientModel):
19    _name = 'mrp.immediate.production'
20    _description = 'Immediate Production'
21
22    @api.model
23    def default_get(self, fields):
24        res = super().default_get(fields)
25        if 'immediate_production_line_ids' in fields:
26            if self.env.context.get('default_mo_ids'):
27                res['mo_ids'] = self.env.context['default_mo_ids']
28                res['immediate_production_line_ids'] = [(0, 0, {'to_immediate': True, 'production_id': mo_id[1]}) for mo_id in res['mo_ids']]
29        return res
30
31    mo_ids = fields.Many2many('mrp.production', 'mrp_production_production_rel')
32    show_productions = fields.Boolean(compute='_compute_show_production')
33    immediate_production_line_ids = fields.One2many(
34        'mrp.immediate.production.line',
35        'immediate_production_id',
36        string="Immediate Production Lines")
37
38    @api.depends('immediate_production_line_ids')
39    def _compute_show_production(self):
40        for wizard in self:
41            wizard.show_productions = len(wizard.immediate_production_line_ids.production_id) > 1
42
43    def process(self):
44        productions_to_do = self.env['mrp.production']
45        productions_not_to_do = self.env['mrp.production']
46        for line in self.immediate_production_line_ids:
47            if line.to_immediate is True:
48                productions_to_do |= line.production_id
49            else:
50                productions_not_to_do |= line.production_id
51
52        for production in productions_to_do:
53            error_msg = ""
54            if production.product_tracking in ('lot', 'serial') and not production.lot_producing_id:
55                production.action_generate_serial()
56            if production.product_tracking == 'serial' and float_compare(production.qty_producing, 1, precision_rounding=production.product_uom_id.rounding) == 1:
57                production.qty_producing = 1
58            else:
59                production.qty_producing = production.product_qty - production.qty_produced
60            production._set_qty_producing()
61            for move in production.move_raw_ids.filtered(lambda m: m.state not in ['done', 'cancel']):
62                rounding = move.product_uom.rounding
63                for move_line in move.move_line_ids:
64                    if move_line.product_uom_qty:
65                        move_line.qty_done = min(move_line.product_uom_qty, move_line.move_id.should_consume_qty)
66                    if float_compare(move.quantity_done, move.should_consume_qty, precision_rounding=rounding) >= 0:
67                        break
68                if float_compare(move.product_uom_qty, move.quantity_done, precision_rounding=move.product_uom.rounding) == 1:
69                    if move.has_tracking in ('serial', 'lot'):
70                        error_msg += "\n  - %s" % move.product_id.display_name
71
72            if error_msg:
73                error_msg = _('You need to supply Lot/Serial Number for products:') + error_msg
74                raise UserError(error_msg)
75
76        productions_to_validate = self.env.context.get('button_mark_done_production_ids')
77        if productions_to_validate:
78            productions_to_validate = self.env['mrp.production'].browse(productions_to_validate)
79            productions_to_validate = productions_to_validate - productions_not_to_do
80            return productions_to_validate.with_context(skip_immediate=True).button_mark_done()
81        return True
82
83