Concepto

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.

Regla clave: La 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.
Factura entrante
→
Detectar moneda
→
Buscar / crear cliente
→
Cliente CRC
Cliente USD
Monedas soportadas
MonedaNombreSimboloRol
CRCColon Costarricense₡Moneda base (por defecto)
USDDolar Estadounidense$Moneda extranjera
Diferenciacion de clientes

Cada cliente lleva un sufijo de moneda en su DisplayName. Maximo 41 caracteres — el nombre se trunca para dejar espacio al sufijo.

Ejemplo practico

Cliente original: Cori Motors De Centroamerica S.A. — Codigo: 00190

MonedaDisplayName en QBNotesCurrencyRef
CRCCori Motors De Centroamerica... CRC00190CRC
USDCori Motors De Centroamerica... USD00190USD

Campos configurados

{
  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
}
Algoritmo de busqueda

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
Prioridad: La busqueda por Notes + CurrencyRef es el metodo preferido porque el codigo interno es unico y no cambia, mientras que el nombre puede variar.
Tipo de cambio (ExchangeRate)

Solo aplica a transacciones en moneda extranjera (USD). Debe ser siempre tipo number, nunca string.

MonedaExchangeRateRequiere configFuente
CRC1 (moneda base)No—
USD~500–550SiCampo tipo_cambio o exchange_rate de la factura

Aplicacion a estructuras QB

Factura CRC
{
  CustomerRef: { value: "42" },
  CurrencyRef: { value: "CRC" },
  DocNumber: "FE-001-2025",
  Line: [...]
}
Factura USD
{
  CustomerRef: { value: "43" },
  CurrencyRef: { value: "USD" },
  ExchangeRate: 512.50,
  DocNumber: "FE-002-2025",
  Line: [...]
}
Valor por defecto: Si la factura no trae tipo_cambio, se usa 500 como fallback para USD.
CurrencyUtils — API de referencia

Modulo centralizado en src/utils/currencyUtils.js que elimina duplicacion de logica de moneda entre scripts.

FuncionDescripcion
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

Deteccion de moneda

// 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)

Uso en scripts

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
Troubleshooting
ProblemaCausaSolucion
CurrencyRef inmutableSe intento cambiar moneda de cliente existenteCrear nuevo cliente con sufijo correcto
ExchangeRate como stringDato de factura llega como "512.50"Number(exchangeRate) — siempre convertir
Entidades duplicadasFuncion normalizarFn inconsistenteRevisar logica de normalizacion y busqueda
Tipo de cambio incorrectoCampo tipo_cambio ausenteVerificar datos de factura, fallback a 500
DisplayName excede 41 charsNombre muy largo + sufijoSe trunca automaticamente, verificar resultado

Verificar monedas en QuickBooks

node scripts/utilities/check-quickbooks-currencies.js
node scripts/utilities/debug-currency.js