# Sprint 4: Motor de Precios - Resumen

## Objetivo
Implementar el motor de precios completo para el vertical de Retail, incluyendo gestión de promociones, cupones y cálculo dinámico de precios.

## Componentes Implementados

### 1. Servicios

#### PriceEngineService (`src/modules/pricing/services/price-engine.service.ts`)
Motor central de cálculo de precios con las siguientes capacidades:

- **calculatePrices()**: Calcula precios para un conjunto de líneas de pedido
  - Aplica promociones automáticas activas
  - Soporta múltiples tipos de promoción
  - Gestiona stackability (promociones acumulables)
  - Aplica cupones si se proporciona código

- **getActivePromotions()**: Obtiene promociones activas para sucursal/canal

- **applyCoupon()**: Aplica un cupón al resultado de precios

- **validateCoupon()**: Valida un código de cupón sin aplicarlo

**Tipos de Promoción Soportados:**
| Tipo | Descripción |
|------|-------------|
| `percentage_discount` | Descuento porcentual |
| `fixed_discount` | Descuento de monto fijo |
| `buy_x_get_y` | Compra X, lleva Y |
| `bundle` | Precio especial por paquete |
| `flash_sale` | Venta relámpago |
| `quantity_discount` | Descuento por volumen |
| `free_shipping` | Envío gratis |
| `gift_with_purchase` | Regalo con compra |

#### PromotionService (`src/modules/pricing/services/promotion.service.ts`)
Servicio CRUD para gestión de promociones:

- **createPromotion()**: Crear promoción con validación de código único
- **updatePromotion()**: Actualizar promoción (solo en estado draft/scheduled)
- **listPromotions()**: Listar con filtros paginados
- **activatePromotion()**: Activar promoción
- **pausePromotion()**: Pausar promoción activa
- **endPromotion()**: Finalizar promoción
- **cancelPromotion()**: Cancelar promoción
- **addProducts()**: Agregar productos a promoción
- **removeProduct()**: Remover producto de promoción
- **updatePromotionStatuses()**: Actualizar estados automáticamente según fechas

**Flujo de Estados:**
```
draft → scheduled → active → ended
                  ↓
                paused
                  ↓
              cancelled
```

#### CouponService (`src/modules/pricing/services/coupon.service.ts`)
Servicio completo para gestión de cupones:

- **createCoupon()**: Crear cupón individual
- **generateBulkCoupons()**: Generar cupones en lote (hasta 1000)
- **updateCoupon()**: Actualizar cupón
- **activateCoupon()**: Activar cupón
- **deactivateCoupon()**: Desactivar cupón
- **redeemCoupon()**: Canjear cupón con validación completa
- **reverseRedemption()**: Revertir un canje (devolución)
- **getRedemptionHistory()**: Historial de canjes paginado
- **getCouponStats()**: Estadísticas del cupón

**Tipos de Cupón:**
- `percentage`: Descuento porcentual
- `fixed_amount`: Monto fijo
- `free_shipping`: Envío gratis
- `free_product`: Producto gratis

### 2. Validación Zod (`src/modules/pricing/validation/pricing.schema.ts`)

Schemas completos para:

**Promociones:**
- `createPromotionSchema`: Creación con todas las opciones
- `updatePromotionSchema`: Actualización parcial
- `addPromotionProductsSchema`: Agregar productos
- `listPromotionsQuerySchema`: Filtros de listado

**Cupones:**
- `createCouponSchema`: Creación con opciones completas
- `updateCouponSchema`: Actualización parcial
- `generateBulkCouponsSchema`: Generación en lote
- `redeemCouponSchema`: Canje de cupón
- `validateCouponSchema`: Validación de código
- `reverseRedemptionSchema`: Reversión de canje
- `listCouponsQuerySchema`: Filtros de listado

**Motor de Precios:**
- `calculatePricesSchema`: Entrada para cálculo
- `lineItemSchema`: Línea de producto

### 3. Controladores (`src/modules/pricing/controllers/pricing.controller.ts`)

**Endpoints del Motor de Precios (3):**
| Método | Ruta | Descripción |
|--------|------|-------------|
| POST | `/api/pricing/calculate` | Calcular precios |
| POST | `/api/pricing/validate-coupon` | Validar cupón |
| GET | `/api/pricing/active-promotions` | Promociones activas |

