erp-core/docs/02-fase-core-business/MGN-010-financial/requerimientos/RF-FIN-002.md

5.9 KiB

RF-FIN-002: Monedas y Tipos de Cambio

Identificacion

Campo Valor
ID RF-FIN-002
Modulo MGN-010 Financial
Titulo Monedas y Tipos de Cambio
Prioridad P0 - Critica
Estado Draft
Fecha 2025-12-05

Descripcion

El sistema debe soportar operaciones multi-moneda, con gestion de tipos de cambio historicos, conversion automatica, y registro de diferencias cambiarias.


Requisitos Funcionales

RF-FIN-002.1: Estructura de Moneda

interface Currency {
  id: UUID;
  code: string;             // ISO 4217: "MXN", "USD"
  name: string;             // "Peso Mexicano"
  symbol: string;           // "$", "€"
  decimalPlaces: number;    // 2
  decimalSeparator: string; // "."
  thousandSeparator: string; // ","
  symbolPosition: 'before' | 'after';
  isActive: boolean;
}

// Monedas predefinidas
const CURRENCIES = [
  { code: 'MXN', name: 'Peso Mexicano', symbol: '$', decimalPlaces: 2 },
  { code: 'USD', name: 'Dolar Estadounidense', symbol: 'US$', decimalPlaces: 2 },
  { code: 'EUR', name: 'Euro', symbol: '€', decimalPlaces: 2 },
  { code: 'COP', name: 'Peso Colombiano', symbol: '$', decimalPlaces: 0 },
  // ...
];

RF-FIN-002.2: Configuracion de Moneda por Tenant

interface TenantCurrencyConfig {
  tenantId: UUID;
  baseCurrencyId: UUID;     // Moneda funcional
  activeCurrencies: UUID[]; // Monedas habilitadas
  exchangeRateSource: 'manual' | 'api';
  exchangeRateApi?: string; // URL de API
  autoUpdateRates: boolean;
  roundingMode: RoundingMode;
}

enum RoundingMode {
  HALF_UP = 'half_up',       // Redondeo normal
  HALF_DOWN = 'half_down',
  FLOOR = 'floor',           // Hacia abajo
  CEILING = 'ceiling'        // Hacia arriba
}

RF-FIN-002.3: Tipos de Cambio

interface ExchangeRate {
  id: UUID;
  tenantId: UUID;
  fromCurrencyId: UUID;
  toCurrencyId: UUID;
  rate: Decimal;            // 17.50 (1 USD = 17.50 MXN)
  inverseRate: Decimal;     // 0.0571 (1 MXN = 0.0571 USD)
  effectiveDate: Date;
  source: string;           // "manual", "banxico", "api"
  createdAt: TIMESTAMPTZ;
}

// Busqueda de tipo de cambio
// Siempre busca el mas reciente <= fecha solicitada
function getExchangeRate(
  fromCurrency: UUID,
  toCurrency: UUID,
  date: Date
): ExchangeRate;

RF-FIN-002.4: Conversion de Moneda

interface ConversionResult {
  originalAmount: Decimal;
  originalCurrency: string;
  convertedAmount: Decimal;
  targetCurrency: string;
  exchangeRate: Decimal;
  rateDate: Date;
  rateSource: string;
}

// Ejemplo
POST /api/v1/financial/currencies/convert
{
  "amount": 1000,
  "fromCurrency": "USD",
  "toCurrency": "MXN",
  "date": "2025-12-05"
}

Response:
{
  "originalAmount": 1000,
  "originalCurrency": "USD",
  "convertedAmount": 17500,
  "targetCurrency": "MXN",
  "exchangeRate": 17.50,
  "rateDate": "2025-12-05",
  "rateSource": "manual"
}

RF-FIN-002.5: Actualizacion Automatica de Tasas

Integracion con APIs de tipos de cambio:

Proveedor Region Monedas
Banxico Mexico MXN
BCE Europa EUR
Open Exchange Global 150+
Fixer.io Global 170+
interface ExchangeRateJob {
  tenantId: UUID;
  schedule: string;         // "0 8 * * 1-5" (dias habiles 8am)
  provider: string;
  currencies: string[];
  lastRunAt?: TIMESTAMPTZ;
  lastStatus: 'success' | 'failed';
}

RF-FIN-002.6: Diferencias Cambiarias

Al registrar movimientos en moneda extranjera:

interface ExchangeGainLoss {
  id: UUID;
  documentType: string;     // "invoice", "payment"
  documentId: UUID;
  originalAmount: Decimal;
  originalCurrency: UUID;
  originalRate: Decimal;
  settlementAmount: Decimal;
  settlementRate: Decimal;
  gainLoss: Decimal;        // Ganancia/perdida cambiaria
  accountId: UUID;          // Cuenta de diferencia cambiaria
  journalEntryId: UUID;     // Asiento generado
  createdAt: TIMESTAMPTZ;
}

Operaciones

Listar Monedas

GET /api/v1/financial/currencies

Response:
{
  "data": [
    {
      "id": "uuid",
      "code": "MXN",
      "name": "Peso Mexicano",
      "symbol": "$",
      "isBase": true,
      "isActive": true
    },
    {
      "id": "uuid2",
      "code": "USD",
      "name": "Dolar Estadounidense",
      "symbol": "US$",
      "isBase": false,
      "currentRate": 17.50
    }
  ]
}

Obtener Historial de Tipos de Cambio

GET /api/v1/financial/currencies/:code/rates?from=2025-11-01&to=2025-12-05

Response:
{
  "currency": "USD",
  "baseCurrency": "MXN",
  "rates": [
    { "date": "2025-12-05", "rate": 17.50, "source": "manual" },
    { "date": "2025-12-04", "rate": 17.45, "source": "banxico" },
    // ...
  ]
}

Registrar Tipo de Cambio

POST /api/v1/financial/currencies/:code/rates
{
  "rate": 17.55,
  "effectiveDate": "2025-12-06"
}

Configurar Actualizacion Automatica

PUT /api/v1/financial/currencies/auto-update
{
  "enabled": true,
  "provider": "banxico",
  "schedule": "0 8 * * 1-5",
  "currencies": ["USD", "EUR"]
}

Reglas de Negocio

ID Regla Severidad
BR-001 Moneda base no puede cambiarse si hay movimientos Error
BR-002 Tipo de cambio no puede ser negativo o cero Error
BR-003 No pueden existir dos tasas para la misma fecha Error
BR-004 Diferencias cambiarias se registran automaticamente Info
BR-005 API fallida usa ultima tasa conocida Warning

Criterios de Aceptacion

  • CRUD de monedas
  • Historial de tipos de cambio
  • Conversion automatica
  • Integracion con APIs externas
  • Calculo de diferencias cambiarias
  • Soporte para multiples decimales por moneda
  • Formato configurable por moneda

Historial

Version Fecha Autor Cambios
1.0 2025-12-05 Requirements-Analyst Creacion inicial