# mbProduccion

Módulo de producción para los sistemas MacroBase: del pronóstico de ventas a la orden de
producción, y de ahí al inventario.

Es una **extensión del Back Office**, no un reemplazo. Comparte la base de datos de cada
cliente y escribe sus movimientos en las mismas tablas de inventario que mbinv. Vive
aparte porque mbinv corre PHP 5.6 con Symfony 2.7, y esto nace en **PHP 8.4 con Symfony
7.4 LTS**.

## El flujo

```
  Pronóstico            Orden de producción
  ┌──────────┐          ┌────────────────────────────────────────────┐
  │ al ojo ──┼────────► │ planificar → despachar MP → registrar      │
  │ aritmético│  (luego) │              producción → trasladar a PT   │
  │ ML        │  (luego) └────────────────────────────────────────────┘
  └──────────┘
```

| paso | qué escribe en el inventario de mbinv |
|---|---|
| Planificar | nada — explota la fórmula y la congela |
| Despachar materia prima | 1 traslado: bodega MP → bodega de producción |
| Registrar producción | **2 documentos**: producción (entra el PT) + explosión (sale la MP gastada) |
| Trasladar a producto terminado | 1 traslado: bodega de producción → bodega PT |

⚠️ **Un ciclo son cuatro documentos, no dos.** Registrar producción parecía no mover
nada —«sólo anota lo que salió»— y con eso se corrió el ciclo completo contra la base
real de masamadreartisan el 24-sep-2026. Funcionó, y dejó la bodega de producción
mintiendo de dos maneras a la vez: los 21.000 g de harina seguían ahí como si nadie los
hubiera usado, y el producto terminado quedó en **−48**, porque el último traslado lo
sacó de una bodega donde nunca había entrado. Está contado en
`api/src/Inventario/Produccion.php`.

Y se consume la fórmula de lo que se **produjo**, no de lo que se despachó: si se
despachó para 10 y salieron 9, la materia prima de 1 se queda en la bodega de
producción, que es donde de verdad está.

## Cómo está armado

```
api/    PHP 8.4 + Symfony 7.4 LTS — sólo API, sin plantillas
web/    Next.js + React + shadcn/ui
docs/   el diseño y las decisiones (empezá por docs/DISENO.md)
```

- `api/src/Inventario/` — **lo único** que escribe en tablas de mbinv: `Traslado.php`
  para los dos traslados, `Produccion.php` para el par producción + explosión.
- `api/src/Legado/ExplosionFormula.php` — la explosión de fórmula, recursiva.
- `api/src/Servicio/FlujoOrden.php` — las transiciones y sus reglas, todas juntas.
- `api/src/Bitacora/` — la bitácora mensual en la base de temporales.
- `despliegue/` — las plantillas de las **dos** formas de instalarlo: un demo en
  contenedores, y un cliente de producción con Apache y PHP nativos (sin Docker).
  Cuál es cuál, y por qué PHP 8.4 tiene que entrar por FPM, está en `docs/INSTALACION.md`.

## Para empezar

1. **Leé `docs/DISENO.md`.** Está lo que se decidió y, más importante, lo que se midió
   en mbinv antes de decidirlo.
2. **Levantá el ambiente** con `docs/AMBIENTE-LOCAL.md`. La imagen (`docker/`) sí está
   versionada; el `docker-compose.yml` local no, y esa página es la receta.
   Para instalarlo en un cliente, `docs/INSTALACION.md`.
3. **Comprobá** con `GET /api/salud`, que dice con nombre y apellido qué falta.

## Tres cosas que muerden

- **`schema_filter: ~^prod_~` en `api/config/packages/doctrine.yaml`.** Sin eso, una
  migración genera `DROP TABLE` para las 400 tablas de mbinv que este proyecto no mapea.
  Toda tabla nueva de este módulo lleva el prefijo `prod_`.
- **La bitácora usa su propia conexión.** Crea sus tablas mensuales con `CREATE TABLE`,
  y en MySQL el DDL hace commit implícito: sobre la conexión principal cerraba la
  transacción del despacho a mitad de camino.
- **`SetEnvIf Authorization "^(.+)$"` en Apache**, y no `(.*)`. Ver
  `docs/AMBIENTE-LOCAL.md`.
