feat: Implement precise unit factor calculation for BOM-related stock moves and add a script to fix existing MO quantity decimals.
This commit is contained in:
parent
3b19d279ff
commit
4fd8c57af3
49
fix_mo_decimals.py
Normal file
49
fix_mo_decimals.py
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
import xmlrpc.client
|
||||||
|
import ssl
|
||||||
|
|
||||||
|
url = "https://trialerp.mapan.co.id"
|
||||||
|
username = 'suherdy.yacob'
|
||||||
|
api_key = '27aa1dfc979d5507973b190018329d0690400c66'
|
||||||
|
selected_db = 'mapangroup_trial_o19'
|
||||||
|
context = ssl._create_unverified_context()
|
||||||
|
|
||||||
|
try:
|
||||||
|
common = xmlrpc.client.ServerProxy(f'{url}/xmlrpc/2/common', context=context)
|
||||||
|
uid = common.authenticate(selected_db, username, api_key, {})
|
||||||
|
models = xmlrpc.client.ServerProxy('{}/xmlrpc/2/object'.format(url), context=context)
|
||||||
|
|
||||||
|
# Search for all draft or confirmed MOs to recalculate quantities based on true BOM ratios.
|
||||||
|
mo_ids = models.execute_kw(selected_db, uid, api_key, 'mrp.production', 'search', [[('state', 'in', ['draft', 'confirmed'])]])
|
||||||
|
|
||||||
|
print(f"Found {len(mo_ids)} active MOs.")
|
||||||
|
|
||||||
|
for mo_id in mo_ids:
|
||||||
|
mo = models.execute_kw(selected_db, uid, api_key, 'mrp.production', 'read', [[mo_id]], {'fields': ['name', 'product_qty', 'bom_id', 'move_raw_ids']})[0]
|
||||||
|
if not mo.get('bom_id'):
|
||||||
|
continue
|
||||||
|
|
||||||
|
print(f"Checking MO {mo['name']}...")
|
||||||
|
bom = models.execute_kw(selected_db, uid, api_key, 'mrp.bom', 'read', [[mo['bom_id'][0]]], {'fields': ['product_qty', 'bom_line_ids']})[0]
|
||||||
|
bom_qty = bom['product_qty']
|
||||||
|
|
||||||
|
# Read BOM lines to get exact ratios
|
||||||
|
bom_lines = models.execute_kw(selected_db, uid, api_key, 'mrp.bom.line', 'read', [bom['bom_line_ids']], {'fields': ['product_qty']})
|
||||||
|
bom_ratios = {bl['id']: bl['product_qty'] / bom_qty for bl in bom_lines}
|
||||||
|
|
||||||
|
moves = models.execute_kw(selected_db, uid, api_key, 'stock.move', 'read', [mo['move_raw_ids']], {'fields': ['bom_line_id', 'product_uom_qty']})
|
||||||
|
|
||||||
|
for move in moves:
|
||||||
|
if move.get('bom_line_id'):
|
||||||
|
bom_line_id = move['bom_line_id'][0]
|
||||||
|
if bom_line_id in bom_ratios:
|
||||||
|
correct_qty = bom_ratios[bom_line_id] * mo['product_qty']
|
||||||
|
current_qty = move.get('product_uom_qty') or 0.0
|
||||||
|
|
||||||
|
if abs(correct_qty - current_qty) > 0.0001:
|
||||||
|
print(f" - Fixing move {move['id']}: qty {current_qty} -> exact integer {correct_qty}")
|
||||||
|
models.execute_kw(selected_db, uid, api_key, 'stock.move', 'write', [[move['id']], {'product_uom_qty': correct_qty}])
|
||||||
|
|
||||||
|
print("Finished checking MOs.")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print("Error:", e)
|
||||||
@ -3,4 +3,6 @@ from . import mrp_production
|
|||||||
from . import mrp_bom
|
from . import mrp_bom
|
||||||
from . import mrp_production_schedule
|
from . import mrp_production_schedule
|
||||||
from . import mrp_packaging
|
from . import mrp_packaging
|
||||||
|
from . import stock_move
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
22
models/stock_move.py
Normal file
22
models/stock_move.py
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
from odoo import api, models
|
||||||
|
|
||||||
|
class StockMove(models.Model):
|
||||||
|
_inherit = 'stock.move'
|
||||||
|
|
||||||
|
@api.depends('product_uom_qty', 'raw_material_production_id', 'raw_material_production_id.product_qty', 'raw_material_production_id.qty_producing')
|
||||||
|
def _compute_unit_factor(self):
|
||||||
|
super()._compute_unit_factor()
|
||||||
|
for move in self:
|
||||||
|
mo = move.raw_material_production_id or move.production_id
|
||||||
|
# Prevent 3-decimal rounding drift if the move comes from a BOM Line!
|
||||||
|
if mo and mo.bom_id and move.bom_line_id:
|
||||||
|
# Use the exact, unrounded mathematical ratio directly from BOM line and UoMs.
|
||||||
|
bom_line = move.bom_line_id
|
||||||
|
bom = mo.bom_id
|
||||||
|
|
||||||
|
# Fetch quantities directly converting to product matching formats without DB truncation
|
||||||
|
line_qty = bom_line.product_uom_id._compute_quantity(bom_line.product_qty, bom_line.product_id.uom_id, round=False)
|
||||||
|
bom_qty = bom.product_uom_id._compute_quantity(bom.product_qty, bom.product_tmpl_id.uom_id, round=False)
|
||||||
|
|
||||||
|
if bom_qty:
|
||||||
|
move.unit_factor = line_qty / bom_qty
|
||||||
Loading…
Reference in New Issue
Block a user