From 4af511d01643b9771ea54e1785917f5645e88f94 Mon Sep 17 00:00:00 2001 From: mabejoyb Date: Mon, 18 May 2026 12:44:32 -0300 Subject: [PATCH] Refactor boot process and error handling; simplify library path setup and enhance number formatting functions. Archivo: parrafos_dinamicos_forma_pago.py --- parrafos_dinamicos_forma_pago.py | 114 +++++++++++++++---------------- 1 file changed, 54 insertions(+), 60 deletions(-) diff --git a/parrafos_dinamicos_forma_pago.py b/parrafos_dinamicos_forma_pago.py index e241201..1e51fc2 100644 --- a/parrafos_dinamicos_forma_pago.py +++ b/parrafos_dinamicos_forma_pago.py @@ -9,41 +9,20 @@ import unicodedata import datetime as dt from decimal import Decimal, InvalidOperation -def _rb_set_early(name, value): - try: - SetVar(name, value) - except Exception: - pass - - # -------------------- # Boot libs (Rocketbot portable) # -------------------- -_rb_set_early("gdoc_textos_status", "BOOTING") +base_dir = os.path.dirname(sys.executable) +libs_dir = os.path.join(base_dir, "py_libs", "py310") +sys.path.insert(0, libs_dir) -try: - base_dir = os.path.dirname(sys.executable) - libs_candidates = [ - os.path.join(base_dir, "py_libs", "py310"), - os.path.join(base_dir, "librerias", "py_libs", "py310"), - os.path.join(os.getcwd(), "librerias", "py_libs", "py310"), - ] - for libs_dir in libs_candidates: - if os.path.isdir(libs_dir) and libs_dir not in sys.path: - sys.path.insert(0, libs_dir) +for k in list(sys.modules.keys()): + if k == "pyparsing" or k.startswith("pyparsing."): + del sys.modules[k] - for k in list(sys.modules.keys()): - if k == "pyparsing" or k.startswith("pyparsing."): - del sys.modules[k] - - from googleapiclient.discovery import build - from googleapiclient.errors import HttpError - from google.oauth2 import service_account -except Exception as e: - _rb_set_early("gdoc_textos_status", "ERROR") - _rb_set_early("gdoc_textos_error", "BOOT_IMPORT: " + repr(e)) - print("BOOT_IMPORT error:", repr(e)) - raise +from googleapiclient.discovery import build +from googleapiclient.errors import HttpError +from google.oauth2 import service_account # ----------------------------------------------------------- @@ -113,13 +92,22 @@ def _normalizar_numero(valor) -> str: if "," in s: parts = s.split(',') + if len(parts) == 2 and len(parts[1]) == 3 and parts[0].replace('-', '').isdigit(): + return "".join(parts) + if len(parts) > 2 and all(len(p) == 3 for p in parts[1:]): + return "".join(parts) if len(parts) > 2: return "".join(parts[:-1]) + "." + parts[-1] return s.replace(',', '.') - if s.count('.') > 1: + if "." in s: parts = s.split('.') - return "".join(parts[:-1]) + "." + parts[-1] + if len(parts) == 2 and len(parts[1]) == 3 and parts[0].replace('-', '').isdigit(): + return "".join(parts) + if len(parts) > 2 and all(len(p) == 3 for p in parts[1:]): + return "".join(parts) + if len(parts) > 2: + return "".join(parts[:-1]) + "." + parts[-1] return s @@ -161,7 +149,7 @@ def numero_decimal_a_palabras_es(valor, max_decimales=2) -> str: def numero_a_letras_es(valor, max_decimales=2) -> str: return numero_decimal_a_palabras_es(valor, max_decimales=max_decimales) -def cantidad_a_letras_con_moneda(valor, max_decimales=2, moneda_prefix="DOLARES AMERICANOS") -> str: +def cantidad_a_letras_con_moneda(valor, max_decimales=0, moneda_prefix="DOLARES AMERICANOS") -> str: s = numero_decimal_a_palabras_es(valor, max_decimales=max_decimales) if not s or s.strip() == "": return "" @@ -258,26 +246,34 @@ def _to_int(v) -> int: return 0 def _format_money_es(v) -> str: - d = _to_decimal_money(v) - s = f"{d:,.2f}" - return s.replace(",", "X").replace(".", ",").replace("X", ".") + from decimal import ROUND_HALF_UP + d = _to_decimal_money(v).quantize(Decimal("1"), rounding=ROUND_HALF_UP) + s = f"{d:,.0f}" + return s.replace(",", ".") def _money_amount_display(v) -> str: + from decimal import ROUND_HALF_UP s = _normalizar_numero(v) if s == "": - return "0,00" + return "0" try: - d = Decimal(s) + d = Decimal(s).quantize(Decimal("1"), rounding=ROUND_HALF_UP) except Exception: return _format_money_es(v) - s2 = f"{d:,.2f}" - return s2.replace(",", "X").replace(".", ",").replace("X", ".") + s2 = f"{d:,.0f}" + return s2.replace(",", ".") def _raw_or_money_text(v) -> str: s = str(v or "").strip() - if s != "" and s != "ERROR_NOT_VAR" and s.lower() != "none": - return s - return _format_money_es(v) + if s == "" or s == "ERROR_NOT_VAR" or s.lower() == "none": + return "0" + return _money_amount_display(v) + +def _sanitize_usd_amounts_in_text(text: str) -> str: + s = str(text or "") + def _repl(m): + return f"USD. {_money_amount_display(m.group(1))}" + return re.sub(r"USD\.\s*([0-9][0-9\.,]*)", _repl, s) def _first_non_empty(*values): for v in values: @@ -383,7 +379,7 @@ def _money_text_and_letters(raw_value, raw_letters=""): txt = _raw_or_money_text(raw_value) letters = str(raw_letters or "").strip() if letters == "": - letters = cantidad_a_letras_con_moneda(raw_value, max_decimales=2) + letters = cantidad_a_letras_con_moneda(raw_value, max_decimales=0) return txt, letters def _build_cuotas_pre_paragraphs(cuotas_pre, base_label="a", sep_line="--------------------------------------------------------", nl="\n"): @@ -406,7 +402,7 @@ def _build_cuotas_pre_paragraphs(cuotas_pre, base_label="a", sep_line="--------- amount_txt = _raw_or_money_text(amount_raw) amount_letras = _first_non_empty( _safe_dict_get(cuota, "amount_letras", ""), - cantidad_a_letras_con_moneda(amount_raw, max_decimales=2) + cantidad_a_letras_con_moneda(amount_raw, max_decimales=0) ) frequency = str(_safe_dict_get(cuota, "frequency", "") or "").lower() fecha_txt = _date_text_long(_safe_dict_get(cuota, "date", "")) @@ -436,7 +432,7 @@ def _build_cuotas_post_paragraphs(cuotas_post, base_label="a", sep_line="------- amount_txt = _raw_or_money_text(amount_raw) amount_letras = _first_non_empty( _safe_dict_get(cuota, "amount_letras", ""), - cantidad_a_letras_con_moneda(amount_raw, max_decimales=2) + cantidad_a_letras_con_moneda(amount_raw, max_decimales=0) ) frequency = str(_safe_dict_get(cuota, "frequency", "") or "").lower() fecha_txt = _date_text_long(_safe_dict_get(cuota, "date", "")) @@ -460,7 +456,7 @@ def _build_refuerzos_pre_paragraphs(refuerzos_pre, sep_line="------------------- refuerzo_monto_txt = _money_amount_display(refuerzo_monto_raw) refuerzo_letras = _first_non_empty( _safe_dict_get(refuerzo, "amount_letras", ""), - cantidad_a_letras_con_moneda(refuerzo_monto_raw, max_decimales=2) + cantidad_a_letras_con_moneda(refuerzo_monto_raw, max_decimales=0) ) fecha_txt = _date_text_long(_safe_dict_get(refuerzo, "date", "")) parts.append( @@ -479,7 +475,7 @@ def _build_refuerzos_post_paragraphs(refuerzos_post, sep_line="----------------- refuerzo_monto_txt = _money_amount_display(refuerzo_monto_raw) refuerzo_letras = _first_non_empty( _safe_dict_get(refuerzo, "amount_letras", ""), - cantidad_a_letras_con_moneda(refuerzo_monto_raw, max_decimales=2) + cantidad_a_letras_con_moneda(refuerzo_monto_raw, max_decimales=0) ) fecha_txt = _date_text_long(_safe_dict_get(refuerzo, "date", "")) parts.append( @@ -557,6 +553,7 @@ def get_services(credentials_json_path, impersonated_user): drive = build("drive", "v3", credentials=creds, cache_discovery=False) return docs, drive, "service_account_impersonated" + # ----------------------------------------------------------- # DRIVE / DOC HELPERS # ----------------------------------------------------------- @@ -934,10 +931,6 @@ globals().update(locals()) # MAIN # ----------------------------------------------------------- try: - _sv("gdoc_textos_status", "STARTED") - _sv("gdoc_textos_error", "") - print("parrafos_dinamicos_forma_pago.py STARTED") - NL = "\n" # usar SOLO current_url @@ -963,7 +956,7 @@ try: cred_path = os.path.join(base_dir, cred_path) if not os.path.exists(cred_path): - raise RuntimeError("No existe JSON de cuenta de servicio: " + cred_path) + raise RuntimeError("No existe credentials.json: " + cred_path) impersonated_user = _gvs("gdoc_impersonated_user", "") @@ -1099,7 +1092,7 @@ try: ) # valor financiado con interés incluído - valor_total_compra_financiado = _to_decimal_money(_gvs("valor_total_compra_financiado", "0")) + valor_total_compra_financiado = _raw_or_money_text(_gvs("valor_total_compra_financiado", "")) valor_total_letras_financiado = _first_non_empty( _gvs("valor_total_letras_financiado", ""), cantidad_a_letras_con_moneda(_gvs("valor_total_compra_financiado", "0")) @@ -1210,7 +1203,7 @@ try: saldo_a_pagar_raw = _gvs("saldo_a_pagar", "") saldo_a_pagar = _raw_or_money_text(saldo_a_pagar_raw) - saldo_letras = cantidad_a_letras_con_moneda(saldo_a_pagar_raw, max_decimales=2) + saldo_letras = cantidad_a_letras_con_moneda(saldo_a_pagar_raw, max_decimales=0) num_pre_cuotas_fallback = _to_int(_gvs("num_pre_cuotas", "0")) @@ -1250,7 +1243,7 @@ try: pre_amount = _raw_or_money_text(pre_amount_raw) pre_amount_letras = _first_non_empty( _safe_dict_get(primer_pre, "amount_letras", ""), - cantidad_a_letras_con_moneda(pre_amount_raw, max_decimales=2) + cantidad_a_letras_con_moneda(pre_amount_raw, max_decimales=0) ) frecuencia_pre = str(_safe_dict_get(primer_pre, "frequency", "") or "").lower() @@ -1258,7 +1251,7 @@ try: pos_cuota_monto = _raw_or_money_text(pos_amount_raw) pos_cuota_letras = _first_non_empty( _safe_dict_get(primer_pos, "amount_letras", ""), - cantidad_a_letras_con_moneda(pos_amount_raw, max_decimales=2) + cantidad_a_letras_con_moneda(pos_amount_raw, max_decimales=0) ) frecuencia_pos = str(_safe_dict_get(primer_pos, "frequency", "") or "").lower() @@ -1789,6 +1782,10 @@ try: # -------------------- # REEMPLAZAR MARCADORES # -------------------- + _sv("debug_script_version", "v4_sanitize_usd_final") + texto_precio = _sanitize_usd_amounts_in_text(texto_precio) + texto_fp = _sanitize_usd_amounts_in_text(texto_fp) + precio_insert_info = replace_marker_by_index( docs_service=docs_service, doc_id=doc_id, @@ -1833,12 +1830,9 @@ try: except HttpError as e: _sv("gdoc_textos_status", "ERROR") _sv("gdoc_textos_error", "HttpError: " + str(e)) - _sv("gdoc_textos_traceback", "HttpError: " + str(e)) raise except Exception as e: - import traceback _sv("gdoc_textos_status", "ERROR") _sv("gdoc_textos_error", str(e)) - _sv("gdoc_textos_traceback", traceback.format_exc()) raise