Ir al contenido

Facturación por Hito

Sistema de auto-generación de facturas al completar hitos del proyecto.

  • Componente: MilestoneInvoiceConfig.tsx
  • Integración: Dentro de MilestoneForm.tsx
  • Trigger: Cambio de estado de hito a “completed”
interface MilestoneInvoiceConfig {
auto_invoice: boolean; // Activar/desactivar
invoice_amount: number; // Monto a facturar
invoice_description?: string; // Descripción en factura
invoice_id?: string; // ID de factura generada
invoiced_at?: string; // Timestamp de facturación
}
  1. Monto a Facturar (€)

    • Input numérico con 2 decimales
    • Mínimo: 0.01
    • Icono de Euro en el input
    • Validación: No puede ser 0 si auto-invoice está activo
  2. Descripción para la Factura

    • Textarea para detallar el servicio
    • Hasta 500 caracteres
    • Se incluye como línea de factura
    • Texto sugerido: “Servicios correspondientes al hito: [nombre_hito]”
  3. Cálculo Automático de IVA

    • IVA del 21% por defecto
    • Muestra subtotal, IVA y total
    • Preview en tiempo real

Fase 1: Configuración (Al crear/editar hito)

Sección titulada «Fase 1: Configuración (Al crear/editar hito)»
1. Usuario activa toggle "auto_invoice"
2. Ingresa monto y descripción
3. Se guarda configuración en el hito
4. Estado: "Configurado pero no facturado"
1. Usuario cambia estado del hito a "completed"
2. Sistema detecta auto_invoice = true
3. Genera factura automáticamente:
- Cliente: Del proyecto
- Línea: invoice_description
- Monto: invoice_amount
- IVA: 21%
- Estado: Borrador
4. Asocia invoice_id al hito
5. Registra invoiced_at con timestamp
1. Usuario recibe notificación
2. Factura en estado "borrador"
3. Puede editar antes de enviar
4. Opción de enviar o eliminar
  • Sin configurar: auto_invoice: false
  • Configurado: auto_invoice: true, sin invoice_id
  • Facturado: auto_invoice: true, con invoice_id
  • Cancelado: Hito cancelado, no se genera factura

El componente muestra diferentes vistas según el estado:

[ ] Facturar automáticamente al completar
Se generará una factura cuando este hito se marque como completado
[✓] Facturar automáticamente al completar
Monto: €1,200.00
Descripción: Desarrollo de módulo de usuarios
IVA (21%): €252.00
Total: €1,452.00
ℹ️ La factura se generará automáticamente cuando este hito se marque como completado.
✅ Factura generada
Facturado el 15/02/2024
[Ver Factura] → /invoices/{invoice_id}

Seguridad:

  • Solo usuarios con permisos de facturación pueden configurar
  • Validación de montos y cliente válido
  • No se puede facturar si el proyecto no tiene cliente

Edición:

  • Una vez facturado, no se puede editar la config
  • El toggle y campos se deshabilitan
  • Botón para ver factura generada

Cancelación:

  • Si se cancela el hito después de facturar, la factura NO se elimina
  • Requiere eliminar factura manualmente si es necesario
Lógica de generación de factura
// Trigger al completar hito (conceptual)
const handleMilestoneComplete = async (milestoneId: string) => {
// Obtener hito
const { data: milestone } = await supabase
.from('project_milestones')
.select('*, project:projects(client_id)')
.eq('id', milestoneId)
.single();
// Si auto_invoice está activado
if (milestone.auto_invoice && !milestone.invoice_id) {
// Crear factura
const { data: invoice } = await supabase
.from('invoices')
.insert({
user_id: userId,
customer_id: milestone.project.client_id,
status: 'draft',
issue_date: new Date().toISOString(),
items: [{
description: milestone.invoice_description,
quantity: 1,
unit_price: milestone.invoice_amount,
tax_rate: 21,
total: milestone.invoice_amount * 1.21
}],
subtotal: milestone.invoice_amount,
tax_total: milestone.invoice_amount * 0.21,
total: milestone.invoice_amount * 1.21
})
.select()
.single();
// Actualizar hito con invoice_id
await supabase
.from('project_milestones')
.update({
invoice_id: invoice.id,
invoiced_at: new Date().toISOString()
})
.eq('id', milestoneId);
// Notificación
toast.success('Factura generada automáticamente');
}
};