**Endpoints de Promociones (11):**
| Método | Ruta | Descripción |
|--------|------|-------------|
| GET | `/api/pricing/promotions` | Listar promociones |
| GET | `/api/pricing/promotions/:id` | Obtener promoción |
| POST | `/api/pricing/promotions` | Crear promoción |
| PUT | `/api/pricing/promotions/:id` | Actualizar promoción |
| POST | `/api/pricing/promotions/:id/activate` | Activar |
| POST | `/api/pricing/promotions/:id/pause` | Pausar |
| POST | `/api/pricing/promotions/:id/end` | Finalizar |
| POST | `/api/pricing/promotions/:id/cancel` | Cancelar |
| POST | `/api/pricing/promotions/:id/products` | Agregar productos |
| DELETE | `/api/pricing/promotions/:id/products/:productId` | Remover producto |
| DELETE | `/api/pricing/promotions/:id` | Eliminar (soft) |

**Endpoints de Cupones (14):**
| Método | Ruta | Descripción |
|--------|------|-------------|
| GET | `/api/pricing/coupons` | Listar cupones |
| GET | `/api/pricing/coupons/:id` | Obtener cupón |
| GET | `/api/pricing/coupons/code/:code` | Obtener por código |
| POST | `/api/pricing/coupons` | Crear cupón |
| POST | `/api/pricing/coupons/bulk` | Generar lote |
| PUT | `/api/pricing/coupons/:id` | Actualizar cupón |
| POST | `/api/pricing/coupons/:id/activate` | Activar |
| POST | `/api/pricing/coupons/:id/deactivate` | Desactivar |
| POST | `/api/pricing/coupons/:id/redeem` | Canjear por ID |
| POST | `/api/pricing/coupons/redeem` | Canjear por código |
| POST | `/api/pricing/coupons/redemptions/:id/reverse` | Revertir canje |
| GET | `/api/pricing/coupons/:id/redemptions` | Historial canjes |
| GET | `/api/pricing/coupons/:id/stats` | Estadísticas |
| DELETE | `/api/pricing/coupons/:id` | Eliminar (soft) |

**Total: 28 endpoints**

### 4. Rutas (`src/modules/pricing/routes/pricing.routes.ts`)

Configuración de rutas con:
- Autenticación JWT requerida
- Middleware de sucursal donde aplica
- Validación Zod de entrada
- Control de permisos granular

**Permisos Requeridos:**
- `pricing:calculate`, `pricing:validate`, `pricing:view`
- `promotions:view`, `promotions:create`, `promotions:update`, `promotions:activate`, `promotions:delete`
- `coupons:view`, `coupons:create`, `coupons:update`, `coupons:activate`, `coupons:redeem`, `coupons:reverse`, `coupons:delete`

## Características Destacadas

### Restricciones de Promociones
- Por fechas (inicio/fin)
- Por días de la semana
- Por horarios específicos
- Por monto mínimo de orden
- Por cantidad mínima de productos
- Por categorías incluidas/excluidas
- Por productos excluidos
- Por sucursales específicas
- Por niveles de cliente
- Solo nuevos clientes
- Solo miembros de lealtad

### Stackability (Acumulabilidad)
- Promociones pueden ser acumulables o exclusivas
- Lista de promociones con las que puede combinarse
- Prioridad numérica para resolver conflictos

### Tracking de Cupones
- Límite de usos totales
- Límite de usos por cliente
- Tracking de canjes con orden y canal
- Posibilidad de reversión con razón

## Estructura de Archivos

```
src/modules/pricing/
├── controllers/
│   ├── index.ts
│   └── pricing.controller.ts
├── entities/
│   ├── index.ts
│   ├── promotion.entity.ts
│   ├── promotion-product.entity.ts
│   ├── coupon.entity.ts
│   └── coupon-redemption.entity.ts
├── routes/
│   ├── index.ts
│   └── pricing.routes.ts
├── services/
│   ├── index.ts
│   ├── price-engine.service.ts
│   ├── promotion.service.ts
│   └── coupon.service.ts
├── validation/
│   ├── index.ts
│   └── pricing.schema.ts
└── index.ts
```

## Dependencias

- TypeORM 0.3.x
- Zod para validación
- Express para routing
- Entidades existentes: Promotion, Coupon, PromotionProduct, CouponRedemption

## Próximos Pasos

El Sprint 5 cubrirá CFDI/Facturación según el roadmap:
- Integración con PAC para timbrado
- Generación de XML CFDI 4.0
- Cancelación de facturas
- Notas de crédito
