Files
enterprise-addons/mrp_workorder/models/stock_move.py
T

138 lines
6.4 KiB
Python

# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import _, api, fields, models
class StockMove(models.Model):
_inherit = 'stock.move'
check_id = fields.One2many('quality.check', 'move_id')
note = fields.Html('Note', related='check_id.note')
worksheet_document = fields.Binary('Worksheet Image/PDF', compute='_compute_worksheet_document')
product_barcode = fields.Char(related='product_id.barcode')
move_line_ids_picked = fields.One2many('stock.move.line', 'move_id', domain=[('picked', '=', True)])
picking_type_prefill_shop_floor_lots = fields.Boolean(related='picking_type_id.prefill_shop_floor_lots')
@api.depends('check_id.worksheet_document')
def _compute_worksheet_document(self):
for record in self:
if record.check_id:
record.worksheet_document = record.check_id.worksheet_document
else:
record.worksheet_document = None
@api.depends('workorder_id')
def _compute_manual_consumption(self):
super()._compute_manual_consumption()
for move in self:
if move.product_id in move.workorder_id.check_ids.component_id and \
move.product_id not in move.raw_material_production_id.workorder_ids.check_ids.component_id:
move.manual_consumption = True
def _should_bypass_set_qty_producing(self):
production = self.raw_material_production_id or self.production_id
if production and ((self.product_id in production.workorder_ids.quality_point_ids.component_id) or self.operation_id):
return True
return super()._should_bypass_set_qty_producing()
def _action_assign(self, force_qty=False):
res = super()._action_assign(force_qty=force_qty)
for workorder in self.raw_material_production_id.workorder_ids:
for check in workorder.check_ids:
if check.test_type not in ('register_consumed_materials', 'register_byproducts'):
continue
check.write(workorder._defaults_from_move(check.move_id))
return res
@api.ondelete(at_uninstall=False)
def _unlink_quality_check(self):
self.env['quality.check'].search([('move_id', 'in', self.ids)]).unlink()
def action_add_from_catalog_raw(self):
mo = self.env['mrp.production'].browse(self.env.context.get('order_id'))
return mo.with_context(child_field='move_raw_ids', from_shop_floor=self.env.context.get('from_shop_floor')).action_add_from_catalog()
def action_pass(self, keep_hidden_lines=False):
if not keep_hidden_lines:
for record in self:
if record.has_tracking != 'none' and not record.picking_type_id.prefill_shop_floor_lots:
# Remove any reserved smls that are hidden
record.move_line_ids.filtered(lambda ml: not ml.picked).unlink()
for check in self.check_id:
check.action_next()
if not self.check_id:
self.picked = True
return True
def action_undo(self):
if self.check_id:
self.check_id.write({'quality_state': 'none'})
self.picked = False
self.quantity = self.product_uom_qty
def get_quant_from_barcode(self, barcode):
self.ensure_one()
if self.product_id.tracking == 'none':
return False
lot_id = self.env['stock.lot'].search([('name', '=', barcode), ('product_id', '=', self.product_id.id)], limit=1)
if not lot_id:
lot_id = self.env['stock.lot'].with_context(active_mo_id=self.raw_material_production_id.id).create([{
'name': barcode,
'product_id': self.product_id.id
}])
return self.env['stock.quant'].create([{
'lot_id': lot_id.id,
'product_id': self.product_id.id,
'location_id': self.warehouse_id.lot_stock_id.id
}]).id
return self.env['stock.quant'].search([('lot_id', '=', lot_id.id), ('location_id', 'child_of', self.location_id.id)], limit=1).id
def _visible_quantity(self):
self.ensure_one()
if self.env.context.get('hide_unpicked'):
return sum(
sml.product_uom_id._compute_quantity(sml.quantity, self.product_uom, rounding_method='HALF-UP')
for sml in self.move_line_ids_picked
)
return super()._visible_quantity()
def _add_from_quant(self, quant):
hide_unpicked = self.product_id.tracking != 'none' and not self.picking_type_prefill_shop_floor_lots
if hide_unpicked:
move_line = next((sml for sml in self.move_line_ids if sml._takes_from_quant(quant) and not sml.picked), False)
if move_line: # Quant already has hidden sml -> make visible
move_line.picked = True
return
remaining_qty = self.product_qty - sum(sml.quantity_product_uom for sml in self.move_line_ids if not hide_unpicked or sml.picked)
if min(remaining_qty, quant.available_quantity) > 0 and self.product_id.tracking != 'serial':
qty_to_take = min(remaining_qty, quant.available_quantity)
else:
qty_to_take = 1
move_line = next((sml for sml in self.move_line_ids if sml._takes_from_quant(quant)), False)
if move_line: # Quant already has visible sml -> increase existing sml's quantity
move_line.quantity += self.product_id.uom_id._compute_quantity(qty_to_take, self.product_uom)
else: # No sml exists for quant -> make new sml
move_line_vals = self._prepare_move_line_vals(
quantity=qty_to_take,
reserved_quant=quant)
self.env['stock.move.line'].create([{**move_line_vals, 'picked': True}])
def action_add_from_quant(self, quant_id):
self._add_from_quant(self.env['stock.quant'].browse(quant_id))
if self.product_id.tracking != 'none' and (not self.picking_type_prefill_shop_floor_lots or self in self.production_id.move_byproduct_ids):
self.move_line_ids.filtered(lambda ml: not ml.picked).unlink()
if self.check_id:
self.check_id.action_next()
class StockMoveLine(models.Model):
_inherit = 'stock.move.line'
def _takes_from_quant(self, quant):
self.ensure_one()
fields_to_match = ('location_id', 'product_id', 'owner_id', 'package_id', 'lot_id')
return all(self[field] == quant[field] for field in fields_to_match)