> ## Documentation Index
> Fetch the complete documentation index at: https://docs.prodexlabs.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Planificación de la producción

> Crea y gestiona planes de producción desde la Demanda hasta la entrega.

## Resumen

El módulo de planificación de ProDex es un optimizador de Planificación y Programación Avanzadas (APS). Dado tu Demanda, Inventario, lista de materiales (BOM) y Restricciones (Constraints) de Recursos (Resources), calcula un plan de producción óptimo: qué producir, cuándo y en qué cantidades.

La planificación opera sobre un horizonte de tiempo configurable dividido en intervalos (días, semanas, etc.) y equilibra **dos** objetivos:

1. **Cumplimiento de Demanda**: cumplir la Demanda a tiempo (la pérdida por atraso)
2. **Objetivos de Inventario**: mantener el Inventario dentro de su banda objetivo (la pérdida de Inventario)

**La capacidad de Recursos es una Restricción dura, no un objetivo.** El optimizador nunca compensa Demanda o Inventario contra capacidad: si no hay suficiente capacidad en algún intervalo, el plan queda inviable hasta que añadas capacidad, relajes los plazos o relajes Restricciones.

## Cómo configurar tu Modelo de Planificación

Un **Modelo de Planificación (Planning Model)** es la Plantilla (Template) de configuración para tus ejecuciones de planificación. Define la estructura de tu problema de planificación: el horizonte, los Recursos, las BOMs, las variantes y los pesos del objetivo. Lo creas una vez y lo reutilizas en múltiples ejecuciones de planificación.

### Horizonte de planificación

Establece el número de intervalos (`n_intervals`) y la unidad de intervalo (p. ej., `day`, `week`, `month`). Un horizonte de 30 días con intervalos diarios significa que el optimizador planifica 30 días por adelantado, día por día.

### Recursos

