From d4a70eab4d741406d9cd0e5756e2f2fbf00e9fd2 Mon Sep 17 00:00:00 2001 From: clesgow Date: Fri, 10 Mar 2023 17:21:05 +0000 Subject: [PATCH] [FIX] {purchase_,}mrp: fix wrong uom for Overview replenishments The MO Overview would display the wrong uom in the replenishments lines of the MO Overview. Since the data was pulled from the forecast report (which displays it in the product's uom), it could not coincide with the ones used in the MO. Part-of: odoo/odoo#118023 --- addons/mrp/report/mrp_report_mo_overview.py | 20 ++++++++-------- .../report/mrp_report_mo_overview.py | 24 +++++++++---------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/addons/mrp/report/mrp_report_mo_overview.py b/addons/mrp/report/mrp_report_mo_overview.py index 0fe4ec390fc..727463f1369 100644 --- a/addons/mrp/report/mrp_report_mo_overview.py +++ b/addons/mrp/report/mrp_report_mo_overview.py @@ -258,7 +258,7 @@ class ReportMoOverview(models.AbstractModel): doc_in = self.env[forecast_line['document_in']['_name']].browse(forecast_line['document_in']['id']) replenishment_index = f"{current_index}{count}" replenishment = {} - uom_id = self.env['uom.uom'].browse(forecast_line['uom_id']['id']) + forecast_uom_id = forecast_line['uom_id'] replenishment['summary'] = { 'level': level + 1, 'index': replenishment_index, @@ -269,11 +269,11 @@ class ReportMoOverview(models.AbstractModel): 'product_id': product.id, 'state': doc_in.state, 'formatted_state': self._format_state(doc_in), - 'quantity': forecast_line['quantity'], - 'uom_name': forecast_line['uom_id']['display_name'], + 'quantity': min(move_raw.product_uom_qty, forecast_uom_id._compute_quantity(forecast_line['quantity'], move_raw.product_uom)), # Avoid over-rounding + 'uom_name': move_raw.product_uom.display_name, 'uom_precision': self._get_uom_precision(forecast_line['uom_id']['rounding']), - 'mo_cost': self._get_replenishment_cost(product, forecast_line['quantity'], uom_id, currency, forecast_line['move_in']), - 'product_cost': currency.round(uom_id._compute_quantity(forecast_line['quantity'], product.uom_id) * product.standard_price), + 'mo_cost': self._get_replenishment_cost(product, forecast_line['quantity'], forecast_uom_id, currency, forecast_line['move_in']), + 'product_cost': currency.round(forecast_uom_id._compute_quantity(forecast_line['quantity'], product.uom_id) * product.standard_price), 'currency_id': currency.id, 'currency': currency, } @@ -395,7 +395,7 @@ class ReportMoOverview(models.AbstractModel): continue if production_id and extra.get('production_id', False) and extra['production_id'] != production_id: continue - taken_from_extra = min(line_qty, extra['quantity']) + taken_from_extra = min(line_qty, extra['uom']._compute_quantity(extra['quantity'], forecast_line['uom_id'])) line_qty -= taken_from_extra # Create copy of the current forecast line to add a possible replenishment. # Needs to be a copy since it might take multiple replenishment to fulfill a single "out" line. @@ -452,12 +452,12 @@ class ReportMoOverview(models.AbstractModel): for move in linked_moves: if move.state not in ('partially_available', 'assigned'): continue - # count reserved stock. - reserved = move.product_uom._compute_quantity(move.reserved_availability, move.product_id.uom_id) + # count reserved stock in move_raw's uom + reserved = move.product_uom._compute_quantity(move.reserved_availability, move_raw.product_uom) # check if the move reserved qty was counted before (happens if multiple outs share pick/pack) - reserved = min(reserved - replenish_data['qty_already_reserved'][move], move_raw.product_qty) + reserved = min(reserved - move.product_uom._compute_quantity(replenish_data['qty_already_reserved'][move], move_raw.product_uom), move_raw.product_uom_qty) total_reserved += reserved - replenish_data['qty_already_reserved'][move] += reserved + replenish_data['qty_already_reserved'][move] += move_raw.product_uom._compute_quantity(reserved, move.product_uom) if float_compare(total_reserved, move_raw.product_qty, precision_rounding=move.product_id.uom_id.rounding) >= 0: break replenish_data['qty_reserved'][move_raw] = total_reserved diff --git a/addons/purchase_mrp/report/mrp_report_mo_overview.py b/addons/purchase_mrp/report/mrp_report_mo_overview.py index bceb8cbabc4..6da3bbf90ed 100644 --- a/addons/purchase_mrp/report/mrp_report_mo_overview.py +++ b/addons/purchase_mrp/report/mrp_report_mo_overview.py @@ -2,7 +2,6 @@ # Part of Odoo. See LICENSE file for full copyright and licensing details. from odoo import models -from odoo.tools import float_compare class ReportMoOverview(models.AbstractModel): _inherit = 'report.mrp.report_mo_overview' @@ -16,17 +15,17 @@ class ReportMoOverview(models.AbstractModel): po_lines = self.env['purchase.order.line'].search(domain, order='date_planned, id') for po_line in po_lines: - line_qty = po_line.product_uom_qty - if po_line.move_dest_ids.raw_material_production_id: - for move in po_line.move_dest_ids: - if float_compare(line_qty, move.product_uom_qty, precision_rounding=po_line.product_uom.rounding) >= 0: - prod_qty = move.product_uom_qty - else: - prod_qty = line_qty - res.append(self._format_extra_replenishment(po_line, prod_qty, move.raw_material_production_id.id)) - line_qty -= prod_qty - else: - res.append(self._format_extra_replenishment(po_line, po_line.product_uom_qty)) + line_qty = po_line.product_qty + for move in po_line.move_dest_ids: + linked_production = self.env['stock.move'].browse(move._rollup_move_dests()).raw_material_production_id + # Only create specific lines for moves directly linked to a manufacturing order + if not linked_production: + continue + prod_qty = min(line_qty, move.product_uom._compute_quantity(move.product_uom_qty, po_line.product_uom)) + res.append(self._format_extra_replenishment(po_line, prod_qty, linked_production.id)) + line_qty -= prod_qty + if line_qty: + res.append(self._format_extra_replenishment(po_line, line_qty)) return res @@ -36,6 +35,7 @@ class ReportMoOverview(models.AbstractModel): 'id': po_line.order_id.id, 'cost': po_line.price_total, 'quantity': quantity, + 'uom': po_line.product_uom, 'production_id': production_id }