erp-retail/orchestration/planes/fase-2-analisis-modulos/ANALISIS-RT-004-compras.md

10 KiB

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

  • Generar sugerencias automaticas
  • Ver sugerencias pendientes
  • Aprobar/rechazar sugerencias
  • Crear OC desde sugerencias
  • Crear OC manual
  • Asignar distribucion por sucursal
  • Enviar OC a proveedor (email)
  • Registrar recepcion
  • Validar cantidades vs OC
  • Registrar diferencias
  • Actualizar stock al recibir
  • Ver historial de compras por proveedor

8.2 Performance

  • Generacion sugerencias < 30s
  • Listado OC < 1s

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)