From 5a4b45738435d986f4a326692a62a6ae0641c868 Mon Sep 17 00:00:00 2001 From: david Date: Sun, 9 Nov 2025 11:58:31 +0100 Subject: [PATCH] =?UTF-8?q?Arreglo=20en=20el=20c=C3=A1lculo=20de=20l=C3=AD?= =?UTF-8?q?neas=20de=20detalle?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/core/src/web/hooks/use-money.ts | 36 ++++++++++++++----------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/modules/core/src/web/hooks/use-money.ts b/modules/core/src/web/hooks/use-money.ts index c122b034..74cc0f28 100644 --- a/modules/core/src/web/hooks/use-money.ts +++ b/modules/core/src/web/hooks/use-money.ts @@ -1,4 +1,4 @@ -import type { MoneyDTO } from "@erp/core/common"; +import { MoneyDTO, MoneyDTOHelper } from "@erp/core/common"; import type { Currency } from "dinero.js"; import * as React from "react"; import { useTranslation } from "../i18n"; @@ -10,26 +10,27 @@ export type { Currency }; // Quita símbolos de moneda/letras, conserva dígitos, signo y , . const stripCurrencySymbols = (s: string) => s - .replace(/[^\d.,\-]/g, "") + .replace(/[^\d.,-]/g, "") .replace(/\s+/g, " ") .trim(); // Heurística robusta: determina decimal por última ocurrencia de , o . -const parseLocaleNumber = (raw: string): number | null => { +const parseLocaleNumber = (raw: string, locale = "es-ES"): number | null => { if (!raw) return null; + const s = stripCurrencySymbols(raw); if (!s) return null; - const lastComma = s.lastIndexOf(","); - const lastDot = s.lastIndexOf("."); - let normalized = s; - if (lastComma > -1 && lastDot > -1) { - if (lastComma > lastDot) normalized = s.replace(/\./g, "").replace(",", "."); - else normalized = s.replace(/,/g, ""); - } else if (lastComma > -1) { - normalized = s.replace(/\s/g, "").replace(",", "."); - } else { - normalized = s.replace(/\s/g, ""); - } + + // Obtener formato local + const example = Intl.NumberFormat(locale).format(1000.1); + const group = example.charAt(1); // normalmente "." o "," + const decimal = example.charAt(example.length - 2); // normalmente "," o "." + + // Normalizar: eliminar separador de miles y reemplazar decimal por "." + const normalized = s + .replace(new RegExp(`\\${group}`, "g"), "") + .replace(new RegExp(`\\${decimal}`), "."); + const n = Number(normalized); return Number.isFinite(n) ? n : null; }; @@ -93,7 +94,7 @@ export function useMoney(overrides?: { // Formateos const formatCurrency = React.useCallback( - (dto: MoneyDTO, loc?: string) => formatDTO(dto, loc ?? locale), + (dto: MoneyDTO, loc?: string) => MoneyDTOHelper.formatDTO(dto, loc ?? locale), [locale] ); @@ -110,7 +111,10 @@ export function useMoney(overrides?: { [locale, toNumber, defaultScale] ); - const parse = React.useCallback((text: string): number | null => parseLocaleNumber(text), []); + const parse = React.useCallback( + (text: string): number | null => parseLocaleNumber(text, locale), + [locale] + ); // Adaptadores API const fromApi = React.useCallback(