Saltar al contenido

Cumplimiento sanitario

En OdontoWare, el inventario avisa que un medicamento caducó, pero igual permite darle salida

Por Eduardo Gallegos · Publicado el 24 de septiembre de 2026

Consultorio dental con vitrina de medicamentos e insumos.

La Ley General de Salud no deja espacio para interpretación: "quedan prohibidos la venta y suministro de medicamentos con fecha de caducidad vencida", y esa prohibición está nombrada de forma expresa -no como residual- en el catálogo de multas del artículo 421. Verificamos en el código de OdontoWare que el inventario sí detecta y lista los medicamentos por caducar, pero que ni una salida manual ni el descuento automático al emitir una receta comprueban la fecha de caducidad antes de mover el stock.

La ley lo nombra de forma expresa, no es un catch-all

El artículo 233 de la Ley General de Salud es una prohibición directa, sin condicionantes:

"Quedan prohibidos la venta y suministro de medicamentos con fecha de caducidad vencida."

El supuesto es amplio: no exige que exista una venta -basta con el suministro- y no distingue entre farmacia y consultorio. A diferencia de otros hallazgos que caen en el residual genérico de la LGS, este artículo 233 aparece nombrado explícitamente en el catálogo cerrado del artículo 421, junto con otras cerca de cuarenta disposiciones:

"Se sancionará con una multa equivalente de seis mil hasta doce mil veces el salario mínimo general diario vigente en la zona económica de que se trate, la violación de las disposiciones contenidas en los artículos [...] 232, 233, 237 [...] de esta Ley."

Agenda una demo gratis

La sanción: de 6,000 a 12,000 veces el salario mínimo, un rango fijo por ley

A diferencia del residual del artículo 422 -que fija sólo un techo, "hasta" cierto número de veces-, el artículo 421 fija un rango cerrado: nunca menos de 6,000 veces el salario mínimo general diario, nunca más de 12,000. Con el salario mínimo general diario vigente en 2026 ($315.04 en la zona general del país, $440.87 en la Zona Libre de la Frontera Norte, cifras de la Comisión Nacional de los Salarios Mínimos), el rango de la multa por cada infracción es de $1,890,240.00 a $3,780,480.00 MXN en zona general, y de $2,645,220.00 a $5,290,440.00 MXN en la frontera norte. El artículo 421 remite igual al artículo 418, que obliga a la autoridad sanitaria a fundar y motivar el monto dentro de ese rango según el daño a la salud, la gravedad, la condición socioeconómica del infractor, la reincidencia y el beneficio obtenido.

ElementoQué dice la norma
Prohibición de vender o suministrar medicamento caducadoArt. 233, Ley General de Salud
El art. 233 está nombrado de forma expresa en el catálogo de multas (no es residual)Art. 421, LGS
Rango de la multa por infracciónArt. 421, LGS: 6,000 a 12,000 veces el salario mínimo general diario ($1,890,240.00-$3,780,480.00 MXN zona general; $2,645,220.00-$5,290,440.00 MXN Zona Libre de la Frontera Norte, 2026)
Criterios para fijar el monto dentro del rangoArt. 418, LGS: daño a la salud, gravedad, condición socioeconómica, reincidencia, beneficio obtenido

Verificado en el código: hay alerta, pero no hay candado

Confirmamos el hallazgo directamente en el código de OdontoWare. El inventario sí sabe distinguir medicamentos por caducar: el método alerts() (services/clinical/src/inventory/inventory.service.ts:305-325) consulta expiry_date y devuelve la lista de artículos que vencen dentro de los próximos días configurados. El sistema tiene el dato, y lo muestra.

Lo que no hace es usar ese mismo dato para detener una salida. El registro de un movimiento manual, createMovement() (services/clinical/src/inventory/inventory.service.ts:266-302), sólo confirma que el artículo existe y pertenece a la clínica antes de llamar a applyStockDelta() (línea 446); la rama que resta stock (líneas 467-477) valida exclusivamente que stock_qty >= qty -saldo suficiente-, sin ninguna referencia a expiry_date. Un medicamento con existencia positiva y fecha de caducidad de ayer registra la salida igual que uno vigente.

El mismo patrón se repite en el descuento automático. decrementForPrescription() (services/clinical/src/inventory/inventory.service.ts:346-426) resuelve cada medicamento de la receta por nombre contra inventory_items con la condición WHERE active = true AND category = 'medicine' AND lower(name) = $1 -sin filtrar por caducidad- y descuenta con el mismo condicional de saldo:

