DROP PROCEDURE IF EXISTS nota_bodega_lock_por_tiempo;
DELIMITER $$
CREATE PROCEDURE nota_bodega_lock_por_tiempo()
    COMMENT 'Pone lock_por_tiempo a notas dadas con alta_db o desloqueados antes de: ahora - minutos'
    MODIFIES SQL DATA
BEGIN
    DECLARE affectedRows INT;
    DECLARE minutos INT;
    DECLARE antesDel DATETIME;
    DECLARE EXIT HANDLER FOR SQLEXCEPTION
        BEGIN
            ROLLBACK;
            RESIGNAL; -- Reraise the error for external handling
        END;
    DECLARE EXIT HANDLER FOR NOT FOUND
        BEGIN
            ROLLBACK;
        END;

    SELECT
        CASE
            WHEN parametros->>'$.unit' = 'min' THEN   parametros->>'$.valor'
            WHEN parametros->>'$.unit' = 'hr' THEN 60*parametros->>'$.valor'
            WHEN parametros->>'$.unit' = 'dias' THEN 60*24*parametros->>'$.valor'
            END
    INTO minutos
    FROM parametro
    WHERE parametro_id = 'lock_por_tiempo-time';

    SELECT DATE_SUB(NOW(), INTERVAL minutos MINUTE) INTO antesDel;

    START TRANSACTION;
    INSERT INTO nota_bodega_hist(action, pk, motive, record, user_nick, date)
        (SELECT 'lock_por_tiempo Locked por tiempo', nota_bodega_id, 'lock_por_tiempo no_record','{}','sistema', NOW()
         FROM nota_bodega
         WHERE lock_por_tiempo = 0 AND alta_db <= antesDel AND (lock_por_tiempo_el IS NULL OR lock_por_tiempo_el <= antesDel)
        );
    SET affectedRows = ROW_COUNT();
    IF affectedRows > 0 THEN
        UPDATE nota_bodega SET
                               lock_por_tiempo = 1,
                               lock_por_tiempo_el = NOW(),
                               lock_por_tiempo_motivo =
                                   CONCAT('\r\n<li>',
                                          'Lock Por Tiempo Parametro de tiempo el',
                                          DATE_FORMAT(NOW(), '%e/%b/%y %k:%i'),
                                          IFNULL(lock_por_tiempo_motivo, '')
                                   ),
                               lock_por_tiempo_por = 'Sistema'
        WHERE lock_por_tiempo = 0 AND alta_db <= antesDel AND (lock_por_tiempo_el IS NULL OR lock_por_tiempo_el <= antesDel);
    END IF;
    COMMIT;
    SELECT antesDel, affectedRows;
END
$$
DELIMITER ;

DROP PROCEDURE IF EXISTS nota_bodega_lock_system_lock;
DELIMITER $$
CREATE PROCEDURE nota_bodega_lock_system_lock()
    COMMENT 'Pone system_lock a notas dadas con alta_db o desloqueados antes de: ahora - minutos'
    MODIFIES SQL DATA
BEGIN
    DECLARE affectedRows INT;
    DECLARE minutos INT;
    DECLARE antesDel DATETIME;
    DECLARE EXIT HANDLER FOR SQLEXCEPTION
        BEGIN
            ROLLBACK;
            RESIGNAL; -- Reraise the error for external handling
        END;
    DECLARE EXIT HANDLER FOR NOT FOUND
        BEGIN
            ROLLBACK;
        END;

    SELECT
        CASE
            WHEN parametros->>'$.unit' = 'min' THEN   parametros->>'$.valor'
            WHEN parametros->>'$.unit' = 'hr' THEN 60*parametros->>'$.valor'
            WHEN parametros->>'$.unit' = 'dias' THEN 60*24*parametros->>'$.valor'
            END
    INTO minutos
    FROM parametro
    WHERE parametro_id = 'system_lock-time';

    SELECT DATE_SUB(NOW(), INTERVAL minutos MINUTE) INTO antesDel;

    START TRANSACTION;
    INSERT INTO nota_bodega_hist(action, pk, motive, record, user_nick, date)
        (SELECT 'System Locked por tiempo', nota_bodega_id, 'system_lock no_record','{}','sistema', NOW()
         FROM nota_bodega
         WHERE system_lock = 0 AND alta_db <= antesDel AND (system_lock_el IS NULL OR system_lock_el <= antesDel)
        );
    SET affectedRows = ROW_COUNT();
    IF affectedRows > 0 THEN
        UPDATE nota_bodega SET
                               system_lock = 1,
                               system_lock_el = NOW(),
                               system_lock_motivo =
                                   CONCAT('\r\n<li>',
                                          'System Lock por Parametro de tiempo el',
                                          DATE_FORMAT(NOW(), '%e/%b/%y %k:%i'),
                                          IFNULL(system_lock_motivo, '')
                                   ),
                               system_lock_por = 'Sistema'
        WHERE system_lock = 0 AND alta_db <= antesDel AND (system_lock_el IS NULL OR system_lock_el <= antesDel);
    END IF;
    COMMIT;
    SELECT antesDel, affectedRows;
END
$$
DELIMITER ;

DROP PROCEDURE IF EXISTS nota_bodega_lock_super_lock;
DELIMITER $$
CREATE PROCEDURE nota_bodega_lock_super_lock()
    COMMENT 'Pone super_lock a notas dadas con alta_db o desloqueados antes de: ahora - minutos'
    MODIFIES SQL DATA
