Skip to content

Modulo preperación de quimicos - chemicalPreparation

Propósito

Registra y gestiona preparaciones de productos químicos para plantas de tratamiento, actualizando inventario por lotes, y emitiendo notificaciones cuando el inventario es insuficiente o está por debajo del mínimo.

Dónde se usa

  • Rutas: src/routes/v1/chemicalPreparation/chemicalPreparation.ts registradas en src/routes/v1/index.ts.
  • Controlador: src/controllers/chemicalPreparation/chemicalPreparationController.ts.
  • Modelo: src/models/chemicalPreparation.ts e interfaz src/interfaces/IChemicalPreparation/IChemicalPreparation.ts.
  • Integraciones: ChemicalProduct (inventario y lotes), NotifyManager (notificaciones), TreatmentPlant, User.

Endpoints

  • POST /chemical-preparation

    • Middlewares: validateJwt, tenantMiddleware, validateFunctionalityPermission(FUNCTIONALITIES.SETTING_DOSING_CREATION), chemicalPreparationValidator.
    • Crea un registro de preparación y descuenta inventario por lotes del producto químico indicado.
    • Emite notificaciones de inventario insuficiente o bajo inventario según corresponda.
  • GET /chemical-preparations

    • Middlewares: validateJwt, tenantMiddleware, validateFunctionalityPermission(FUNCTIONALITIES.SETTING_DOSING_LIST).
    • Lista preparaciones con datos poblados de producto, usuario y planta.
  • GET /chemical-preparation/:id

    • Detalle de una preparación con datos poblados.
  • GET /chemical-preparation-by-plant/:treatmentPlantId

    • Lista preparaciones asociadas a una planta específica.

Datos principales (IChemicalPreparation)

  • treatmentPlantId: ObjectId de la planta.
  • chemicalProductId: ObjectId del producto químico.
  • quantityToPrepare: cantidad a preparar.
  • units: unidades (validadas por validUnits).
  • preparedBy: usuario que preparó.
  • preparedAt: fecha de preparación (por defecto Date.now en el modelo si no se envía).
  • status: PREPARED | CANCELLED (por defecto PREPARED).
  • notes: notas libres.
  • state: active|inactive (según validState).

Nota: el arreglo lotsUsed existe a nivel de interfaz pero está temporalmente oculto en el esquema del modelo.

Flujo de creación (POST /chemical-preparation)

  1. Selección de modelos por tenant: usa conexión multitenant (getModel) si req.dbConnection existe; de lo contrario usa modelos globales.
  2. Validación de producto e inventario:
    • Busca ChemicalProduct por chemicalProductId.
    • Si availableQuantity <= 0 o quantityToPrepare <= 0, responde 400 y puede generar notificación noInventory (ver notificaciones).
  3. Descuento por lotes:
    • Usa helpers/deductFromLots/distributeQuantity para distribuir la cantidad requerida (quantityToPrepare) comenzando por los lotes con fecha de expiración más cercana.
    • Actualiza cada lote con su nueva quantity mediante updateOne por _id del subdocumento del lote.
    • Recalcula y actualiza availableQuantity del producto a partir de la suma de los lotes resultantes; también refresca lastUpdated.
    • Si la cantidad total por lotes no alcanza (remainingQuantity > 0), responde 400.
  4. Notificación de inventario bajo (lowInventory):
    • Si el nuevo availableQuantity es menor o igual a minQuantity, crea notificación para roles SUPERVISOR/OPERADOR.
  5. Creación del registro:
    • Inserta el documento ChemicalPreparation con el body original.
    • Responde 201 con el documento creado.

Reglas de negocio de inventario (distributeQuantity)

  • Ordena los lotes por expirationDate ascendente.
  • Descuenta de cada lote lo necesario hasta cumplir la cantidad a preparar, respetando cantidades disponibles.
  • Retorna updatedInventory (lotes con su nueva quantity) y remainingQuantity (cantidad faltante si no alcanza el inventario total).

Notificaciones

  • Se usa createNotifyManager del controlador notifyManagerController para persistir notificaciones en el tenant actual (si aplica).
  • Tipos relevantes en este flujo:
    • noInventory: cuando no hay inventario suficiente para preparar. Mensaje generado con mapeo de nombre de químico (chemicalNameMapping).
    • lowInventory: cuando availableQuantity queda por debajo del mínimo configurado.
  • Reglas por rol:
    • TREEA_ADMIN: no genera notificaciones en estos casos.
    • SUPERVISOR o OPERADOR: se crea la notificación en la BD del cliente.

Validaciones de entrada

Validator src/validators/chemicalPreparation.ts (express-validator):

  • Requeridos: treatmentPlantId, chemicalProductId, quantityToPrepare, units, preparedBy, preparedAt.

Seguridad y permisos

  • Autenticación JWT (validateJwt).
  • Contexto tenant (tenantMiddleware) para enrutar a la conexión de BD del cliente.
  • Permisos por funcionalidad (validateFunctionalityPermission):
    • Crear: FUNCTIONALITIES.SETTING_DOSING_CREATION.
    • Listar/consultar: FUNCTIONALITIES.SETTING_DOSING_LIST.

Relación con dosificación (Setting Dosing)

  • La preparación registra el acto de preparar cierta cantidad de un producto antes o durante la operación de dosificación.
  • El descuento de inventario por lotes asegura coherencia con la disponibilidad de producto usada en la dosificación.
  • Las notificaciones noInventory/lowInventory ayudan a anticipar faltantes que impactarían la continuidad de la dosificación.

Consideraciones de diseño

  • Multitenancy: todos los accesos a modelos soportan req.dbConnection para aislar datos por cliente.
  • Consistencia de inventario: el availableQuantity se deriva de la suma de lotes actualizados para evitar desalineación.
  • Precisión numérica: se usa Decimal.js para operaciones de resta/suma de cantidades.
  • Mapeo de nombres: chemicalNameMapping estandariza el nombre en mensajes de notificación.

Ejemplos de uso (request minimos)

POST /chemical-preparation

json
{
  "treatmentPlantId": "<ObjectId>",
  "chemicalProductId": "<ObjectId>",
  "quantityToPrepare": 120.5,
  "units": "L",
  "preparedBy": "<ObjectId usuario>",
  "preparedAt": "2025-10-06T12:00:00.000Z",
  "notes": "Preparación para turno tarde"
}

GET /chemical-preparations

  • Respuesta incluye chemicalProductId, preparedBy, treatmentPlantId poblados con campos básicos.

Posibles errores y respuestas

  • 400: inventario insuficiente para la cantidad a preparar.
  • 400: inventario no positivo o cantidad a preparar no válida.
  • 500: error interno (por ejemplo, producto no encontrado, fallos de BD).

Archivos clave

  • Controlador: src/controllers/chemicalPreparation/chemicalPreparationController.ts
  • Modelo: src/models/chemicalPreparation.ts
  • Interfaz: src/interfaces/IChemicalPreparation/IChemicalPreparation.ts
  • Rutas: src/routes/v1/chemicalPreparation/chemicalPreparation.ts y registro en src/routes/v1/index.ts
  • Lógica de lotes: src/helpers/deductFromLots/distributeQuantity.ts
  • Notificaciones: src/controllers/notifyManagerController.ts
  • Validator: src/validators/chemicalPreparation.ts

Pendiente

  • Habilitar lotsUsed en el modelo para auditar qué lotes se consumieron por preparación.