ANALISIS MODULO RT-004: COMPRAS Y REABASTECIMIENTO
Fecha: 2025-12-18
Fase: 2 - Analisis por Modulo
Modulo: RT-004 Compras
Herencia: 80%
Story Points: 38
Prioridad: P0
1. DESCRIPCION GENERAL
1.1 Proposito
Gestion centralizada de compras con sugerencias automaticas de reabastecimiento, ordenes de compra y recepcion de mercancia.
1.2 Funcionalidades Principales
| Funcionalidad |
Descripcion |
Criticidad |
| Sugerencias compra |
Automaticas por stock |
Alta |
| Ordenes de compra |
CRUD completo |
Critica |
| Recepcion |
Validacion contra OC |
Critica |
| Proveedores |
Catalogo y evaluacion |
Media |
| Distribucion |
A sucursales |
Media |
2. HERENCIA DEL CORE
2.1 Componentes Heredados (80%)
| Componente Core |
% Uso |
Accion |
| purchase.purchase_orders |
100% |
HEREDAR |
| purchase.purchase_order_lines |
100% |
HEREDAR |
| purchase.rfqs |
100% |
HEREDAR |
| core.partners (proveedores) |
100% |
HEREDAR |
| inventory.pickings |
80% |
EXTENDER para recepcion |
2.2 Servicios a Heredar
import { PurchaseOrdersService } from '@erp-core/purchases';
import { RFQsService } from '@erp-core/purchases';
import { PartnersService } from '@erp-core/core'; // proveedores
2.3 Servicios a Extender
class RetailPurchaseService extends PurchaseOrdersService {
// Sugerencias automaticas
async generateSuggestions(): Promise<PurchaseSuggestion[]>;
// Distribucion a sucursales
async distributeToBranches(poId: string, distribution: DistributionDto): Promise<void>;
}
3. COMPONENTES NUEVOS
3.1 Entidades Adicionales
// 1. PurchaseSuggestion - Sugerencia de compra
@Entity('purchase_suggestions', { schema: 'retail' })
export class PurchaseSuggestion {
@PrimaryGeneratedColumn('uuid')
id: string;
@Column('uuid')
tenantId: string;
@ManyToOne(() => Product)
product: Product;
@ManyToOne(() => Branch, { nullable: true })
branch: Branch;
@ManyToOne(() => Partner)
supplier: Partner;
@Column({ type: 'decimal', precision: 12, scale: 4 })
currentStock: number;
@Column({ type: 'decimal', precision: 12, scale: 4 })
reorderPoint: number;
@Column({ type: 'decimal', precision: 12, scale: 4 })
suggestedQuantity: number;
@Column({ type: 'decimal', precision: 12, scale: 2 })
estimatedCost: number;
@Column({ type: 'boolean', default: false })
isProcessed: boolean;
@Column({ type: 'timestamptz' })
generatedAt: Date;
}
// 2. PurchaseDistribution - Distribucion a sucursales
@Entity('purchase_distributions', { schema: 'retail' })
export class PurchaseDistribution {
@PrimaryGeneratedColumn('uuid')
id: string;
@ManyToOne(() => PurchaseOrder)
purchaseOrder: PurchaseOrder;
@ManyToOne(() => PurchaseOrderLine)
purchaseOrderLine: PurchaseOrderLine;
@ManyToOne(() => Branch)
branch: Branch;
@Column({ type: 'decimal', precision: 12, scale: 4 })
quantity: number;
@Column({ type: 'boolean', default: false })
isReceived: boolean;
}
3.2 Servicios Backend
| Servicio |
Metodos Principales |
| PurchaseSuggestionService |
generate(), getAll(), approve(), reject() |
| RetailPurchaseService |
createFromSuggestions(), distribute() |
| ReceiptService |
create(), validate(), confirm() |
| SupplierEvaluationService |
evaluate(), getMetrics() |
3.3 Controladores
@Controller('purchases')
export class RetailPurchaseController {
// Sugerencias
@Get('suggestions')
getSuggestions(): Promise<PurchaseSuggestion[]>;
@Post('suggestions/generate')
generateSuggestions(): Promise<PurchaseSuggestion[]>;
@Post('suggestions/approve')
approveSuggestions(@Body() ids: string[]): Promise<PurchaseOrder>;
// Ordenes de compra (heredado + extendido)
@Post()
create(@Body() dto: CreatePurchaseOrderDto): Promise<PurchaseOrder>;
@Post(':id/distribute')
distribute(@Param('id') id: string, @Body() dto: DistributionDto): Promise<void>;
@Post(':id/send')
sendToSupplier(@Param('id') id: string): Promise<void>;
// Recepcion
@Post(':id/receive')
receiveOrder(@Param('id') id: string, @Body() dto: ReceiveDto): Promise<Receipt>;
// Proveedores
@Get('suppliers/:id/metrics')
getSupplierMetrics(@Param('id') id: string): Promise<SupplierMetrics>;
}
4. ALGORITMO DE SUGERENCIAS
4.1 Logica de Reorden
interface ReorderAlgorithm {
// Parametros
stockActual: number;
stockMinimo: number;
stockMaximo: number;
ventasDiarias: number; // promedio ultimos 30 dias
leadTime: number; // dias de entrega proveedor
// Calculo
puntoReorden = stockMinimo + (ventasDiarias * leadTime);
// Condicion
if (stockActual <= puntoReorden) {
cantidadSugerida = stockMaximo - stockActual;
return { producto, cantidadSugerida, proveedor };
}
}
4.2 Pseudocodigo
-- Query para generar sugerencias
WITH ventas_promedio AS (
SELECT
product_id,
AVG(quantity) as avg_daily_sales
FROM retail.pos_order_lines pol
JOIN retail.pos_orders po ON pol.order_id = po.id
WHERE po.order_date >= NOW() - INTERVAL '30 days'
GROUP BY product_id
),
stock_actual AS (
SELECT
product_id,
SUM(quantity_on_hand) as total_stock
FROM retail.branch_stock
GROUP BY product_id
)
SELECT
p.id as product_id,
sa.total_stock,
p.reorder_point,
p.max_stock,
COALESCE(vp.avg_daily_sales, 0) as avg_sales,
s.lead_time_days,
(p.reorder_point + (COALESCE(vp.avg_daily_sales, 0) * s.lead_time_days)) as calculated_reorder,
(p.max_stock - sa.total_stock) as suggested_quantity
FROM inventory.products p
JOIN stock_actual sa ON p.id = sa.product_id
LEFT JOIN ventas_promedio vp ON p.id = vp.product_id
LEFT JOIN core.partners s ON p.default_supplier_id = s.id
WHERE sa.total_stock <= (p.reorder_point + (COALESCE(vp.avg_daily_sales, 0) * s.lead_time_days));
5. FLUJOS DE NEGOCIO
5.1 Flujo de Compra
1. Sistema genera sugerencias (cron)
↓
2. Comprador revisa sugerencias
↓
3. Aprobar sugerencias
↓
4. Crear orden de compra
↓
5. Asignar distribucion por sucursal
↓
6. Enviar OC al proveedor
↓
7. Estado: DRAFT → CONFIRMED → SENT
↓
8. Recepcion de mercancia
↓
9. Validar vs OC (diferencias)
↓
10. Estado: SENT → RECEIVED
↓
11. Actualizar stock por sucursal
↓
12. Generar factura proveedor (opcional)
5.2 Flujo de Recepcion
1. Proveedor entrega mercancia
↓
2. Buscar OC correspondiente
↓
3. Contar productos recibidos
↓
4. Registrar cantidades por linea
↓
5. Validar vs ordenado
↓
6. Si diferencia:
a. Faltante: registrar, notificar
b. Sobrante: rechazar o aceptar
↓
7. Confirmar recepcion
↓
8. Distribuir a sucursales
↓
9. Actualizar stock
6. TABLAS DDL
6.1 Tablas Heredadas
-- Del core (schema purchase)
purchase.purchase_orders
purchase.purchase_order_lines
purchase.rfqs
purchase.rfq_lines
6.2 Tablas Nuevas Retail
-- Sugerencias
CREATE TABLE retail.purchase_suggestions (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
tenant_id UUID NOT NULL REFERENCES auth.tenants(id),
product_id UUID NOT NULL REFERENCES inventory.products(id),
branch_id UUID REFERENCES retail.branches(id),
supplier_id UUID REFERENCES core.partners(id),
current_stock DECIMAL(12,4) NOT NULL,
reorder_point DECIMAL(12,4) NOT NULL,
suggested_quantity DECIMAL(12,4) NOT NULL,
estimated_cost DECIMAL(12,2),
is_processed BOOLEAN DEFAULT FALSE,
generated_at TIMESTAMPTZ DEFAULT NOW(),
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- Distribucion
CREATE TABLE retail.purchase_distributions (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
tenant_id UUID NOT NULL REFERENCES auth.tenants(id),
purchase_order_id UUID NOT NULL REFERENCES purchase.purchase_orders(id),
purchase_order_line_id UUID NOT NULL REFERENCES purchase.purchase_order_lines(id),
branch_id UUID NOT NULL REFERENCES retail.branches(id),
quantity DECIMAL(12,4) NOT NULL,
is_received BOOLEAN DEFAULT FALSE,
created_at TIMESTAMPTZ DEFAULT NOW()
);
7. DEPENDENCIAS
7.1 Dependencias de Core
| Modulo |
Estado |
Requerido Para |
| MGN-012 Purchasing |
0% |
Ordenes de compra |
| MGN-011 Inventory |
60% |
Productos |
| MGN-005 Catalogs |
0% |
Proveedores |
7.2 Dependencias de Retail
| Modulo |
Tipo |
| RT-001 Fundamentos |
Prerequisito |
| RT-003 Inventario |
Stock y recepciones |
7.3 Bloquea a
| Modulo |
Razon |
| RT-003 Inventario |
Recepciones actualizan stock |
8. CRITERIOS DE ACEPTACION
8.1 Funcionales
8.2 Performance
9. RIESGOS
| Riesgo |
Probabilidad |
Impacto |
Mitigacion |
| Core purchase incompleto |
Alta |
Bloqueante |
Implementar primero en core |
| Algoritmo ineficiente |
Media |
Medio |
Indices y optimizacion query |
10. ESTIMACION DETALLADA
| Componente |
SP Backend |
SP Frontend |
Total |
| Entities + Migrations |
3 |
- |
3 |
| SuggestionService |
5 |
- |
5 |
| RetailPurchaseService |
5 |
- |
5 |
| ReceiptService |
5 |
- |
5 |
| SupplierEvaluationService |
2 |
- |
2 |
| Controllers |
3 |
- |
3 |
| Suggestions UI |
- |
5 |
5 |
| PO Pages |
- |
5 |
5 |
| Receipt Pages |
- |
5 |
5 |
| TOTAL |
23 |
15 |
38 |
11. REFERENCIAS
| Documento |
Ubicacion |
| Epica RT-004 |
docs/08-epicas/EPIC-RT-004-compras.md |
| Modulo Core Purchase |
erp-core/backend/src/modules/purchases/ |
Estado: ANALISIS COMPLETO
Bloqueado por: RT-001, RT-003, MGN-012 (core)