Define los tipos de Recursos disponibles para producción: líneas, máquinas, grupos de mano de obra, etc. Cada Recurso tiene un **techo de capacidad** por intervalo, definido por (Recurso, fecha) en cada [ejecución de planificación](#capacidad-de-recursos), no en el Modelo.

Los Recursos se conectan a las BOMs mediante **requisitos de Recursos** (`resource_requirements.json`): un arreglo plano de entradas `{bom_id, resource_id, quantity}` que especifican cuánto consume una BOM dada de cada Recurso por unidad producida.

### Lista de materiales

Especifica qué [BOMs](/es/product/bom) incluye el Modelo de Planificación. El `metadata.json` del Modelo lleva un campo explícito `boms`: las BOMs no listadas son invisibles para el optimizador, incluso si existen en la Fábrica (Factory). ProDex clasifica los materiales automáticamente:

* **RAW**: materiales hoja sin componentes (solo entradas, suministrados externamente)
* **INTERMEDIATE**: materiales que *tienen componentes* Y son *consumidos por al menos otra BOM*, producidos internamente y consumidos por BOMs aguas abajo
* **SKU**: productos terminados vendibles que tienen componentes y *no* son consumidos por ninguna otra BOM

Una BOM sin componentes es RAW independientemente de si algo la consume.

### Variantes

La mayoría de las Fábricas producen la misma Entidad (Entity) en múltiples variantes (tamaño, color, grado, configuración). El sistema de planificación maneja variantes mediante **predicados de atributos tipados**: cada BOM, Pedido (Order) de Demanda, objetivo de Inventario y registro a la mano puede llevar una especificación de variante.

El optimizador empareja una línea de Demanda con una BOM verificando que la condición de variante de la BOM sea un *subconjunto* de la variante de la Demanda. Una BOM sin condición de variante (la receta por defecto) coincide con cualquier cosa para esa Entidad. Consulta [BOMs](/es/product/bom#variant-conditions) para la sintaxis de la condición de variante (condiciones boolean / discrete\_text / discrete\_number / range, unidas con AND).

### Balance del objetivo (Alpha)

El único parámetro que controla el compromiso entre los dos objetivos:

`Total Loss = (1 − α) · Demand Lateness + α · Inventory Loss`

* **α = 0**: cumplimiento puro de Demanda: al optimizador solo le importa cumplir los plazos; los objetivos de Inventario se ignoran.
* **α = 1**: objetivos puros de Inventario: al optimizador solo le importan las bandas de Inventario; la Demanda puede atrasarse arbitrariamente.
* **α ≈ 0.5**: balanceado; ajusta por Fábrica.

No hay un peso separado para la Utilización de Recursos: los Recursos son siempre Restricciones duras.

### Decaimiento temporal (Beta, Gamma)

Dos parámetros de amortiguación que reducen el peso de las penalizaciones más adelante en el horizonte:

* **Beta (β)**: decaimiento temporal sobre las penalizaciones de **Demanda**. Un Pedido de Demanda incumplido `d` intervalos adelante se penaliza por `β^d`. Por defecto `0.9`: a 30 días, una entrega incumplida cuesta \~4% de lo que cuesta el mismo incumplimiento hoy.
* **Gamma (γ)**: decaimiento temporal sobre las penalizaciones de **objetivos de Inventario**. Misma forma, aplicada a las violaciones de banda de Inventario. Por defecto `0.9`.

Baja el decaimiento (más cerca de 0) cuando solo te importa el corto plazo; súbelo (más cerca de 1) cuando la planificación de horizonte largo importa tanto como hoy.

### Etiquetas de Pedido y etiquetas de Inventario

Las etiquetas clasifican Pedidos de Demanda y objetivos de Inventario en categorías con sus propios pesos y formas de penalización. Esto te permite expresar que algunos Pedidos son más críticos que otros, o que algunos objetivos de Inventario tienen más riesgo.

Cada etiqueta lleva:

* **`weight`**: multiplicador del término de penalización de esa etiqueta
* **`hard`**: booleano. Una etiqueta dura promueve el plazo (u objetivo de Inventario) a una Restricción dura; incumplirla hace que la ejecución sea inviable
* **`penalty_curvature`**: controla qué tan agresivamente crece la penalización con el tamaño del incumplimiento (lineal, sublineal, superlineal)
* **`buffer`**: ventana de holgura antes de que se active la penalización
* **Rolling vs. non-rolling (solo etiquetas de Inventario)**: las etiquetas de Inventario non-rolling fuerzan el Inventario a cero fuera de la ventana objetivo, útil para objetivos limitados en el tiempo como caducidad. Por defecto es rolling con peso 0.

### Restricciones personalizadas

Opcionalmente define Restricciones adicionales en `custom_constraints/`: por ejemplo, cantidades mínimas de producción, salida diaria máxima para un SKU específico o reglas de secuencia de producción.

### Objetivos personalizados

Separado de las Restricciones, `custom_objectives/` te permite añadir términos ponderados a la función objetivo: útil cuando "minimizar el costo total" o "suavizar la producción a lo largo del horizonte" es parte de tu objetivo real.

## Cómo ejecutar un plan

Una **Ejecución (Run) de Planificación** es una ejecución del optimizador contra tu Modelo de Planificación. Cada ejecución toma una Instantánea (Snapshot) puntual de tus entradas de Demanda y Suministro.

### Pedidos de Demanda

Lo que necesitas producir. Cada Pedido de Demanda especifica:

* `name`: nombre legible del Pedido (el nombre del archivo sirve como ID)
* `tag_id`: qué etiqueta de Pedido clasifica este Pedido
* `date`: fecha de vencimiento
* `skus`: lista de entradas SKU + cantidad, cada una opcionalmente con una variante

Los Pedidos de Demanda solo aceptan Entidades clasificadas como SKU. Las Entidades RAW o INTERMEDIATE no pueden ser pedidas como Demanda.

### Pedidos de Suministro

Materias primas que esperas recibir. Cada Pedido de Suministro especifica:

* `name`
* `date`: fecha de llegada
* `materials`: lista de entradas `{entity_id, quantity, variant?}`

Los Pedidos de Suministro solo aceptan Entidades clasificadas como RAW.

### Inventario a la mano

Stock actual al momento de la planificación, establecido en el `initial_conditions.json` de la ejecución junto con el `start_date` de la ejecución. Cada entrada es `{entity_id, quantity, variant?}`.

### Objetivos de Inventario

Niveles de Inventario objetivo que quieres mantener, con una etiqueta, cantidad objetivo y una banda de margen aceptable. Las penalizaciones crecen lineales por tramos fuera de la banda (pendientes ±1 dentro del búfer, ±7 en la siguiente zona, ±25 en la zona de incumplimiento profundo) para que los pequeños incumplimientos se perdonen y los grandes incumplimientos dominen rápidamente.

### Capacidad de Recursos

Techos de capacidad por (Recurso, fecha) para la ejecución.

<Warning>
  **Los intervalos faltantes se asumen como cero, no ilimitados.** Si olvidas especificar capacidad para una fecha, el optimizador trata ese Recurso como no disponible en esa fecha, y "¿por qué no se está produciendo nada?" generalmente es una fila de capacidad faltante, no un bug del solver.
</Warning>

No hay línea base implícita; defines la capacidad desde cero por (Recurso, fecha). Planifica el tiempo de inactividad *omitiendo o poniendo en cero* los intervalos relevantes; planifica capacidad excedente subiendo el techo.

### Cómo validar las entradas

Antes de ejecutar el optimizador, valida. El paso `validate_inputs` atrapa las roturas más comunes:

* BOMs faltantes o no referenciadas en la lista `boms` del Modelo
* Violaciones de condición de variante (variantes mutuamente exclusivas, referencias a atributos no definidos)
* Clasificaciones de material inconsistentes con cómo se usan las Entidades (p. ej., un no-SKU apareciendo en un Pedido de Demanda)
* Ciclos en el grafo de BOM

Corrige los errores de validación antes de optimizar: casi siempre indican un problema de configuración de datos, no un problema del solver.

### Optimización

Una vez listas tus entradas, ejecuta el optimizador. ProDex devuelve sincrónicamente para planes rápidos (menos de \~30 segundos). Las ejecuciones más largas devuelven un `job_id`; haz polling a `get_optimization_results` para recuperar el plan cuando se complete.

## Cómo interpretar la salida

### Plan de producción

Un calendario día por día (o intervalo por intervalo) de qué producir: Entidad, variante, fecha y cantidad. Esta es la salida principal.

### Cumplimientos de Pedidos

El campo `fulfilled` de cada Pedido de Demanda es **booleano**: cada Pedido está totalmente cubierto por el plan o no. No hay un estado intermedio "parcialmente satisfecho" a nivel de Pedido.

### Viabilidad

Si el optimizador no encuentra un plan válido, reporta inviable con una razón. La causa más común es un **plazo duro** (un Pedido de Demanda en una etiqueta dura) que no puede cumplirse dada la capacidad de Recursos y la cadena de BOM. Otras causas incluyen Suministro faltante para materias primas y Restricciones personalizadas sobre-restrictivas.

Para recuperarte: relaja la etiqueta dura, añade capacidad en los intervalos restringidos, extiende el horizonte o elimina la Restricción sobre-restrictiva.

### KPIs

* **Estado del solver**: óptimo, viable o inviable
* **Valor objetivo**: la pérdida total ponderada que el optimizador minimizó
* **Brecha de optimalidad**: qué tan cerca está la solución del mejor teórico (más bajo es mejor)
* **Tiempo de cómputo**: tiempo de reloj del solver, en segundos

## Cómo ajustar y volver a ejecutar

La planificación es iterativa. Después de revisar los resultados:

* Ajusta **α** si el balance atraso/Inventario no coincide con tus prioridades
* Vuelve a ajustar los pesos por etiqueta si Pedidos u objetivos específicos merecen más o menos énfasis
* Añade o modifica Restricciones personalizadas / objetivos personalizados
* Actualiza las entradas de Demanda o Suministro a medida que llegue nueva información
* Vuelve a ejecutar y compara contra el plan anterior

Los resultados de múltiples ejecuciones de planificación se almacenan y pueden compararse lado a lado.