BEGIN
    DECLARE affectedRows INT;
    DECLARE minutos INT;
    DECLARE antesDel DATETIME;
    DECLARE EXIT HANDLER FOR SQLEXCEPTION
        BEGIN
            ROLLBACK;
            RESIGNAL; -- Reraise the error for external handling
        END;
    DECLARE EXIT HANDLER FOR NOT FOUND
        BEGIN
            ROLLBACK;
        END;

    SELECT
        CASE
            WHEN parametros->>'$.unit' = 'min' THEN   parametros->>'$.valor'
            WHEN parametros->>'$.unit' = 'hr' THEN 60*parametros->>'$.valor'
            WHEN parametros->>'$.unit' = 'dias' THEN 60*24*parametros->>'$.valor'
            END
    INTO minutos
    FROM parametro
    WHERE parametro_id = 'super_user_lock-time';

    SELECT DATE_SUB(NOW(), INTERVAL minutos MINUTE) INTO antesDel;

    START TRANSACTION;
        INSERT INTO nota_bodega_hist(action, pk, motive, record, user_nick, date)
            (SELECT 'Super Locked por tiempo', nota_bodega_id, 'super_lock no_record','{}','sistema', NOW()
             FROM nota_bodega
             WHERE super_lock = 0 AND alta_db <= antesDel AND (super_lock_el IS NULL OR super_lock_el <= antesDel)
            );
        SET affectedRows = ROW_COUNT();
        IF affectedRows > 0 THEN
            UPDATE nota_bodega SET
                                   super_lock = 1,
                                   super_lock_el = NOW(),
                                   super_lock_motivo =
                                       CONCAT('\r\n<li>',
                                              'Pone Super Lock por parametro de tiempo el',
                                              DATE_FORMAT(NOW(), '%e/%b/%y %k:%i'),
                                              IFNULL(super_lock_motivo, '')
                                       ),
                                   super_lock_por = 'Sistema'
            WHERE super_lock = 0 AND alta_db <= antesDel AND (super_lock_el IS NULL OR super_lock_el <= antesDel);
        END IF;
    COMMIT;
    SELECT antesDel, affectedRows;
END
$$
DELIMITER ;

INSERT INTO ats(
    funcion, es, termino,
    intervalo, base, siguiente_el
) VALUES(
            'nota_bodega_lockea_tiempo_transcurrido', 'manual', 'Si',
            'P30M', '2024-04-22 07:00:00', '2024-04-23 07:00:00') as new
ON DUPLICATE KEY UPDATE es=new.es, intervalo=new.intervalo, base=new.base, siguiente_el=new.siguiente_el;

-- Recrear el evento si cambia cada cuanto corre a checar
DROP EVENT IF EXISTS event_nota_bodega_locks_por_tiempo;
DELIMITER $$
CREATE EVENT event_nota_bodega_locks_por_tiempo
    ON SCHEDULE EVERY 30 MINUTE STARTS '2024-04-22 07:00:00'
    ON COMPLETION PRESERVE
    DO
        BEGIN
            DECLARE ponTermino CHAR(2) DEFAULT 'Si';
            DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
                BEGIN
                    SET ponTermino = 'No';
                END;

            UPDATE ats /* mysql_event event_nota_bodega_locks_por_tiempo marca incia*/
            SET termino = 'No', corrio_el = NOW(),
                -- suma 30 minutos y redondea a media hora
                siguiente_el = FROM_UNIXTIME( ROUND(UNIX_TIMESTAMP(DATE_ADD(NOW(), INTERVAL 30 MINUTE)) / 1800,0)*1800)
            WHERE funcion = 'nota_bodega_lockea_tiempo_transcurrido';

            CALL nota_bodega_lock_por_tiempo();
            CALL nota_bodega_lock_super_lock();
            CALL nota_bodega_lock_system_lock();
            CALL nota_bodega_lock_por_nota_posterior_ajuste();

            UPDATE ats /* mysql_event event_nota_bodega_locks_por_tiempo marca termina*/ SET termino = ponTermino
            WHERE funcion = 'nota_bodega_lockea_tiempo_transcurrido';

        END
$$
DELIMITER ;

/*
 -- checar si fallo o no inicio
SELECT funcion, siguiente_el, termino
FROM ats
WHERE funcion = 'nota_bodega_lockea_tiempo_transcurrido'
  AND (
    (termino = 'No' AND corrio_el > DATE_ADD(NOW(), INTERVAL 5 MINUTE ) ) -- anterior no ha terminado y ya tardo mucho
        OR
    (termino = 'Si' AND NOW() > DATE_ADD(siguiente_el, INTERVAL 5 MINUTE) )  -- anterior termino bien, pero no inicio a tiempo check#1
    );

 -- muestra como es el fail safe
 SELECT funcion,termino, now(), siguiente_el,
       (termino = 'Si' AND  NOW() > DATE_ADD(siguiente_el, INTERVAL 5 MINUTE)) as 'si_termino_ejecuto?',
       DATE_ADD(siguiente_el, INTERVAL 5 MINUTE) as 'si_termino_no_disparo_hora_dispara',
       (termino = 'No' AND NOW() > DATE_ADD(corrio_el, INTERVAL 5 MINUTE) ) as 'NO_termino_ejecuto?',
       DATE_ADD(corrio_el, INTERVAL 5 MINUTE) as 'NO_termino_no_disparo_hora_dispara'
FROM ats
WHERE funcion = 'nota_bodega_lockea_tiempo_transcurrido';

 */