UPDATE inventory_items SET stock_qty = stock_qty - $2 WHERE id = $1 AND stock_qty >= $2 RETURNING stock_qty

PrescriptionsService.issue() (services/clinical/src/prescriptions/prescriptions.service.ts:70) llama a ese descuento en la misma transacción en la que emite la receta (línea 147). Como diseño best-effort, el propio código documenta que "stock insuficiente NO bloquea la receta"; lo que no está documentado ni implementado es que la caducidad tampoco la bloquea. Un medicamento vencido con existencia positiva se descuenta y se asocia a la receta sin ninguna alerta adicional a la que ya existe, por separado, en el listado de inventario.

El origen del dato tampoco ayuda: createInventoryItemSchema y updateInventoryItemSchema (services/clinical/src/inventory/inventory.schemas.ts:18-40) definen expiryDate como opcional al crear un artículo, y como opcional y anulable (nullable().optional()) al actualizarlo -incluso para un artículo de categoría medicine-. Un medicamento puede darse de alta o editarse sin fecha de caducidad en absoluto.

Agenda una demo gratis

Qué significa en la práctica, y qué falta en el producto

El código demuestra una brecha de control, no que un consultorio ya haya suministrado un medicamento caducado: una salida puede corresponder a una baja legítima, y emitir una receta tampoco acredita que el medicamento llegó a entregarse. Lo que sí está confirmado es que el sistema no impide ese destino. Lo que falta no es la alerta -ya existe-, sino que applyStockDelta() y decrementForPrescription() rechacen o adviertan explícitamente una salida de un artículo con expiry_date vencida, y que la fecha de caducidad sea obligatoria para artículos de categoría medicine. Puedes ver ese recorrido completo, de la alerta a la salida, en de la alerta a la salida: el flujo completo en OdontoWare, o estimar la exposición con tus propios números en la calculadora de exposición por medicamento caducado en inventario.

Preguntas frecuentes

¿OdontoWare no tiene ninguna alerta de caducidad?
Sí la tiene: el panel de alertas lista los medicamentos por caducar dentro de los próximos días configurados. El hallazgo es que esa alerta es informativa: ni el registro manual de una salida ni el descuento automático al recetar consultan la fecha de caducidad antes de mover el stock.

¿Basta con que el consultorio revise la caducidad por disciplina propia?
Reduce el riesgo si esa disciplina se sostiene siempre, pero el sistema no lo comprueba: no hay ningún bloqueo si algún día se omite la revisión manual, y la alerta por sí sola no impide la salida.

¿Esto significa que ya se suministró un medicamento caducado en mi consultorio?
No necesariamente: el hallazgo es que el sistema lo permite y no lo detecta al momento de la salida, no que ya haya ocurrido. Si tu equipo retira del anaquel los medicamentos vencidos por disciplina propia, hoy no tienes el problema -pero tampoco tienes ningún candado si algún día deja de hacerlo.

¿Cuál es la multa exacta?
La Ley General de Salud fija un rango cerrado, no un monto único: de 6,000 a 12,000 veces el salario mínimo general diario vigente en la zona económica ($1,890,240.00 a $3,780,480.00 MXN en zona general, $2,645,220.00 a $5,290,440.00 MXN en la Zona Libre de la Frontera Norte, con el salario mínimo 2026), calificada por la autoridad sanitaria dentro de ese rango según los cinco criterios del artículo 418 -no es un cobro automático por cada caso-.

Fuentes consultadas: Ley General de Salud, texto vigente publicado por la Cámara de Diputados del H. Congreso de la Unión, artículos 233, 416, 417, 418 y 421. Salario mínimo general diario vigente en 2026 por zona económica (Comisión Nacional de los Salarios Mínimos). Este artículo es orientativo y no sustituye una revisión de tu caso por tu responsable sanitario o asesor legal.

Ve cómo OdontoWare maneja hoy la caducidad, y dónde falta el candado

Te mostramos en vivo el panel de alertas, el registro de una salida y el punto exacto donde nadie cruza uno con el otro.

Agenda una demo gratis
Agendar 30 min
Contacta a un especialista
Ventas y Proyectos (abre en una ventana nueva) Soporte Técnico (abre en una ventana nueva)