Ejemplos del Sistema de Monedas

📚 Casos de Uso Reales

1. Tabla de Órdenes

// apps/app/app/[lang]/dashboard/(project)/project/[projectSlug]/orders/view.tsx
<CurrencyDisplay
value={row.original.totalPrice}
sourceCurrency={row.original.currency as Currency}
targetCurrency={projectCurrency as Currency}
size="sm"
/>

Escenarios:

  • Orden USD ($2.57) en app COP → $10,794 COP
  • Orden COP (10,800) en app USD → $2.57 USD
  • Orden COP (10,800) en app COP → $10,800 COP (sin conversión)

2. Detalle de Pago

// apps/app/app/[lang]/dashboard/(project)/project/[projectSlug]/orders/[orderId]/sections/payments.tsx
<CurrencyDisplay
value={subtotalPrice}
sourceCurrency={currency as Currency}
targetCurrency={projectCurrency as Currency}
size="sm"
/>

3. Productos y Variantes

// apps/app/app/[lang]/dashboard/(project)/project/[projectSlug]/products/view.tsx
<CurrencyDisplay
value={variant.price}
sourceCurrency={variant.currency as Currency}
targetCurrency={projectCurrency as Currency}
size="sm"
/>

4. Planes de Billing

// apps/app/app/[lang]/dashboard/(config)/org/[orgId]/(billing)/plans/view.tsx
<CurrencyDisplay
value={planData.price / 100} // Convertir centavos a dólares
sourceCurrency={Currency.Usd} // Los planes siempre están en USD
targetCurrency={currency as Currency}
size="xl"
showDecimals={currency === "USD"} // Decimales solo para USD
/>

🎯 Configuraciones Especiales

Mostrar Sin Símbolo de Moneda

<CurrencyDisplay
value={price}
sourceCurrency={sourceCurrency}
targetCurrency={targetCurrency}
showCurrencySymbol={false}
/>
// Resultado: "2.57" en lugar de "$2.57"

Forzar Decimales

<CurrencyDisplay
value={price}
sourceCurrency={sourceCurrency}
targetCurrency={targetCurrency}
showDecimals={true}
/>
// Resultado: COP muestra "10,800.00" en lugar de "10,800"

Tasa de Cambio Personalizada

<CurrencyDisplay
value={price}
sourceCurrency={Currency.Usd}
targetCurrency={Currency.Cop}
exchangeRate={4500} // 1 USD = 4,500 COP (tasa especial)
/>
// Resultado: Usa la tasa personalizada en lugar de la por defecto (4,200)

Tamaños de Texto

// Extra pequeño
<CurrencyDisplay size="xs" value={price} sourceCurrency={src} targetCurrency={tgt} />

// Pequeño
<CurrencyDisplay size="sm" value={price} sourceCurrency={src} targetCurrency={tgt} />

// Mediano (por defecto)
<CurrencyDisplay size="md" value={price} sourceCurrency={src} targetCurrency={tgt} />

// Grande
<CurrencyDisplay size="lg" value={price} sourceCurrency={src} targetCurrency={tgt} />

// Extra grande
<CurrencyDisplay size="xl" value={price} sourceCurrency={src} targetCurrency={tgt} />

🔧 Configuración de Páginas

Obtener Moneda del Proyecto (Server Component)

// apps/app/app/[lang]/dashboard/(project)/project/[projectSlug]/orders/page.tsx
export default async function OrdersPage(props: OrdersPageProps) {
const [params] = await Promise.all([props.params]);

// Obtener currency del proyecto
const { data: projectData } = await ApolloServerSupabase.query({
query: graphql(/* GraphQL */ `
query GetProjectCurrency {
getProject {
currency
}
}
`),
context: {
headers: {
"x-project-slug": params.projectSlug, // IMPORTANTE
},
},
});

return (
<OrdersView
projectSlug={params.projectSlug}
projectCurrency={projectData?.getProject?.currency || "USD"}
/>
);
}

Pasar a Componentes Hijos

// En el componente padre
interface OrdersViewProps {
projectSlug: string;
projectCurrency: string;
}

export function OrdersView({ projectSlug, projectCurrency }: OrdersViewProps) {
return (
<div>
{/* Pasar projectCurrency a componentes que muestran precios */}
<OrderTable projectCurrency={projectCurrency} />
<OrderSummary projectCurrency={projectCurrency} />
</div>
);
}

🚨 Errores y Soluciones

Error: "Cannot find name 'Currency'"

// Solución: Importar el enum
import { Currency } from "@packages/apollo/src/__generated__/graphql";

Error: "Property 'currency' does not exist"

// Solución: Agregar campo currency a la query GraphQL
query GetOrders {
getTenantOrders {
id
totalPrice
currency # ← Agregar este campo
}
}

Error: "Type 'string' is not assignable to type 'Currency'"

// Solución: Cast explícito
<CurrencyDisplay
sourceCurrency={order.currency as Currency}
targetCurrency={projectCurrency as Currency}
/>

Los precios no se convierten

// Verificar que se esté pasando el contexto del proyecto
const { data } = await ApolloServerSupabase.query({
query: graphql(`query GetProject { getProject { currency } }`),
context: {
headers: {
"x-project-slug": params.projectSlug, // ← No olvidar esto
},
},
});

🧪 Testing Manual

Probar Conversiones

  1. Crear orden en USD con precio $2.57
  2. Cambiar proyecto a COP en configuración
  3. Verificar que se muestre como ~$10,794 COP
  4. Cambiar proyecto a USD
  5. Verificar que se muestre como $2.57 USD

Probar Sin Conversión

  1. Crear orden en COP con precio 10,800 COP
  2. Mantener proyecto en COP
  3. Verificar que se muestre como $10,800 COP (sin conversión)

Probar Planes de Billing

  1. Ir a configuración de organización
  2. Cambiar moneda entre USD y COP
  3. Verificar que los precios de planes se conviertan correctamente
  4. Verificar que USD muestre decimales y COP no

📊 Datos de Prueba

Órdenes de Prueba

{
"orders": [
{
"id": "order-1",
"totalPrice": 257, // $2.57 USD (en centavos)
"currency": "USD"
},
{
"id": "order-2",
"totalPrice": 10800, // 10,800 COP
"currency": "COP"
}
]
}

Resultados Esperados

Orden Moneda Original Proyecto USD Proyecto COP
order-1 USD ($2.57) $2.57 USD $10,794 COP
order-2 COP (10,800) $2.57 USD $10,800 COP

Planes de Billing

{
"plans": [
{
"name": "Basic",
"price": 2999, // $29.99 USD (en centavos)
"currency": "USD"
}
]
}

Resultados Esperados

Plan Proyecto USD Proyecto COP
Basic $29.99 USD $125,980 COP

🔍 Debugging

Agregar Logs Temporales

// En CurrencyDisplay component
console.log('Currency conversion:', {
value,
sourceCurrency,
targetCurrency,
finalValue,
formattedPrice
});

Verificar Props

// En componentes que usan CurrencyDisplay
console.log('CurrencyDisplay props:', {
value: price,
sourceCurrency: order.currency,
targetCurrency: projectCurrency
});

Verificar Query GraphQL

// En páginas
console.log('Project data:', projectData);
console.log('Currency:', projectData?.getProject?.currency);


Última actualización Diciembre 2024
Para más información Ver CURRENCY_SYSTEM.md