mirror of
https://github.com/bringout/oca-ocb-mrp.git
synced 2026-04-26 14:52:07 +02:00
19.0 vanilla
This commit is contained in:
parent
accf5918df
commit
6e65e8c877
688 changed files with 225434 additions and 199401 deletions
132
odoo-bringout-oca-ocb-mrp/mrp/models/stock_move_line.py
Normal file
132
odoo-bringout-oca-ocb-mrp/mrp/models/stock_move_line.py
Normal file
|
|
@ -0,0 +1,132 @@
|
|||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import api, fields, models
|
||||
from odoo.fields import Domain
|
||||
|
||||
|
||||
class StockMoveLine(models.Model):
|
||||
_inherit = 'stock.move.line'
|
||||
|
||||
workorder_id = fields.Many2one('mrp.workorder', 'Work Order', check_company=True, index='btree_not_null')
|
||||
production_id = fields.Many2one('mrp.production', 'Production Order', check_company=True)
|
||||
|
||||
@api.depends('production_id')
|
||||
def _compute_picking_type_id(self):
|
||||
line_to_remove = self.env['stock.move.line']
|
||||
for line in self:
|
||||
if production_id := line.production_id or line.move_id.production_id:
|
||||
line.picking_type_id = production_id.picking_type_id
|
||||
line_to_remove |= line
|
||||
return super(StockMoveLine, self - line_to_remove)._compute_picking_type_id()
|
||||
|
||||
def _search_picking_type_id(self, operator, value):
|
||||
if operator in Domain.NEGATIVE_OPERATORS:
|
||||
return NotImplemented
|
||||
domain = super()._search_picking_type_id(operator, value)
|
||||
return (Domain('production_id', '=', False) & domain) | Domain('production_id.picking_type_id', operator, value)
|
||||
|
||||
@api.model_create_multi
|
||||
def create(self, vals_list):
|
||||
res = super().create(vals_list)
|
||||
for line in res:
|
||||
# If the line is added in a done production, we need to map it
|
||||
# manually to the produced move lines in order to see them in the
|
||||
# traceability report
|
||||
if line.move_id.raw_material_production_id and line.state == 'done':
|
||||
mo = line.move_id.raw_material_production_id
|
||||
finished_lots = mo.lot_producing_ids
|
||||
finished_lots |= mo.move_finished_ids.filtered(lambda m: m.product_id != mo.product_id).move_line_ids.lot_id
|
||||
if finished_lots:
|
||||
produced_move_lines = mo.move_finished_ids.move_line_ids.filtered(lambda sml: sml.lot_id in finished_lots)
|
||||
line.produce_line_ids = [(6, 0, produced_move_lines.ids)]
|
||||
else:
|
||||
produced_move_lines = mo.move_finished_ids.move_line_ids
|
||||
line.produce_line_ids = [(6, 0, produced_move_lines.ids)]
|
||||
return res
|
||||
|
||||
def _get_similar_move_lines(self):
|
||||
lines = super()._get_similar_move_lines()
|
||||
if self.move_id.production_id:
|
||||
finished_moves = self.move_id.production_id.move_finished_ids
|
||||
finished_move_lines = finished_moves.mapped('move_line_ids')
|
||||
lines |= finished_move_lines.filtered(lambda ml: ml.product_id == self.product_id and (ml.lot_id or ml.lot_name))
|
||||
if self.move_id.raw_material_production_id:
|
||||
raw_moves = self.move_id.raw_material_production_id.move_raw_ids
|
||||
raw_moves_lines = raw_moves.mapped('move_line_ids')
|
||||
lines |= raw_moves_lines.filtered(lambda ml: ml.product_id == self.product_id and (ml.lot_id or ml.lot_name))
|
||||
return lines
|
||||
|
||||
def write(self, vals):
|
||||
for move_line in self:
|
||||
production = move_line.move_id.production_id or move_line.move_id.raw_material_production_id
|
||||
if production and move_line.state == 'done' and any(field in vals for field in ('lot_id', 'location_id', 'quantity')):
|
||||
move_line._log_message(production, move_line, 'mrp.track_production_move_template', vals)
|
||||
return super().write(vals)
|
||||
|
||||
def _get_aggregated_properties(self, move_line=False, move=False):
|
||||
aggregated_properties = super()._get_aggregated_properties(move_line, move)
|
||||
bom = aggregated_properties['move'].bom_line_id.bom_id
|
||||
aggregated_properties['bom'] = bom or False
|
||||
aggregated_properties['line_key'] += f'_{bom.id if bom else ""}'
|
||||
return aggregated_properties
|
||||
|
||||
def _get_aggregated_product_quantities(self, **kwargs):
|
||||
"""Returns dictionary of products and corresponding values of interest grouped by optional kit_name
|
||||
|
||||
Removes descriptions where description == kit_name. kit_name is expected to be passed as a
|
||||
kwargs value because this is not directly stored in move_line_ids. Unfortunately because we
|
||||
are working with aggregated data, we have to loop through the aggregation to do this removal.
|
||||
|
||||
arguments: kit_name (optional): string value of a kit name passed as a kwarg
|
||||
returns: dictionary {same_key_as_super: {same_values_as_super, ...}
|
||||
"""
|
||||
aggregated_move_lines = super()._get_aggregated_product_quantities(**kwargs)
|
||||
kit_name = kwargs.get('kit_name')
|
||||
|
||||
to_be_removed = []
|
||||
for aggregated_move_line in aggregated_move_lines:
|
||||
bom = aggregated_move_lines[aggregated_move_line]['bom']
|
||||
is_phantom = bom.type == 'phantom' if bom else False
|
||||
if kit_name:
|
||||
product = bom.product_id or bom.product_tmpl_id if bom else False
|
||||
display_name = product.display_name if product else False
|
||||
description = aggregated_move_lines[aggregated_move_line]['description']
|
||||
if not is_phantom or display_name != kit_name:
|
||||
to_be_removed.append(aggregated_move_line)
|
||||
elif description == kit_name:
|
||||
aggregated_move_lines[aggregated_move_line]['description'] = ""
|
||||
elif not kwargs and is_phantom:
|
||||
to_be_removed.append(aggregated_move_line)
|
||||
|
||||
for move_line in to_be_removed:
|
||||
del aggregated_move_lines[move_line]
|
||||
|
||||
return aggregated_move_lines
|
||||
|
||||
def _prepare_stock_move_vals(self):
|
||||
move_vals = super()._prepare_stock_move_vals()
|
||||
if self.env['product.product'].browse(move_vals['product_id']).is_kits:
|
||||
move_vals['location_id'] = self.location_id.id
|
||||
move_vals['location_dest_id'] = self.location_dest_id.id
|
||||
return move_vals
|
||||
|
||||
def _get_linkable_moves(self):
|
||||
""" Don't linke move lines with kit products to moves with dissimilar locations so that
|
||||
post `action_explode()` move lines will have accurate location data.
|
||||
"""
|
||||
self.ensure_one()
|
||||
if self.product_id and self.product_id.is_kits:
|
||||
moves = self.picking_id.move_ids.filtered(lambda move:
|
||||
move.product_id == self.product_id and
|
||||
move.location_id == self.location_id and
|
||||
move.location_dest_id == self.location_dest_id
|
||||
)
|
||||
return sorted(moves, key=lambda m: m.quantity < m.product_qty, reverse=True)
|
||||
else:
|
||||
return super()._get_linkable_moves()
|
||||
|
||||
def _exclude_requiring_lot(self):
|
||||
return (
|
||||
self.move_id.unbuild_id
|
||||
and not self.move_id.origin_returned_move_id.move_line_ids.lot_id
|
||||
) or super()._exclude_requiring_lot()
|
||||
Loading…
Add table
Add a link
Reference in a new issue