71 lines
3.4 KiB
Python
71 lines
3.4 KiB
Python
from odoo import api, models
|
|
|
|
|
|
class QualityCheckWizard(models.TransientModel):
|
|
_inherit = 'quality.check.wizard'
|
|
|
|
# The AttributeError fix is now handled by the compatibility field in models/mrp_production.py
|
|
|
|
@api.onchange('qty_failed')
|
|
def onchange_qty_failed(self):
|
|
""" Disable enterprise quality_mrp behavior that resets qty_failed to qty_line """
|
|
pass
|
|
|
|
def do_fail(self):
|
|
""" Ensure move_line_id is populated for MO checks with Quantity control.
|
|
This is required for quality_control's _move_to_failure_location to split
|
|
the stock move correctly.
|
|
"""
|
|
check = self.current_check_id
|
|
# We mimic the enterprise/quality_mrp behavior but in our patch
|
|
if check.production_id and check.point_id.measure_on == 'move_line' and not check.move_line_id:
|
|
# Try to find a finished move line for this product
|
|
move_line = check.production_id.finished_move_line_ids.filtered(
|
|
lambda ml: ml.product_id == (check.product_id or self.product_id)
|
|
)[:1]
|
|
if move_line:
|
|
check.move_line_id = move_line
|
|
# Also set lot if available
|
|
if not check.lot_line_id and check.production_id.lot_producing_ids:
|
|
check.lot_line_id = check.production_id.lot_producing_ids[0]
|
|
|
|
return super().do_fail()
|
|
|
|
def confirm_fail(self):
|
|
""" Override to capture the quantity from the failure wizard popup """
|
|
import logging
|
|
_logger = logging.getLogger(__name__)
|
|
_logger.info(f"DEBUG: confirm_fail called. qty_failed from wizard: {self.qty_failed}")
|
|
|
|
if self.qty_failed > 0:
|
|
self.current_check_id.qty_failed_manual = self.qty_failed
|
|
_logger.info(f"DEBUG: Saved qty_failed_manual: {self.current_check_id.qty_failed_manual} to check {self.current_check_id.id}")
|
|
|
|
# Odoo 18 Wizard logic:
|
|
# self.current_check_id.do_fail()
|
|
# if self.measure_on == 'move_line':
|
|
# self.current_check_id._move_line_to_failure_location(self.failure_location_id.id, self.qty_failed)
|
|
|
|
# We replicate this but with our relaxed condition:
|
|
self.current_check_id.do_fail()
|
|
|
|
# Check if we should split the move line.
|
|
# We allow it if strictly defined as move_line check OR if a manual fail qty is provided (relaxed logic)
|
|
if self.current_check_id.point_id.measure_on == 'move_line' or self.qty_failed > 0:
|
|
_logger.info(f"DEBUG: Triggering _move_line_to_failure_location for check {self.current_check_id.id}")
|
|
# Use our ported method
|
|
self.current_check_id._move_line_to_failure_location(self.failure_location_id.id, self.qty_failed)
|
|
else:
|
|
_logger.info(f"DEBUG: Skipping _move_line_to_failure_location. measure_on={self.current_check_id.point_id.measure_on}, qty_failed={self.qty_failed}")
|
|
|
|
return self.action_generate_next_window()
|
|
|
|
def show_failure_message(self):
|
|
""" Initialize qty_failed with tested quantity or line quantity """
|
|
res = super().show_failure_message()
|
|
# If the user has already tested a specific quantity, that's likely the one they found
|
|
# failed if it's a pass/fail check on a quantity.
|
|
if self.qty_tested and self.qty_tested < self.qty_line:
|
|
self.qty_failed = self.qty_tested
|
|
return res
|