Basándome en el prototipo construido, aquí están las tareas técnicas para la planning con el equipo de desarrollo:
1.1 Diseño de Base de Datos
facturas con campos: id, cliente_id, producto, cosecha, contrato, monto, fecha_emision, fecha_vencimiento, status, metodo_pago, fecha_gestion, observaciones, monto_pedidoclientes con campos: id, razon_social, cuit, direccion, etc.cuentas_bancarias con campos: id, cliente_id, banco, tipo_cuenta, cbu, alias, monedapedidos_pago con campos: id, cliente_id, monto_total, metodo_pago, cuenta_bancaria_id, descontar_gastos, para_cobrar_insumos, observaciones, fecha_creacion, statuspedidos_pago_detalle (relación muchos a muchos con facturas)ordenes_pago con campos según estructura actual (numero_documento, numero_operacion, fecha_contabilizacion, proveedor, montos por método, retenciones, etc.)1.2 APIs REST
GET /api/facturas - Listar facturas con filtros (status, cliente, búsqueda)GET /api/facturas/:id - Obtener detalle de facturaPATCH /api/facturas/:id - Actualizar factura (status, método pago, etc.)GET /api/clientes/:id/cuentas-bancarias - Listar cuentas bancarias por clientePOST /api/pedidos-pago - Crear pedido de pagoGET /api/pedidos-pago - Listar pedidos de pagoGET /api/ordenes-pago - Listar órdenes de pago emitidasGET /api/ordenes-pago/:id - Detalle de orden de pago2.1 Listado de Facturas
2.2 Tarjetas de Resumen (Dashboard)
2.3 Modal de Pedido de Pago
2.4 Modal de Detalle de Gestión
2.5 Exportación
3.1 Listado de Órdenes de Pago
3.2 Tarjetas de Resumen
3.3 Modal de Detalle de Orden de Pago
3.4 Exportación
4.1 Validaciones
4.2 Flujo de Estados
4.3 Observaciones Automáticas
5.1 Sistema Contable/ERP
6.1 UX/UI
6.2 Testing
6.3 Documentación
Este listado cubre las funcionalidades del prototipo. Te sugiero priorizar en el siguiente orden: Modelo de datos → APIs básicas → Listado de facturas → Modal de pedido de pago → Exportación → Módulo de órdenes de pago.
Aquí te detallo las tareas de backend con mayor profundidad técnica para los endpoints:
-- Tabla de Clientes
CREATE TABLE clientes (
id INT PRIMARY KEY IDENTITY,
codigo VARCHAR(20) UNIQUE NOT NULL,
razon_social VARCHAR(200) NOT NULL,
cuit VARCHAR(13),
direccion VARCHAR(300),
activo BIT DEFAULT 1,
created_at DATETIME DEFAULT GETDATE(),
updated_at DATETIME
);
-- Tabla de Cuentas Bancarias por Cliente
CREATE TABLE cuentas_bancarias (
id INT PRIMARY KEY IDENTITY,
cliente_id INT FOREIGN KEY REFERENCES clientes(id),
banco VARCHAR(100) NOT NULL,
tipo_cuenta VARCHAR(20) NOT NULL, -- 'Cuenta Corriente', 'Caja de Ahorro'
cbu VARCHAR(22) NOT NULL,
alias VARCHAR(50),
moneda VARCHAR(3) DEFAULT 'ARS', -- 'ARS', 'USD'
activo BIT DEFAULT 1,
created_at DATETIME DEFAULT GETDATE()
);
-- Tabla de Facturas
CREATE TABLE facturas (
id INT PRIMARY KEY IDENTITY,
numero_factura VARCHAR(20) UNIQUE NOT NULL,
cliente_id INT FOREIGN KEY REFERENCES clientes(id),
producto VARCHAR(100),
cosecha VARCHAR(10),
contrato VARCHAR(30),
monto DECIMAL(18,2) NOT NULL,
fecha_emision DATE NOT NULL,
fecha_vencimiento DATE NOT NULL,
status VARCHAR(20) DEFAULT 'pendiente', -- 'pendiente', 'tomado', 'pagado'
created_at DATETIME DEFAULT GETDATE(),
updated_at DATETIME
);
-- Tabla de Pedidos de Pago (cabecera)
CREATE TABLE pedidos_pago (
id INT PRIMARY KEY IDENTITY,
numero_pedido VARCHAR(20) UNIQUE NOT NULL,
cliente_id INT FOREIGN KEY REFERENCES clientes(id),
metodo_pago VARCHAR(20) NOT NULL, -- 'transferencia', 'cheque', 'echeq', 'cuenta'
cuenta_bancaria_id INT FOREIGN KEY REFERENCES cuentas_bancarias(id) NULL,
monto_total DECIMAL(18,2) NOT NULL,
descontar_gastos BIT DEFAULT 1,
para_cobrar_insumos BIT DEFAULT 0,
observaciones TEXT,
status VARCHAR(20) DEFAULT 'pendiente', -- 'pendiente', 'procesado', 'anulado'
fecha_pedido DATETIME DEFAULT GETDATE(),
usuario_creacion VARCHAR(50),
created_at DATETIME DEFAULT GETDATE()
);
-- Tabla de Detalle Pedido de Pago (facturas incluidas)
CREATE TABLE pedidos_pago_detalle (
id INT PRIMARY KEY IDENTITY,
pedido_pago_id INT FOREIGN KEY REFERENCES pedidos_pago(id),
factura_id INT FOREIGN KEY REFERENCES facturas(id),
monto_factura DECIMAL(18,2) NOT NULL,
monto_a_pagar DECIMAL(18,2) NOT NULL, -- puede diferir del monto factura
created_at DATETIME DEFAULT GETDATE()
);
-- Tabla de Gestión de Pago (registro en factura cuando se toma)
CREATE TABLE facturas_gestion (
id INT PRIMARY KEY IDENTITY,
factura_id INT FOREIGN KEY REFERENCES facturas(id),
pedido_pago_id INT FOREIGN KEY REFERENCES pedidos_pago(id),
metodo_pago VARCHAR(20) NOT NULL,
monto_pedido DECIMAL(18,2),
observaciones TEXT,
fecha_gestion DATETIME DEFAULT GETDATE(),
usuario VARCHAR(50)
);
-- Tabla de Órdenes de Pago Emitidas (importada del sistema contable)
CREATE TABLE ordenes_pago (
id INT PRIMARY KEY IDENTITY,
numero_documento VARCHAR(20) NOT NULL,
numero_operacion VARCHAR(20),
fecha_contabilizacion DATE NOT NULL,
codigo_proveedor VARCHAR(20),
nombre_proveedor VARCHAR(200),
efectivo DECIMAL(18,2) DEFAULT 0,
cheques DECIMAL(18,2) DEFAULT 0,
transferencia DECIMAL(18,2) DEFAULT 0,
tarjeta DECIMAL(18,2) DEFAULT 0,
importe_retencion DECIMAL(18,2) DEFAULT 0,
tipo_cambio DECIMAL(10,4) DEFAULT 1,
total DECIMAL(18,2) NOT NULL,
total_documento DECIMAL(18,2),
created_at DATETIME DEFAULT GETDATE()
);GET /api/facturas Lista facturas con filtros y paginación.
| Parámetro | Tipo | Descripción |
|---|---|---|
status | query string | Filtro por estado: pendiente, tomado, pagado, todos |
cliente_id | query int | Filtro por cliente específico |
search | query string | Búsqueda en cliente, producto, contrato |
fecha_desde | query date | Filtro fecha emisión desde |
fecha_hasta | query date | Filtro fecha emisión hasta |
page | query int | Página (default: 1) |
limit | query int | Registros por página (default: 50) |
-- Query base
SELECT
f.id,
f.numero_factura,
c.id as cliente_id,
c.razon_social as cliente,
f.producto,
f.cosecha,
f.contrato,
f.monto,
f.fecha_emision,
f.fecha_vencimiento,
f.status,
fg.metodo_pago,
fg.monto_pedido,
fg.fecha_gestion,
fg.observaciones
FROM facturas f
INNER JOIN clientes c ON f.cliente_id = c.id
LEFT JOIN facturas_gestion fg ON f.id = fg.factura_id
WHERE 1=1
AND (@status IS NULL OR @status = 'todos' OR f.status = @status)
AND (@cliente_id IS NULL OR f.cliente_id = @cliente_id)
AND (@search IS NULL OR
c.razon_social LIKE '%' + @search + '%' OR
f.producto LIKE '%' + @search + '%' OR
f.contrato LIKE '%' + @search + '%')
ORDER BY f.fecha_emision DESC
OFFSET (@page - 1) * @limit ROWS
FETCH NEXT @limit ROWS ONLY;Response:
{
"data": [
{
"id": "FAC-001",
"cliente": "Agrícola San Martín S.A.",
"clienteId": 1,
"producto": "Soja",
"cosecha": "2024/25",
"contrato": "CT-2024-0156",
"monto": 125000.00,
"fechaEmision": "2024-11-15",
"fechaVencimiento": "2025-01-15",
"status": "pendiente",
"metodoPago": null,
"montoPedido": null,
"fechaGestion": null,
"observaciones": null
}
],
"pagination": {
"page": 1,
"limit": 50,
"total": 150,
"totalPages": 3
},
"summary": {
"totalPendientes": 85,
"montoPendiente": 4500000.00,
"totalTomados": 45,
"montoTomado": 2100000.00,
"totalPagados": 20,
"montoPagado": 980000.00
}
}GET /api/facturas/:id Obtiene detalle completo de una factura.
SELECT
f.*,
c.razon_social as cliente,
c.cuit as cliente_cuit,
fg.metodo_pago,
fg.monto_pedido,
fg.fecha_gestion,
fg.observaciones,
pp.numero_pedido
FROM facturas f
INNER JOIN clientes c ON f.cliente_id = c.id
LEFT JOIN facturas_gestion fg ON f.id = fg.factura_id
LEFT JOIN pedidos_pago pp ON fg.pedido_pago_id = pp.id
WHERE f.id = @id;GET /api/clientes/:clienteId/cuentas-bancarias Lista cuentas bancarias activas de un cliente.
SELECT
id,
banco,
tipo_cuenta,
cbu,
alias,
moneda
FROM cuentas_bancarias
WHERE cliente_id = @clienteId
AND activo = 1
ORDER BY banco, tipo_cuenta;Response:
{
"data": [
{
"id": 1,
"banco": "Banco Nación",
"tipoCuenta": "Cuenta Corriente",
"cbu": "0110012345678901234567",
"alias": "AGRICOLA.SANMARTIN.BNA",
"moneda": "ARS"
},
{
"id": 2,
"banco": "Banco Galicia",
"tipoCuenta": "Caja de Ahorro",
"cbu": "0070012345678901234567",
"alias": "AGRICOLA.SM.USD",
"moneda": "USD"
}
]
}POST /api/pedidos-pago Crea un nuevo pedido de pago.
Request Body:
{
"clienteId": 1,
"metodoPago": "transferencia",
"cuentaBancariaId": 2,
"montoTotal": 125000.00,
"descontarGastos": true,
"paraCobrarInsumos": false,
"observaciones": "Pago parcial según acuerdo",
"facturas": [
{
"facturaId": 1,
"montoFactura": 125000.00,
"montoAPagar": 100000.00
},
{
"facturaId": 5,
"montoFactura": 92150.00,
"montoAPagar": 25000.00
}
]
}Validaciones:
Stored Procedure / Transacción:
BEGIN TRANSACTION;
-- 1. Generar número de pedido
DECLARE @numeroPedido VARCHAR(20);
SET @numeroPedido = 'PP-' + FORMAT(GETDATE(), 'yyyyMMdd') + '-' +
RIGHT('0000' + CAST((SELECT COUNT(*) + 1 FROM pedidos_pago
WHERE CAST(fecha_pedido AS DATE) = CAST(GETDATE() AS DATE)) AS VARCHAR), 4);
-- 2. Insertar cabecera pedido de pago
INSERT INTO pedidos_pago (
numero_pedido, cliente_id, metodo_pago, cuenta_bancaria_id,
monto_total, descontar_gastos, para_cobrar_insumos,
observaciones, usuario_creacion
)
VALUES (
@numeroPedido, @clienteId, @metodoPago, @cuentaBancariaId,
@montoTotal, @descontarGastos, @paraCobrarInsumos,
@observaciones, @usuario
);
DECLARE @pedidoId INT = SCOPE_IDENTITY();
-- 3. Insertar detalle (por cada factura)
INSERT INTO pedidos_pago_detalle (pedido_pago_id, factura_id, monto_factura, monto_a_pagar)
VALUES (@pedidoId, @facturaId, @montoFactura, @montoAPagar);
-- 4. Actualizar status de facturas a 'tomado'
UPDATE facturas
SET status = 'tomado', updated_at = GETDATE()
WHERE id IN (SELECT factura_id FROM pedidos_pago_detalle WHERE pedido_pago_id = @pedidoId);
-- 5. Registrar gestión en cada factura
INSERT INTO facturas_gestion (
factura_id, pedido_pago_id, metodo_pago, monto_pedido, observaciones, usuario
)
SELECT
ppd.factura_id,
@pedidoId,
@metodoPago,
ppd.monto_a_pagar,
@observaciones,
@usuario
FROM pedidos_pago_detalle ppd
WHERE ppd.pedido_pago_id = @pedidoId;
COMMIT;Response (201 Created):
{
"success": true,
"data": {
"id": 45,
"numeroPedido": "PP-20241215-0012",
"clienteId": 1,
"cliente": "Agrícola San Martín S.A.",
"metodoPago": "transferencia",
"montoTotal": 125000.00,
"cantidadFacturas": 2,
"fechaPedido": "2024-12-15T14:30:00"
}
}GET /api/pedidos-pago Lista pedidos de pago con filtros.
| Parámetro | Tipo | Descripción |
|---|---|---|
status | query | pendiente, procesado, anulado |
cliente_id | query | Filtro por cliente |
fecha_desde | query | Desde fecha pedido |
fecha_hasta | query | Hasta fecha pedido |
metodo_pago | query | Filtro por método |
GET /api/pedidos-pago/:id Detalle completo de un pedido de pago.
-- Cabecera
SELECT
pp.*,
c.razon_social as cliente,
cb.banco,
cb.cbu,
cb.alias
FROM pedidos_pago pp
INNER JOIN clientes c ON pp.cliente_id = c.id
LEFT JOIN cuentas_bancarias cb ON pp.cuenta_bancaria_id = cb.id
WHERE pp.id = @id;
-- Detalle facturas
SELECT
ppd.*,
f.numero_factura,
f.producto,
f.cosecha,
f.contrato,
f.fecha_emision,
f.fecha_vencimiento
FROM pedidos_pago_detalle ppd
INNER JOIN facturas f ON ppd.factura_id = f.id
WHERE ppd.pedido_pago_id = @id;GET /api/ordenes-pago Lista órdenes de pago emitidas (readonly, importadas del sistema contable).
| Parámetro | Tipo | Descripción |
|---|---|---|
search | query | Búsqueda en N° doc, operación, proveedor |
fecha_desde | query | Desde fecha contabilización |
fecha_hasta | query | Hasta fecha contabilización |
metodo_pago | query | efectivo, cheques, transferencia, tarjeta |
SELECT
id,
numero_documento,
numero_operacion,
fecha_contabilizacion,
codigo_proveedor,
nombre_proveedor,
efectivo,
cheques,
transferencia,
tarjeta,
importe_retencion,
tipo_cambio,
total,
total_documento,
-- Calcular método principal
CASE
WHEN transferencia > 0 THEN 'transferencia'
WHEN cheques > 0 THEN 'cheque'
WHEN efectivo > 0 THEN 'efectivo'
WHEN tarjeta > 0 THEN 'tarjeta'
ELSE 'otro'
END as metodo_principal
FROM ordenes_pago
WHERE 1=1
AND (@search IS NULL OR
numero_documento LIKE '%' + @search + '%' OR
numero_operacion LIKE '%' + @search + '%' OR
nombre_proveedor LIKE '%' + @search + '%')
ORDER BY fecha_contabilizacion DESC;Response con resumen:
{
"data": [...],
"summary": {
"totalOrdenes": 35,
"montoTotal": 15840000.00,
"totalEfectivo": 450000.00,
"totalCheques": 2100000.00,
"totalTransferencias": 12500000.00,
"totalTarjeta": 150000.00,
"totalRetenciones": 640000.00
}
}GET /api/ordenes-pago/:id Detalle de una orden de pago.
GET /api/facturas/export Exporta facturas a CSV/Excel.
| Parámetro | Tipo | Descripción |
|---|---|---|
format | query | csv o xlsx |
status | query | Filtro opcional |
ids | query | Lista de IDs específicos (opcional) |
Response: Archivo descargable con headers apropiados.
GET /api/ordenes-pago/export Exporta órdenes de pago a CSV/Excel.
Seguridad:
Performance:
facturas.status, facturas.cliente_id, facturas.fecha_emisionpedidos_pago.cliente_id, pedidos_pago.fecha_pedidoManejo de Errores:
{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "Las facturas seleccionadas no pertenecen al mismo cliente",
"details": []
}
}Este documento debería darles a los devs suficiente detalle para estimar y ejecutar las tareas de backend.
You can send messages while the preview loads