Uecko_ERP_FactuGES_sync/app/utils/importes_helper.py
2025-11-21 19:42:03 +01:00

56 lines
1.7 KiB
Python

from decimal import Decimal, ROUND_HALF_UP
from typing import Any, Optional
def cents4(value: Optional[Decimal | float | int]) -> int:
"""Convierte a centésimas (valor * 10000). Soporta None."""
v = Decimal(str(value or 0))
return int((v * 10000).to_integral_value(rounding=ROUND_HALF_UP))
def cents(value: Optional[Decimal | float | int]) -> int:
"""Convierte a centésimas (valor * 100). Soporta None."""
v = Decimal(str(value or 0))
return int((v * 100).to_integral_value(rounding=ROUND_HALF_UP))
def money_round(value: Decimal, ndigits: int = 2) -> Decimal:
"""Redondeo bancario a n decimales (por defecto 2)."""
q = Decimal((0, (1,), -ndigits)) # 10^-ndigits
return value.quantize(q, rounding=ROUND_HALF_UP)
def unscale_to_decimal(value: Any, scale: Any) -> Decimal:
"""
Convierte un valor escalado (p. ej. 24200 con scale=2) a su valor en unidades (242).
No redondea; sólo mueve el punto decimal.
"""
if value is None:
return Decimal("0")
d = Decimal(str(value))
s = int(scale or 0)
return d.scaleb(-s) # divide por 10**s
def unscale_to_str(
value: Any,
scale: Any,
*,
decimals: Optional[int] = None,
strip_trailing_zeros: bool = True
) -> str:
"""
Igual que unscale_to_decimal, pero devuelve str.
- decimals: fija nº de decimales (p. ej. 2). Si None, no fuerza decimales.
- strip_trailing_zeros: si True, quita ceros y el punto sobrantes.
"""
d = unscale_to_decimal(value, scale)
if decimals is not None:
q = Decimal("1").scaleb(-decimals) # p.ej. 2 -> Decimal('0.01')
d = d.quantize(q, rounding=ROUND_HALF_UP)
s = format(d, "f")
if strip_trailing_zeros and "." in s:
s = s.rstrip("0").rstrip(".")
return s