-- =============================================
-- Author:      Vitacore (с)
-- Create date: 2019-10-29
-- Description: Проверка статуса рецепта
-- =============================================
--DROP PROCEDURE IF EXISTS dbo.sp_CheckRecipeStatus;

CREATE OR REPLACE PROCEDURE  rds.sp_CheckRecipeStatus(
    "RecipeID" uuid,
    "StatusTo" INTEGER,
    "IsNew" BOOLEAN = false,
    "dateTime" timestamp DEFAULT NULL,
    "ChangedByPharmacy" BOOLEAN = false
    )
AS
$$
DECLARE
     _errorDescription text;
     _isValid BOOLEAN;
     
    BEGIN
        DROP TABLE IF EXISTS tempStatusValidation;
	    CREATE TEMP TABLE tempStatusValidation(
	        statusFrom integer
	      , statusTo integer
	      , valid BOOLEAN
	      , error text
	    );

        insert into tempStatusValidation(statusFrom, statusTo, valid, error)
        -- 0:Выписан
              select 0, 0, "IsNew",						    'Невозможная операция (0:Выписан -> 0:Выписан)'
        union select 0, 1, true,							'Невозможная операция (0:Выписан -> 1:Отбракован)'
        union select 0, 2, true,							'Невозможная операция (0:Выписан -> 2:Реализован)'
        union select 0, 3, true,							'Невозможная операция (0:Выписан -> 3:Отсрочен)'
        union select 0, 4, true,							'Невозможная операция (0:Выписан -> 4:Не обработан)'
        union select 0, 5, true,							'Невозможная операция (0:Выписан -> 5:Отложен)'
        -- 1:Отбракован
        union select 1, 0, false,							'Невозможная операция (1:Отбракован -> 0:Выписан)'
        union select 1, 1, false,							'Невозможная операция (1:Отбракован -> 1:Отбракован)'
        union select 1, 2, false,							'Невозможная операция (1:Отбракован -> 2:Реализован)'
        union select 1, 3, false,							'Невозможная операция (1:Отбракован -> 3:Отсрочен)'
        union select 1, 4, false,							'Невозможная операция (1:Отбракован -> 4:Не обработан)'
        union select 1, 5, false,							'Невозможная операция (1:Отбракован -> 5:Отложен)'
        -- 2:Реализован -- 
        union select 2, 0, false,							'Невозможная операция (2:Реализован -> 0:Выписан)'
        union select 2, 1, false,							'Невозможная операция (2:Реализован -> 1:Отбракован)'
        union select 2, 2, "IsNew",						    'Невозможная операция (2:Реализован -> 2:Реализован)'
        union select 2, 3, false,							'Невозможная операция (2:Реализован -> 3:Отсрочен)'
        union select 2, 4, "ChangedByPharmacy",			    'Невозможная операция (2:Реализован -> 4:Не обработан)'
        union select 2, 5, false,							'Невозможная операция (2:Реализован -> 5:Отложен)'
        -- 3:Отсрочен
        union select 3, 0, false,							'Невозможная операция (3:Отсрочен -> 0:Выписан)'
        union select 3, 1, "ChangedByPharmacy",			    'Невозможная операция (3:Отсрочен -> 1:Отбракован)'
        union select 3, 2, "ChangedByPharmacy",			    'Невозможная операция (3:Отсрочен -> 2:Реализован)'
        union select 3, 3, false,							'Невозможная операция (3:Отсрочен -> 3:Отсрочен)'
        union select 3, 4, "ChangedByPharmacy",			    'Невозможная операция (3:Отсрочен -> 4:Не обработан)'
        union select 3, 5, "ChangedByPharmacy",			    'Невозможная операция (3:Отсрочен -> 5:Отложен)'
        -- 4:Не обработан
        union select 4, 0, false,							'Невозможная операция (4:Не обработан -> 0:Выписан)'
        union select 4, 1, true,							'Невозможная операция (4:Не обработан -> 1:Отбракован)'
        union select 4, 2, true,							'Невозможная операция (4:Не обработан -> 2:Реализован)'
        union select 4, 3, true,							'Невозможная операция (4:Не обработан -> 3:Отсрочен)'
        union select 4, 4, false,							'Невозможная операция (4:Не обработан -> 4:Не обработан)'
        union select 4, 5, true,							'Невозможная операция (4:Не обработан -> 5:Отложен)'
        -- 5:Отложен
        union select 5, 0, false,							'Невозможная операция (5:Отложен -> 0:Выписан)'
        union select 5, 1, false,							'Невозможная операция (5:Отложен -> 1:Отбракован)'
        union select 5, 2, "ChangedByPharmacy",			    'Невозможная операция (5:Отложен -> 2:Реализован)'
        union select 5, 3, false,							'Невозможная операция (5:Отложен -> 3:Отсрочен)'
        union select 5, 4, "ChangedByPharmacy",			    'Невозможная операция (5:Отложен -> 4:Не обработан)'
        union select 5, 5, false,							'Невозможная операция (5:Отложен -> 5:Отложен)';

        -- Заполняем необходимые переменные из таблиц, с блокировкой по рецепту
        select sv.error
              ,case when sv.valid is not null then sv.valid
                    -- разрешено, если предыдущее изменение тоже вручную
                    when sv.statusFrom = 3 and sv.statusTo = 4 then true
                    else false
               end
        INTO
            _errorDescription,
            _isValid
        from RDS.T_RECIPE r
            join tempStatusValidation sv on sv.statusFrom = r.Status
                    and
                sv.statusTo = "StatusTo"
        where r.RecipeID = "RecipeID";

        -- Если операция невозможна, возвращаем ошибку
        IF v_IsValid = 0 THEN
            RAISE EXCEPTION '%', _errorDescription;
        END IF;
END;
$$ LANGUAGE plpgsql;