From b796e62f24bde37c180dcebacf1b222b8e710a27 Mon Sep 17 00:00:00 2001 From: Suherdy Yacob Date: Thu, 5 Mar 2026 08:56:41 +0700 Subject: [PATCH] refactor: rewrite MO decimal fixing script to use direct Odoo ORM instead of XML-RPC. --- fix_mo_decimals.py | 57 +++++++++++++--------------------------------- 1 file changed, 16 insertions(+), 41 deletions(-) diff --git a/fix_mo_decimals.py b/fix_mo_decimals.py index 68a931a..87f98d0 100644 --- a/fix_mo_decimals.py +++ b/fix_mo_decimals.py @@ -1,45 +1,20 @@ -import xmlrpc.client -import ssl +# Run this script using your odoo shell on the server: +# ./odoo-bin shell -c odoo.conf -d mapangroup_trial_o19 < /home/bukanadmin/odoo19/customaddons/mrp_packaging_qty/fix_mo_decimals.py -url = "https://trialerp.mapan.co.id" -username = 'suherdy.yacob' -api_key = '27aa1dfc979d5507973b190018329d0690400c66' -selected_db = 'mapangroup_trial_o19' -context = ssl._create_unverified_context() +mos = env['mrp.production'].search([('state', 'in', ['draft', 'confirmed'])]) +fixed_count = 0 -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. - 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', 'move_raw_ids']})[0] - - move_ids = mo.get('move_raw_ids', []) - if not move_ids: - continue +for mo in mos: + for move in mo.move_raw_ids: + if move.product_uom_qty: + # Round to two decimals cleanly + clean_qty = round(move.product_uom_qty, 2) - print(f"Checking MO {mo['name']}...") - moves = models.execute_kw(selected_db, uid, api_key, 'stock.move', 'read', [move_ids], {'fields': ['product_uom_qty']}) - - for move in moves: - current_qty = move.get('product_uom_qty') or 0.0 - - # Detect +0.001 to +0.009 floating point noise - # by comparing it against its cleanly rounded 2-decimal version. - clean_qty = round(current_qty, 2) - fraction_diff = abs(current_qty - clean_qty) - - if 0.0001 < fraction_diff < 0.01: - print(f" - Fixing move {move['id']}: qty {current_qty} -> clean {clean_qty}") - models.execute_kw(selected_db, uid, api_key, 'stock.move', 'write', [[move['id']], {'product_uom_qty': clean_qty}]) + # If the quantity is dirty by .001 or .009 etc... + if 0.0001 < abs(move.product_uom_qty - clean_qty) < 0.01: + print(f"Fixing {mo.name} component {move.product_id.name}: {move.product_uom_qty} -> {clean_qty}") + move.write({'product_uom_qty': clean_qty}) + fixed_count += 1 - print("Finished checking MOs.") - -except Exception as e: - print("Error:", e) +env.cr.commit() +print(f"\\nPerfectly cleaned and committed {fixed_count} dirty components!")