El sistema diferencia automaticamente clientes en QuickBooks por moneda de transaccion. Un mismo cliente puede tener multiples entidades en QB — una por cada moneda con la que opera.
CurrencyRef de un cliente en QuickBooks es inmutable despues de crearlo. Por eso se crean entidades separadas por moneda, cada una con su sufijo en el DisplayName.
| Moneda | Nombre | Simbolo | Rol |
|---|---|---|---|
| CRC | Colon Costarricense | ₡ | Moneda base (por defecto) |
| USD | Dolar Estadounidense | $ | Moneda extranjera |
Cada cliente lleva un sufijo de moneda en su DisplayName. Maximo 41 caracteres — el nombre se trunca para dejar espacio al sufijo.
Cliente original: Cori Motors De Centroamerica S.A. — Codigo: 00190
| Moneda | DisplayName en QB | Notes | CurrencyRef |
|---|---|---|---|
| CRC | Cori Motors De Centroamerica... CRC | 00190 | CRC |
| USD | Cori Motors De Centroamerica... USD | 00190 | USD |
{
DisplayName: "Empresa Prueba Costa Rica CRC", // max 41 chars, con sufijo
CompanyName: "Empresa Prueba Costa Rica", // nombre completo sin sufijo
Notes: "00TEST", // codigo interno para busqueda
PrimaryTaxIdentifier: "31012345678", // cedula / RUC
CurrencyRef: { value: "CRC" } // INMUTABLE despues de crear
}
El sistema busca al cliente en 3 pasos. Si ninguno encuentra coincidencia, crea uno nuevo.
1. Buscar por Notes (codigo interno) + CurrencyRef
cliente = clientes.find(c =>
c.Notes === codigo &&
c.CurrencyRef?.value === moneda
);
2. Buscar por DisplayName exacto con sufijo
const nombreConMoneda = `${nombre} ${moneda}`;
cliente = clientes.find(c =>
c.DisplayName === nombreConMoneda
);
3. No encontrado → crear nuevo cliente con:
- DisplayName con sufijo (truncado a 41 chars)
- CurrencyRef con la moneda
- Notes con codigo interno
Notes + CurrencyRef es el metodo preferido porque el codigo interno es unico y no cambia, mientras que el nombre puede variar.
Solo aplica a transacciones en moneda extranjera (USD). Debe ser siempre tipo number, nunca string.
| Moneda | ExchangeRate | Requiere config | Fuente |
|---|---|---|---|
| CRC | 1 (moneda base) | No | — |
| USD | ~500–550 | Si | Campo tipo_cambio o exchange_rate de la factura |
{
CustomerRef: { value: "42" },
CurrencyRef: { value: "CRC" },
DocNumber: "FE-001-2025",
Line: [...]
}
{
CustomerRef: { value: "43" },
CurrencyRef: { value: "USD" },
ExchangeRate: 512.50,
DocNumber: "FE-002-2025",
Line: [...]
}
tipo_cambio, se usa 500 como fallback para USD.
Modulo centralizado en src/utils/currencyUtils.js que elimina duplicacion de logica de moneda entre scripts.
| Funcion | Descripcion |
|---|---|
determinarConfiguracionMoneda(factura) | Detecta moneda y retorna config completa (moneda, exchangeRate, simbolo) |
buscarEntidadPorMoneda(entidades, nombre, config, normFn) | Busca cliente/proveedor considerando moneda especifica |
crearNombreConMoneda(nombre, config, normFn) | Genera DisplayName con sufijo, truncado a 41 chars |
agregarConfiguracionMoneda(estructura, config) | Agrega CurrencyRef y ExchangeRate a un objeto QB |
formatearMonto(monto, config) | Formatea con simbolo: $1,500.00 o ₡750,000.00 |
// Criterios para detectar USD: 1. Campo moneda o currency = 'USD' 2. Nombre del cliente/proveedor contiene 'USD' 3. Campo nombre o cliente contiene 'USD' // Cualquier otro caso → CRC (moneda base por defecto)
const CurrencyUtils = require('../../src/utils/currencyUtils');
// 1. Detectar moneda
const config = CurrencyUtils.determinarConfiguracionMoneda(factura);
// 2. Buscar/crear entidad con diferenciacion
const cliente = await this.buscarOCrearClienteConMoneda(
factura.cliente, config
);
// 3. Crear estructura QB
const invoiceData = { CustomerRef: { value: cliente.Id } };
// 4. Aplicar configuracion de moneda
CurrencyUtils.agregarConfiguracionMoneda(invoiceData, config);
// → agrega CurrencyRef y ExchangeRate si USD
| Problema | Causa | Solucion |
|---|---|---|
| CurrencyRef inmutable | Se intento cambiar moneda de cliente existente | Crear nuevo cliente con sufijo correcto |
| ExchangeRate como string | Dato de factura llega como "512.50" | Number(exchangeRate) — siempre convertir |
| Entidades duplicadas | Funcion normalizarFn inconsistente | Revisar logica de normalizacion y busqueda |
| Tipo de cambio incorrecto | Campo tipo_cambio ausente | Verificar datos de factura, fallback a 500 |
| DisplayName excede 41 chars | Nombre muy largo + sufijo | Se trunca automaticamente, verificar resultado |
node scripts/utilities/check-quickbooks-currencies.js node scripts/utilities/debug-currency.js