Arreglo en el cálculo de líneas de detalle

This commit is contained in:
David Arranz 2025-11-09 11:58:31 +01:00
parent 0fcba918a6
commit 5a4b457384

View File

@ -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 type { Currency } from "dinero.js";
import * as React from "react"; import * as React from "react";
import { useTranslation } from "../i18n"; import { useTranslation } from "../i18n";
@ -10,26 +10,27 @@ export type { Currency };
// Quita símbolos de moneda/letras, conserva dígitos, signo y , . // Quita símbolos de moneda/letras, conserva dígitos, signo y , .
const stripCurrencySymbols = (s: string) => const stripCurrencySymbols = (s: string) =>
s s
.replace(/[^\d.,\-]/g, "") .replace(/[^\d.,-]/g, "")
.replace(/\s+/g, " ") .replace(/\s+/g, " ")
.trim(); .trim();
// Heurística robusta: determina decimal por última ocurrencia de , o . // 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; if (!raw) return null;
const s = stripCurrencySymbols(raw); const s = stripCurrencySymbols(raw);
if (!s) return null; if (!s) return null;
const lastComma = s.lastIndexOf(",");
const lastDot = s.lastIndexOf("."); // Obtener formato local
let normalized = s; const example = Intl.NumberFormat(locale).format(1000.1);
if (lastComma > -1 && lastDot > -1) { const group = example.charAt(1); // normalmente "." o ","
if (lastComma > lastDot) normalized = s.replace(/\./g, "").replace(",", "."); const decimal = example.charAt(example.length - 2); // normalmente "," o "."
else normalized = s.replace(/,/g, "");
} else if (lastComma > -1) { // Normalizar: eliminar separador de miles y reemplazar decimal por "."
normalized = s.replace(/\s/g, "").replace(",", "."); const normalized = s
} else { .replace(new RegExp(`\\${group}`, "g"), "")
normalized = s.replace(/\s/g, ""); .replace(new RegExp(`\\${decimal}`), ".");
}
const n = Number(normalized); const n = Number(normalized);
return Number.isFinite(n) ? n : null; return Number.isFinite(n) ? n : null;
}; };
@ -93,7 +94,7 @@ export function useMoney(overrides?: {
// Formateos // Formateos
const formatCurrency = React.useCallback( const formatCurrency = React.useCallback(
(dto: MoneyDTO, loc?: string) => formatDTO(dto, loc ?? locale), (dto: MoneyDTO, loc?: string) => MoneyDTOHelper.formatDTO(dto, loc ?? locale),
[locale] [locale]
); );
@ -110,7 +111,10 @@ export function useMoney(overrides?: {
[locale, toNumber, defaultScale] [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 // Adaptadores API
const fromApi = React.useCallback( const fromApi = React.useCallback(