#!/usr/bin/env python3 import os import sys import xmlrpc.client from pathlib import Path from datetime import datetime MACHINE_MAP = { "CORT-00": "Cortadora 0", "CORT-01": "Cortadora 01", "CORT-02": "Cortadora 02", } WORKORDER_STATES = ["waiting", "ready", "progress", "done"] def read_env(path=".env"): env = {} p = Path(path) for raw in p.read_text().splitlines(): line = raw.strip() if not line or line.startswith("#") or "=" not in line: continue k, v = line.split("=", 1) env[k.strip()] = v.strip().strip('"').strip("'") return env def existing_fields(models, db, uid, password, model, wanted): fields = models.execute_kw( db, uid, password, model, "fields_get", [], {"attributes": ["string", "type"]}, ) return [f for f in wanted if f in fields] def search_read(models, db, uid, password, model, domain, fields, limit=20, order="id asc"): fields = existing_fields(models, db, uid, password, model, fields) return models.execute_kw( db, uid, password, model, "search_read", [domain], {"fields": fields, "limit": limit, "order": order}, ) def main(): env = read_env() url = env["ODOO_URL"].rstrip("/") db = os.getenv("ODOO_DB_OVERRIDE") or env["ODOO_DB"] user = env["ODOO_USER"] password = env["ODOO_PASSWORD"] print("ODOO_URL =", url) print("ODOO_DB =", db) print("ODOO_USER=", user) print() common = xmlrpc.client.ServerProxy(f"{url}/xmlrpc/2/common") uid = common.authenticate(db, user, password, {}) if not uid: raise SystemExit("ERROR: autenticación Odoo fallida") print("uid =", uid) print() models = xmlrpc.client.ServerProxy(f"{url}/xmlrpc/2/object") wc_fields = existing_fields( models, db, uid, password, "mrp.workcenter", ["id", "name", "code", "active", "display_name"], ) wo_fields = existing_fields( models, db, uid, password, "mrp.workorder", [ "id", "name", "state", "workcenter_id", "production_id", "product_id", "date_start", "date_finished", "duration_expected", "duration", "qty_production", ], ) print("Campos workcenter disponibles:", wc_fields) print("Campos workorder disponibles :", wo_fields) print() for machine_id, wc_name in MACHINE_MAP.items(): print("=" * 80) print(f"{machine_id} -> {wc_name}") workcenters = search_read( models, db, uid, password, "mrp.workcenter", [("name", "=", wc_name)], ["id", "name", "code", "active", "display_name"], limit=5, order="id asc", ) if not workcenters: print("ERROR: no se encuentra centro de trabajo exacto") continue if len(workcenters) > 1: print("AVISO: hay más de un centro exacto") wc = workcenters[0] wc_id = wc["id"] print("Workcenter:", wc) workorders = search_read( models, db, uid, password, "mrp.workorder", [ ("workcenter_id", "=", wc_id), ("state", "in", WORKORDER_STATES), ], [ "id", "name", "state", "workcenter_id", "production_id", "product_id", "date_start", "date_finished", "duration_expected", "duration", "qty_production", ], limit=20, order="id desc", ) if not workorders: print("Sin workorders candidatas") continue print(f"Workorders candidatas: {len(workorders)}") for wo in workorders: print( " -", { "id": wo.get("id"), "name": wo.get("name"), "state": wo.get("state"), "production_id": wo.get("production_id"), "product_id": wo.get("product_id"), "date_start": wo.get("date_start"), "date_finished": wo.get("date_finished"), "qty_production": wo.get("qty_production"), }, ) if __name__ == "__main__": main()