
CREATE OR ALTER function fn_tolerancia_produto (
    produto_id integer,
    gp_id integer,
    perfil varchar(10))
returns varchar(500)
as
declare variable tipo_tolerancia_produto integer;
declare variable tolerancia_pro_qtd_maior integer;
declare variable tolerancia_pro_qtd_menor integer;
declare variable tolerancia_con_qtd_maior integer;
declare variable tolerancia_con_qtd_menor integer;
declare variable tolerancia_tipo_pro varchar(10);
declare variable tolerancia_tipo_con varchar(10);
declare variable sobra_producao integer;
declare variable sobra_consumo integer;
declare variable familia_id integer;
declare variable f_tolerancia_pro_qtd_maior integer;
declare variable f_tolerancia_pro_qtd_menor integer;
declare variable f_tolerancia_con_qtd_maior integer;
declare variable f_tolerancia_con_qtd_menor integer;
declare variable f_tolerancia_tipo_pro varchar(10);
declare variable f_tolerancia_tipo_con varchar(10);
declare variable f_sobra_producao integer;
declare variable f_sobra_consumo integer;
begin


  select
    /*p.tolerancia_pro_qtd_maior,
    p.tolerancia_pro_qtd_menor,
    p.tolerancia_con_qtd_maior,
    p.tolerancia_con_qtd_menor,
    p.tolerancia_tipo_pro,
    p.tolerancia_tipo_con,
    p.sobra_producao,
    p.sobra_consumo,*/
    p.familia_codigo
  from tbproduto p where p.codigo = :PRODUTO_ID
  into
    /*:tolerancia_pro_qtd_maior,
    :tolerancia_pro_qtd_menor,
    :tolerancia_con_qtd_maior,
    :tolerancia_con_qtd_menor,
    :tolerancia_tipo_pro,
    :tolerancia_tipo_con,
    :sobra_producao,
    :sobra_consumo,*/
    :FAMILIA_ID;

/*
  select
    f.tolerancia_pro_qtd_maior,
    f.tolerancia_pro_qtd_menor,
    f.tolerancia_con_qtd_maior,
    f.tolerancia_con_qtd_menor,
    f.tolerancia_tipo_pro,
    f.tolerancia_tipo_con,
    f.sobra_producao,
    f.sobra_consumo
  from tbfamilia f where f.codigo = :FAMILIA_ID
  into
    :f_tolerancia_pro_qtd_maior,
    :f_tolerancia_pro_qtd_menor,
    :f_tolerancia_con_qtd_maior,
    :f_tolerancia_con_qtd_menor,
    :f_tolerancia_tipo_pro,
    :f_tolerancia_tipo_con,
    :f_sobra_producao,
    :f_sobra_consumo;
*/

  select
    f.pro_qtd_maior,
    f.pro_qtd_menor,
    f.con_qtd_maior,
    f.con_qtd_menor,
    f.tipo_pro,
    f.tipo_con,
    f.sobra_producao,
    f.sobra_consumo
  from TBFAMILIA_TOLERANCIA f where f.familia_id = :FAMILIA_ID and f.gp_id = :GP_ID and f.perfil = :PERFIL
  into
    :f_tolerancia_pro_qtd_maior,
    :f_tolerancia_pro_qtd_menor,
    :f_tolerancia_con_qtd_maior,
    :f_tolerancia_con_qtd_menor,
    :f_tolerancia_tipo_pro,
    :f_tolerancia_tipo_con,
    :f_sobra_producao,
    :f_sobra_consumo;

    tolerancia_pro_qtd_maior = coalesce(f_tolerancia_pro_qtd_maior,0);
    tolerancia_pro_qtd_menor = coalesce(f_tolerancia_pro_qtd_menor,0);
    tolerancia_tipo_pro      = coalesce(f_tolerancia_tipo_pro,'Q');
    tolerancia_con_qtd_maior = coalesce(f_tolerancia_con_qtd_maior,0);
    tolerancia_con_qtd_menor = coalesce(f_tolerancia_con_qtd_menor,0);
    tolerancia_tipo_con      = coalesce(f_tolerancia_tipo_con,'Q');
    sobra_producao           = coalesce(f_sobra_producao,0);
    sobra_consumo            = coalesce(f_sobra_consumo,0);

  return fn_to_json(
    FN_TO_PAR_JSON('TOLERANCIA_PRO_QTD_MAIOR'   ,TOLERANCIA_PRO_QTD_MAIOR   ),
    FN_TO_PAR_JSON('TOLERANCIA_PRO_QTD_MENOR'   ,TOLERANCIA_PRO_QTD_MENOR   ),
    FN_TO_PAR_JSON('TOLERANCIA_TIPO_PRO'        ,TOLERANCIA_TIPO_PRO        ),
    FN_TO_PAR_JSON('TOLERANCIA_CON_QTD_MAIOR'   ,TOLERANCIA_CON_QTD_MAIOR   ),
    FN_TO_PAR_JSON('TOLERANCIA_CON_QTD_MENOR'   ,TOLERANCIA_CON_QTD_MENOR   ),
    FN_TO_PAR_JSON('TOLERANCIA_TIPO_CON'        ,TOLERANCIA_TIPO_CON        ),
    FN_TO_PAR_JSON('SOBRA_PRODUCAO'             ,SOBRA_PRODUCAO             ),
    FN_TO_PAR_JSON('SOBRA_CONSUMO'              ,SOBRA_CONSUMO              )
  );
end;

CREATE OR ALTER function fn_produto_tolerancia (
    produto_id integer,
    gp_id integer,
    perfil varchar(10),
    quantidade numeric(15,5),
    tipo varchar(10))
returns numeric(15,5)
as
declare variable ret numeric(15,5);
declare variable tolerancia varchar(500);
declare variable tolerancia_con_qtd_maior numeric(15,4);
declare variable tolerancia_con_qtd_menor numeric(15,4);
declare variable tolerancia_tipo_con varchar(10);
declare variable sobra_consumo integer;
declare variable tolerancia_quantidade_maior numeric(15,4);
declare variable tolerancia_quantidade_menor numeric(15,4);
declare variable tolerancia_tipo varchar(10);
begin

    RET = NULL;

    TOLERANCIA  = FN_TOLERANCIA_PRODUTO(:PRODUTO_ID, :GP_ID, :PERFIL);
    
    TOLERANCIA_CON_QTD_MAIOR = fn_json_v3(:TOLERANCIA, 'TOLERANCIA_CON_QTD_MAIOR' );
    TOLERANCIA_CON_QTD_MENOR = fn_json_v3(:TOLERANCIA, 'TOLERANCIA_CON_QTD_MENOR' );
    TOLERANCIA_TIPO_CON      = fn_json_v3(:TOLERANCIA, 'TOLERANCIA_TIPO_CON'      );
    SOBRA_CONSUMO            = fn_json_v3(:TOLERANCIA, 'SOBRA_CONSUMO'            );

    IF(TOLERANCIA_TIPO_CON = 'Q')THEN
    BEGIN
        :TOLERANCIA_QUANTIDADE_MAIOR = TOLERANCIA_CON_QTD_MAIOR;
        :TOLERANCIA_QUANTIDADE_MENOR = TOLERANCIA_CON_QTD_MENOR;
        :TOLERANCIA_TIPO = 'Q';
    END ELSE
    BEGIN
        IF(TOLERANCIA_TIPO_CON = 'P')THEN
        BEGIN
            :TOLERANCIA_QUANTIDADE_MAIOR = (QUANTIDADE * (TOLERANCIA_CON_QTD_MAIOR / 100.0000));
            :TOLERANCIA_QUANTIDADE_MENOR = (QUANTIDADE * (TOLERANCIA_CON_QTD_MENOR / 100.0000));
            :TOLERANCIA_TIPO = 'P';
        END ELSE
        BEGIN
            exception "..." 'Tolerância do produto "'||:PRODUTO_ID||'" não identificada. (Verificar tolerância no produto e na família)';
        END
    END

    if ( TIPO = 'MAX' ) then
    BEGIN
        RET = QUANTIDADE + TOLERANCIA_QUANTIDADE_MAIOR;
    END
    ELSE
    if ( TIPO = 'MIN' ) then
    BEGIN
        RET = QUANTIDADE - TOLERANCIA_QUANTIDADE_MENOR;
    END

    if(RET < 0)then
    begin
        RET = 0;
    end

    RETURN RET;

end;

DROP FUNCTION FN_TIPO_TOLERANCIA;

CREATE OR ALTER function fn_tolerancia (
    produto_id integer,
    gp_id integer,
    perfil varchar(10),
    quantidade numeric(15,5))
returns varchar(100)
as
declare variable ret numeric(15,5);
declare variable tolerancia varchar(500);
declare variable tolerancia_con_qtd_maior numeric(15,4);
declare variable tolerancia_con_qtd_menor numeric(15,4);
declare variable tolerancia_tipo_con varchar(10);
declare variable sobra_consumo integer;
declare variable tolerancia_quantidade_maior numeric(15,4);
declare variable tolerancia_quantidade_menor numeric(15,4);
declare variable tolerancia_tipo varchar(10);
declare variable qtd_max numeric(15,4);
declare variable qtd_min numeric(15,4);
begin

    RET = NULL;

    TOLERANCIA  = FN_TOLERANCIA_PRODUTO(:PRODUTO_ID, :GP_ID, :PERFIL);
    
    TOLERANCIA_CON_QTD_MAIOR = fn_json_v3(:TOLERANCIA, 'TOLERANCIA_CON_QTD_MAIOR' );
    TOLERANCIA_CON_QTD_MENOR = fn_json_v3(:TOLERANCIA, 'TOLERANCIA_CON_QTD_MENOR' );
    TOLERANCIA_TIPO_CON      = fn_json_v3(:TOLERANCIA, 'TOLERANCIA_TIPO_CON'      );
    SOBRA_CONSUMO            = fn_json_v3(:TOLERANCIA, 'SOBRA_CONSUMO'            );

    IF(TOLERANCIA_TIPO_CON = 'Q')THEN
    BEGIN
        :TOLERANCIA_QUANTIDADE_MAIOR = TOLERANCIA_CON_QTD_MAIOR;
        :TOLERANCIA_QUANTIDADE_MENOR = TOLERANCIA_CON_QTD_MENOR;
        :TOLERANCIA_TIPO = 'Q';
    END ELSE
    BEGIN
        IF(TOLERANCIA_TIPO_CON = 'P')THEN
        BEGIN
            :TOLERANCIA_QUANTIDADE_MAIOR = (QUANTIDADE * (TOLERANCIA_CON_QTD_MAIOR / 100.0000));
            :TOLERANCIA_QUANTIDADE_MENOR = (QUANTIDADE * (TOLERANCIA_CON_QTD_MENOR / 100.0000));
            :TOLERANCIA_TIPO = 'P';
        END ELSE
        BEGIN
            exception "..." 'Tolerância do produto "'||:PRODUTO_ID||'" não identificada. (Verificar tolerância no produto e na família)';
        END
    END

    qtd_max = QUANTIDADE + TOLERANCIA_QUANTIDADE_MAIOR;
    qtd_min = QUANTIDADE - TOLERANCIA_QUANTIDADE_MENOR;

    if(qtd_min < 0)then
    begin
        qtd_min = 0;
    end

    RETURN TOLERANCIA_TIPO||'#'||TOLERANCIA_QUANTIDADE_MAIOR||'#'||qtd_max||'#'||qtd_min;
end;

CREATE OR ALTER procedure spc_consumo_alocado_v2 (
    remessa_id integer,
    remessa_talao_id integer)
returns (
    produto_id integer,
    produto_descricao varchar(200),
    consumo_id integer,
    quantidade_produzida numeric(15,4),
    quantidade_projetada numeric(15,4),
    quantidade_utilizada numeric(15,4),
    quantidade_defeito numeric(15,4),
    quantidade_alocada numeric(15,4),
    quantidade_sobra numeric(15,4),
    tolerancia_tipo char(1),
    tolerancia_quantidade_maior numeric(15,4),
    tolerancia_quantidade_menor numeric(15,4),
    sobra_producao integer,
    sobra_consumo integer)
as
declare variable talao_id integer;
declare variable tolerancia varchar(500);
declare variable tolerancia_pro_qtd_maior numeric(15,4);
declare variable tolerancia_pro_qtd_menor numeric(15,4);
declare variable tolerancia_con_qtd_maior numeric(15,4);
declare variable tolerancia_con_qtd_menor numeric(15,4);
declare variable tolerancia_tipo_pro varchar(10);
declare variable tolerancia_tipo_con varchar(10);
declare variable fator_unidade numeric(15,4);
declare variable gp_id integer;
declare variable perfil varchar(10);
BEGIN
    FOR
        SELECT
            X.TALAO_ID,
            X.PRODUTO_ID,
            X.PRODUTO_DESCRICAO,
            X.CONSUMO_ID,
            X.GP_ID,
            X.PERFIL,
            SUM(x.QUANTIDADE_DEFEITO) as QUANTIDADE_DEFEITO,
            SUM(X.QUANTIDADE) QUANTIDADE_PROJETADA,
            max(x.fator_unidade) as fator_unidade,
            SUM(x.QTD_PROD) as QTD_PROD,
            round((SUM(x.QTD_PROD) + SUM(x.QUANTIDADE_DEFEITO)) * max(x.fator_unidade),4) as QUANTIDADE_UTILIZADA,
        
            coalesce((SELECT SUM(V.QUANTIDADE)
               FROM TBREMESSA_TALAO_VINCULO V
              WHERE V.TALAO_ID = X.TALAO_ID
                AND V.PRODUTO_ID = X.PRODUTO_ID),0) QUANTIDADE_ALOCADA
        from(
            SELECT
                T.ID TALAO_ID,
                C.PRODUTO_ID,
                P.DESCRICAO PRODUTO_DESCRICAO,
                C.QUANTIDADE,
                c.quantidade_saldo,
                c.fator_unidade,
        
                iif( c.remessa_talao_detalhe_id > 0,
                   coalesce((select sum(d.quantidade_producao_tmp) from vwremessa_talao_detalhe d where d.id = c.remessa_talao_detalhe_id),0),
                   coalesce((select sum(d.quantidade_producao_tmp) from vwremessa_talao_detalhe d where d.remessa_id = c.remessa_id and d.remessa_talao_id = c.remessa_talao_id),0)
                ) as QTD_PROD,

                iif( c.remessa_talao_detalhe_id > 0,

                    COALESCE((SELECT SUM(a.QUANTIDADE)
                       FROM TBDEFEITO_TRANSACAO_ITEM A, vwremessa_talao_detalhe d, TBSAC_DEFEITO B
                      WHERE A.DEFEITO_ID        = B.CODIGO
                        AND A.REMESSA           = d.remessa_id
                        and d.id                = c.remessa_talao_detalhe_id
                        AND A.REMESSA_CONTROLE  = d.id),0),

                    COALESCE((SELECT SUM(a.QUANTIDADE)
                       FROM TBDEFEITO_TRANSACAO_ITEM A, vwremessa_talao_detalhe d, TBSAC_DEFEITO B
                      WHERE A.DEFEITO_ID        = B.CODIGO
                        AND A.REMESSA           = d.remessa_id
                        and d.remessa_id        = c.remessa_id
                        and d.remessa_talao_id  = c.remessa_talao_id
                        AND A.REMESSA_CONTROLE  = d.id),0)

                ) as  QUANTIDADE_DEFEITO,
        
                (SELECT MAX(C1.ID)
                   FROM VWREMESSA_CONSUMO C1
                  WHERE C1.REMESSA_ID = C.REMESSA_ID
                    AND C1.REMESSA_TALAO_ID = C.REMESSA_TALAO_ID
                    AND C1.PRODUTO_ID = C.PRODUTO_ID) CONSUMO_ID,

                t.gp_id,
                u.perfil

            FROM
                VWREMESSA_TALAO T,
                TBPRODUTO P,
                VWREMESSA_CONSUMO C,
                tbup u
        
            WHERE
                T.REMESSA_ID        = C.REMESSA_ID
            AND T.REMESSA_TALAO_ID  = C.REMESSA_TALAO_ID
            AND P.CODIGO            = C.PRODUTO_ID
            AND C.REMESSA_ID        = :REMESSA_ID
            AND C.REMESSA_TALAO_ID  = :REMESSA_TALAO_ID
            AND u.id                = t.up_id
        ) X
        
        GROUP BY 1,2,3,4,5,6
        
    INTO
        :TALAO_ID,
        :PRODUTO_ID,
        :PRODUTO_DESCRICAO,
        :CONSUMO_ID,
        :GP_ID,
        :PERFIL,
        :QUANTIDADE_DEFEITO,
        :QUANTIDADE_PROJETADA,
        :FATOR_UNIDADE,
        :QUANTIDADE_PRODUZIDA,
        :QUANTIDADE_UTILIZADA,
        :QUANTIDADE_ALOCADA
    DO
    BEGIN

        QUANTIDADE_SOBRA = COALESCE(QUANTIDADE_ALOCADA - QUANTIDADE_UTILIZADA,0);

        IF(QUANTIDADE_SOBRA <> 0)THEN
        BEGIN
            TOLERANCIA  = FN_TOLERANCIA_PRODUTO(:PRODUTO_ID, :GP_ID, :PERFIL);
    
            TOLERANCIA_PRO_QTD_MAIOR = fn_json_v3(:TOLERANCIA, 'TOLERANCIA_PRO_QTD_MAIOR' );
            TOLERANCIA_PRO_QTD_MENOR = fn_json_v3(:TOLERANCIA, 'TOLERANCIA_PRO_QTD_MENOR' );
            TOLERANCIA_TIPO_PRO      = fn_json_v3(:TOLERANCIA, 'TOLERANCIA_TIPO_PRO'      );
            TOLERANCIA_CON_QTD_MAIOR = fn_json_v3(:TOLERANCIA, 'TOLERANCIA_CON_QTD_MAIOR' );
            TOLERANCIA_CON_QTD_MENOR = fn_json_v3(:TOLERANCIA, 'TOLERANCIA_CON_QTD_MENOR' );
            TOLERANCIA_TIPO_CON      = fn_json_v3(:TOLERANCIA, 'TOLERANCIA_TIPO_CON'      );
            SOBRA_PRODUCAO           = fn_json_v3(:TOLERANCIA, 'SOBRA_PRODUCAO'           );
            SOBRA_CONSUMO            = fn_json_v3(:TOLERANCIA, 'SOBRA_CONSUMO'            );
    
            IF(TOLERANCIA_TIPO_CON = 'Q')THEN
            BEGIN
                :TOLERANCIA_QUANTIDADE_MAIOR = TOLERANCIA_CON_QTD_MAIOR;
                :TOLERANCIA_QUANTIDADE_MENOR = TOLERANCIA_CON_QTD_MENOR;
                :TOLERANCIA_TIPO = 'Q';

                IF( (TOLERANCIA_CON_QTD_MAIOR       >= QUANTIDADE_SOBRA AND QUANTIDADE_SOBRA > 0) or
                   ((TOLERANCIA_CON_QTD_MENOR * -1) <= QUANTIDADE_SOBRA AND QUANTIDADE_SOBRA < 0))THEN
                BEGIN
                    QUANTIDADE_SOBRA = 0;
                END
            END ELSE
            BEGIN
                IF(TOLERANCIA_TIPO_CON = 'P')THEN
                BEGIN
                    :TOLERANCIA_QUANTIDADE_MAIOR = (QUANTIDADE_PROJETADA * (TOLERANCIA_CON_QTD_MAIOR / 100.0000));
                    :TOLERANCIA_QUANTIDADE_MENOR = (QUANTIDADE_PROJETADA * (TOLERANCIA_CON_QTD_MENOR / 100.0000));
                    :TOLERANCIA_TIPO = 'P';

                    IF( ( TOLERANCIA_QUANTIDADE_MAIOR       >= QUANTIDADE_SOBRA AND QUANTIDADE_SOBRA > 0) or
                       (( TOLERANCIA_QUANTIDADE_MENOR * -1) <= QUANTIDADE_SOBRA AND QUANTIDADE_SOBRA < 0))THEN
                    BEGIN
                        QUANTIDADE_SOBRA = 0;
                    END
                END ELSE
                BEGIN
                    exception "..." 'Tolerância do produto "'||:PRODUTO_ID||' - '||:PRODUTO_DESCRICAO||'" não identificada. (Verificar tolerância no produto e na família)';
                END
            END

        END

        if(QUANTIDADE_PRODUZIDA = 0)then
        begin
            QUANTIDADE_SOBRA = 0;
        end

        IF ( QUANTIDADE_SOBRA <= 0 ) THEN
        BEGIN
            UPDATE VWREMESSA_CONSUMO C SET C.QUANTIDADE_SOBRA = 0 WHERE C.ID = :CONSUMO_ID;
        END ELSE
        BEGIN
           if(SOBRA_CONSUMO = 0)then
           begin
               exception "..." 'O produto "'||:PRODUTO_ID||' - '||:PRODUTO_DESCRICAO||'" não permite sobra de consumo.';
           end
        END

        SUSPEND;
    END
END;

CREATE OR ALTER trigger ttbremessa_consumo_b1u for tbremessa_consumo
active before update position 1
AS
declare variable UMAlternativo VarChar(3);
declare variable PRODUTO_DESCRICAO VARCHAR(150);   
declare variable PRODUTO_INVENTARIO VARCHAR(150);

declare variable qtd_kg Numeric(15,4);
declare variable qtd_ml Numeric(15,4);
declare variable QUANTIDADE_SOBRA NUMERIC(15,4);

declare variable talao_id integer;
declare variable produto_id integer;
declare variable gp_id integer;
declare variable perfil varchar(10);
declare variable quantidade_projetada numeric(15,4);
declare variable fator_unidade numeric(15,4);
declare variable quantidade_produzida numeric(15,4);
declare variable quantidade_utilizada numeric(15,4);
declare variable quantidade_alocada numeric(15,4);
declare variable QUANTIDADE_DEFEITO numeric(15,4);

declare variable tolerancia varchar(500);
declare variable tolerancia_pro_qtd_maior numeric(15,4);
declare variable tolerancia_pro_qtd_menor numeric(15,4);
declare variable tolerancia_con_qtd_maior numeric(15,4);
declare variable tolerancia_con_qtd_menor numeric(15,4);
declare variable tolerancia_tipo_pro varchar(10);
declare variable tolerancia_tipo_con varchar(10);
declare variable tolerancia_tipo varchar(10);
declare variable tolerancia_quantidade_maior numeric(15,4);
declare variable tolerancia_quantidade_menor numeric(15,4);
declare variable sobra_producao integer;
declare variable sobra_consumo integer;
declare variable um varchar(10);
declare variable QTD_MAX numeric(15,4);
declare variable QTD_MIN numeric(15,4);
declare variable QTD numeric(15,4);
declare variable QTD_ALOC numeric(15,4);
Begin

    if (NEW.CONFERENCIA = '1' AND New.Quantidade_Conferencia <> Old.Quantidade_Conferencia and New.Quantidade_Conferencia > Old.Quantidade_Conferencia) then
    begin

        if(coalesce(new.liberar_tolerancia,0) = 0)then
        begin
            SELECT FIRST 1
                   P.DESCRICAO,
                   P.INVENTARIO
              FROM TBPRODUTO P
             WHERE P.CODIGO = NEW.PRODUTO_ID
             INTO
                PRODUTO_DESCRICAO,
                PRODUTO_INVENTARIO
             ;
    
            QUANTIDADE_SOBRA = 0;
    
            UMAlternativo = Coalesce((Select First 1 F.UnidadeMedida_Alternativo From TbFamilia F, TbProduto P Where F.Codigo = P.Familia_Codigo and P.Codigo = New.Produto_Id),'');
            qtd_ml        = (New.Quantidade_Conferencia_ML + coalesce(new.quantidade_sobra,0));
            qtd_kg        = (New.quantidade_conferencia    + coalesce(new.quantidade_sobra,0));
            um            = Coalesce((Select First 1 F.unidademedida_sigla From TbFamilia F, TbProduto P Where F.Codigo = P.Familia_Codigo and P.Codigo = New.Produto_Id),'');
    
            select
                TALAO_ID,
                PRODUTO_ID,
                GP_ID,
                PERFIL,
                QUANTIDADE_PROJETADA,
                FATOR_UNIDADE,
                QUANTIDADE_PRODUZIDA,
                QUANTIDADE_UTILIZADA,
                QUANTIDADE_ALOCADA,
                QUANTIDADE_DEFEITO
            from SPC_DADOS_CONSUMO(new.id) into
                :TALAO_ID,
                :PRODUTO_ID,
                :GP_ID,
                :PERFIL,
                :QUANTIDADE_PROJETADA,
                :FATOR_UNIDADE,
                :QUANTIDADE_PRODUZIDA,
                :QUANTIDADE_UTILIZADA,
                :QUANTIDADE_ALOCADA,
                :QUANTIDADE_DEFEITO;
    
            TOLERANCIA  = FN_TOLERANCIA_PRODUTO(NEW.PRODUTO_ID, :GP_ID, :PERFIL);
        
            TOLERANCIA_PRO_QTD_MAIOR = fn_json_v3(:TOLERANCIA, 'TOLERANCIA_PRO_QTD_MAIOR' );
            TOLERANCIA_PRO_QTD_MENOR = fn_json_v3(:TOLERANCIA, 'TOLERANCIA_PRO_QTD_MENOR' );
            TOLERANCIA_TIPO_PRO      = fn_json_v3(:TOLERANCIA, 'TOLERANCIA_TIPO_PRO'      );
            TOLERANCIA_CON_QTD_MAIOR = fn_json_v3(:TOLERANCIA, 'TOLERANCIA_CON_QTD_MAIOR' );
            TOLERANCIA_CON_QTD_MENOR = fn_json_v3(:TOLERANCIA, 'TOLERANCIA_CON_QTD_MENOR' );
            TOLERANCIA_TIPO_CON      = fn_json_v3(:TOLERANCIA, 'TOLERANCIA_TIPO_CON'      );
            SOBRA_PRODUCAO           = fn_json_v3(:TOLERANCIA, 'SOBRA_PRODUCAO'           );
            SOBRA_CONSUMO            = fn_json_v3(:TOLERANCIA, 'SOBRA_CONSUMO'            );
    
            IF(TOLERANCIA_TIPO_CON = 'Q')THEN
            BEGIN
                :TOLERANCIA_QUANTIDADE_MAIOR = TOLERANCIA_CON_QTD_MAIOR;
                :TOLERANCIA_QUANTIDADE_MENOR = TOLERANCIA_CON_QTD_MENOR;
                :TOLERANCIA_TIPO = 'Q';
            END ELSE
            BEGIN
                IF(TOLERANCIA_TIPO_CON = 'P')THEN
                BEGIN
                    :TOLERANCIA_QUANTIDADE_MAIOR = (QUANTIDADE_PROJETADA * (TOLERANCIA_CON_QTD_MAIOR / 100.0000));
                    :TOLERANCIA_QUANTIDADE_MENOR = (QUANTIDADE_PROJETADA * (TOLERANCIA_CON_QTD_MENOR / 100.0000));
                    :TOLERANCIA_TIPO = 'P';
                END ELSE
                BEGIN
                    exception "..." 'Tolerância do produto "'||:PRODUTO_ID||' - '||:PRODUTO_DESCRICAO||'" não identificada. (Verificar tolerância no produto e na família)';
                END
            END
    
            /*
            if (Char_Length(:UMAlternativo) > 0 and New.Quantidade_Conferencia_ML > 0) then
            begin
                QTD_MAX     = (New.Consumo_Ml + QUANTIDADE_SOBRA + :TOLERANCIA_QUANTIDADE_MAIOR);
                QTD_MIN     = (New.Consumo_Ml + QUANTIDADE_SOBRA - :TOLERANCIA_QUANTIDADE_MENOR);
                QTD         = (New.Consumo_Ml + QUANTIDADE_SOBRA);
                QTD_ALOC    = New.Quantidade_Conferencia_ML;
            end else
            begin
            */
    
            QTD_MAX     = (New.Consumo_Kg + QUANTIDADE_SOBRA + :TOLERANCIA_QUANTIDADE_MAIOR);
            QTD_MIN     = (New.Consumo_Kg + QUANTIDADE_SOBRA - :TOLERANCIA_QUANTIDADE_MENOR);
            QTD         = (New.Consumo_Kg + QUANTIDADE_SOBRA);
            QTD_ALOC    = New.quantidade_conferencia;
    
            um = ' '||lower(um)||'';
    
            if(not (:QUANTIDADE_UTILIZADA between QTD_MIN and QTD_MAX))then
            begin
                 Exception "..." 'QUANTIDADE DE CONSUMO INFORMADA FORA DA TOLERANCIA PERMITIDA "' || PRODUTO_DESCRICAO || '"! PROJECAO: '|| QTD ||um||' CONSUMO: '||QUANTIDADE_UTILIZADA||um||' TOLERANCIA (MAIS): '||TOLERANCIA_QUANTIDADE_MAIOR||um||' TOLERANCIA (MENOS): '||TOLERANCIA_QUANTIDADE_MENOR||um||' ID: ' || NEW.ID || ' . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .';
            end
    
            if(not (:QUANTIDADE_UTILIZADA between (QTD_ALOC - :TOLERANCIA_QUANTIDADE_MENOR) and (QTD_ALOC + :TOLERANCIA_QUANTIDADE_MAIOR)) )then
            begin
                 Exception "..." 'QUANTIDADE DE CONSUMO NÃO PODE SER MAIOR DO QUE O ALOCADO "' || PRODUTO_DESCRICAO || '"! PROJECAO: '|| QTD ||um||' CONSUMO: '||:QUANTIDADE_UTILIZADA||um||' ALOCADO: '||:QTD_ALOC||um||' TOLERANCIA (MAIS): '||TOLERANCIA_QUANTIDADE_MAIOR||um||' TOLERANCIA (MENOS): '||TOLERANCIA_QUANTIDADE_MENOR||um||' ID: ' || NEW.ID || ' . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .';
            end
    
            if(new.quantidade_sobra > 0 and SOBRA_CONSUMO = 0)then
            begin
                Exception "..." 'O PRODUTO "' || PRODUTO_DESCRICAO || '" NÃO PERMITE SOBRA DE CONSUMO. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .';
            end
    
            if(:QUANTIDADE_PRODUZIDA > 0 and SOBRA_PRODUCAO = 0)then
            begin
                Exception "..." 'O PRODUTO "' || PRODUTO_DESCRICAO || '" NÃO PERMITE SOBRA DE PRODUÇÃO. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .';
            end
    
            if (Char_Length(:UMAlternativo) > 0 and New.Quantidade_Conferencia_ML > 0) then
            begin
                QTD_MAX     = (New.Consumo_Ml + :TOLERANCIA_QUANTIDADE_MAIOR);
                QTD_MIN     = (New.Consumo_Ml - :TOLERANCIA_QUANTIDADE_MENOR);
                QTD         = New.Consumo_Ml;
                QTD_ALOC    = New.Quantidade_Conferencia_ML;
                um          = ' '||lower(UMAlternativo)||'';
            end
    
            if(not (:QTD_ALOC between QTD_MIN and QTD_MAX))then
            begin
                 Exception "..." 'QUANTIDADE PRODUZIDA FORA DA TOLERANCIA PERMITIDA "' || PRODUTO_DESCRICAO || '"! PROJECAO: '|| QTD ||um||' PRODUZIDO: '||QTD_ALOC||um||' TOLERANCIA (MAIS): '||TOLERANCIA_QUANTIDADE_MAIOR||um||' TOLERANCIA (MENOS): '||TOLERANCIA_QUANTIDADE_MENOR||um||' ID: ' || NEW.ID || ' . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .';
            end
    
            /*
            if (Char_Length(:UMAlternativo) > 0 and New.Quantidade_Conferencia_ML > 0 AND PRODUTO_INVENTARIO = '1' ) then
            begin
    
            if (((New.Quantidade_Conferencia_ML) > (New.Consumo_Ml + QUANTIDADE_SOBRA + :TOLERANCIA_QUANTIDADE_MAIOR)) or ((New.Quantidade_Conferencia_ML) < (New.Consumo_Ml + QUANTIDADE_SOBRA - :TOLERANCIA_QUANTIDADE_MENOR))) then
                begin
                Exception "..." 'QUANTIDADE DE CONSUMO INFORMADA FORA DA TOLERANCIA PERMITIDA "' || PRODUTO_DESCRICAO || '"! PROJECAO: '||New.Consumo_Ml||' CONSUMO: '||New.Quantidade_Conferencia_Ml||' TOLERANCIA (MAIS): '||TOLERANCIA_QUANTIDADE_MAIOR||' TOLERANCIA (MENOS): '||TOLERANCIA_QUANTIDADE_MENOR||' SOBRA: '||QUANTIDADE_SOBRA||' ID: ' || NEW.ID || ' . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .';
                End
            end else
            Begin
            if (((New.quantidade_conferencia) > (New.Consumo_Kg + QUANTIDADE_SOBRA + :TOLERANCIA_QUANTIDADE_MAIOR)) or ((New.quantidade_conferencia) < (New.Consumo_Kg + QUANTIDADE_SOBRA - :TOLERANCIA_QUANTIDADE_MENOR)))  then
                begin
                Exception "..." 'QUANTIDADE DE CONSUMO INFORMADA FORA DA TOLERANCIA PERMITIDA "' || PRODUTO_DESCRICAO || '"! PROJECAO: '||New.Consumo_Kg||' CONSUMO: '||New.Quantidade_Conferencia||' TOLERANCIA (MAIS): '||TOLERANCIA_QUANTIDADE_MAIOR||' TOLERANCIA (MENOS): '||TOLERANCIA_QUANTIDADE_MENOR||' SOBRA: '||QUANTIDADE_SOBRA||' ID: ' || NEW.ID || ' . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .';
                End
            End
            */
    
            /*
            tTolerancia = '';
    
            -- Verifica tolerancia por produto
            For
            Select First 1 PF.Tolerancia_Qtd, PF.Tolerancia_Perc, PF.Tolerancia_Tipo
              From TbProduto_Ficha PF Where PF.produto_codigo = New.Produto_Id and PF.Tolerancia_tipo in ('Q','P')
              Into :qTolerancia, :pTolerancia, :tTolerancia
             Do
             Begin
    
                UMAlternativo = Coalesce((Select First 1 F.UnidadeMedida_Alternativo From TbFamilia F, TbProduto P Where F.Codigo = P.Familia_Codigo and P.Codigo = New.Produto_Id),'');
                if (tTolerancia = 'Q') then --Tolerancia em Quantidade
                    Begin
                        qtd_ml = (New.Quantidade_Conferencia_ML + coalesce(new.quantidade_sobra,0));
                        qtd_kg = (New.quantidade_conferencia    + coalesce(new.quantidade_sobra,0));
    
                        if (Char_Length(:UMAlternativo) > 0 and New.Quantidade_Conferencia_ML > 0 AND PRODUTO_INVENTARIO = '1' ) then
                            begin
    
                            if (((New.Quantidade_Conferencia_ML) > (New.Consumo_Ml + QUANTIDADE_SOBRA + :qTolerancia)) or ((New.Quantidade_Conferencia_ML) < (New.Consumo_Ml + QUANTIDADE_SOBRA - :qTolerancia))) then
                                begin
                                Exception "..." 'QUANTIDADE INFORMADA FORA DA TOLERANCIA PERMITIDA PARA O PRODUTO "' || PRODUTO_DESCRICAO || '"! PROJECAO: '||New.Consumo_Ml||' CONSUMO: '||New.Quantidade_Conferencia_Ml||' TOLERANCIA: '||qTolerancia||' SOBRA: '||QUANTIDADE_SOBRA||' ID: ' || NEW.ID || ' . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .';
                                End
                            end else
                            Begin
                            if (((New.quantidade_conferencia) > (New.Consumo_Kg + QUANTIDADE_SOBRA + :qTolerancia)) or ((New.quantidade_conferencia) < (New.Consumo_Kg + QUANTIDADE_SOBRA - :qTolerancia)))  then
                                begin
                                Exception "..." 'QUANTIDADE INFORMADA FORA DA TOLERANCIA PERMITIDA PARA O PRODUTO "' || PRODUTO_DESCRICAO || '"! PROJECAO: '||New.Consumo_Kg||' CONSUMO: '||New.Quantidade_Conferencia||' TOLERANCIA: '||qTolerancia||' SOBRA: '||QUANTIDADE_SOBRA||' ID: ' || NEW.ID || ' . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .';
                                End
                            End
                    End else
                if (tTolerancia = 'P') then --Tolerancia em Percentual
                    Begin
    
                        if (Char_Length(:UMAlternativo) > 0 and New.Quantidade_Conferencia_ML > 0 AND PRODUTO_INVENTARIO = '1') then
                            begin
                            if (((New.Quantidade_Conferencia_ML) > (New.Consumo_Ml + ((New.Consumo_Ml + QUANTIDADE_SOBRA) * (:pTolerancia/100.0000)))) or
                                ((New.Quantidade_Conferencia_ML) < (New.Consumo_Ml - ((New.Consumo_Ml + QUANTIDADE_SOBRA) * (:pTolerancia/100.0000))))) then
                                begin
                                Exception "..." 'QUANTIDADE INFORMADA FORA DO PERCENTUAL DE TOLERANCIA PERMITIDO PARA O PRODUTO "' || PRODUTO_DESCRICAO || '"! PROJECAO: '||New.Consumo_Ml||' CONSUMO: '||New.Quantidade_Conferencia_Ml||' TOLERANCIA: '||pTolerancia||'% SOBRA: '||coalesce(new.quantidade_sobra,0)|| 'ID ' || NEW.ID ||' . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .';
                                End
                            end else
                            Begin
                            if (((New.quantidade_conferencia) > (New.Consumo_Kg + ((New.Consumo_Kg + QUANTIDADE_SOBRA) * (:pTolerancia/100.0000)))) or
                                ((New.quantidade_conferencia) < (New.Consumo_Kg - ((New.Consumo_Kg + QUANTIDADE_SOBRA) * (:pTolerancia/100.0000))))) then
                                begin
                                Exception "..." 'QUANTIDADE INFORMADA FORA DO PERCENTUAL DE TOLERANCIA PERMITIDO PARA O PRODUTO "' || PRODUTO_DESCRICAO || '"! PROJECAO: '||New.Consumo_Kg||' CONSUMO: '||New.Quantidade_Conferencia||' TOLERANCIA: '||pTolerancia||'% SOBRA: '||coalesce(new.quantidade_sobra,0)|| 'ID ' || NEW.ID || ' . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .';
                                End
                            End
                    End
             End
    
                if (tTolerancia = '') then
                    begin
            
                        -- Verifica tolerancia por familia
                        For
                        Select First 1 F.Tolerancia_Qtd, F.Tolerancia_Perc, F.Tolerancia_Tipo, F.UnidadeMedida_Alternativo
                          From TbFamilia F, TbProduto P Where F.Codigo = P.Familia_Codigo and P.Codigo = New.Produto_Id and F.Tolerancia_tipo in ('Q','P')
                          Into :qTolerancia, :pTolerancia, :tTolerancia, :UMAlternativo
                         Do
                         Begin
            
                            if (tTolerancia = 'Q') then --Tolerancia em Quantidade
                                Begin
                                if (Char_Length(:UMAlternativo) > 0 and New.Quantidade_Conferencia_ML > 0 AND PRODUTO_INVENTARIO = '1') then
                                    begin
                                    if ((New.Quantidade_Conferencia_ML > (New.Consumo_Ml + QUANTIDADE_SOBRA + :qTolerancia)) or (New.Quantidade_Conferencia_ML < (New.Consumo_Ml + QUANTIDADE_SOBRA - :qTolerancia))) then
                                        begin
                                        Exception "..." 'QUANTIDADE INFORMADA FORA DA TOLERANCIA DA FAMILIA PERMITIDA PARA O PRODUTO "' || PRODUTO_DESCRICAO || '"! PROJECAO: '||New.Consumo_Ml||' CONSUMO: '||New.Quantidade_Conferencia_Ml||' TOLERANCIA: '||qTolerancia||'. ID:' || NEW.ID;
                                        End
                                    end else
                                    Begin
                                    if ((New.Quantidade_Conferencia > (New.Consumo_Kg + QUANTIDADE_SOBRA + :qTolerancia)) or (New.Quantidade_Conferencia < (New.Consumo_Kg + QUANTIDADE_SOBRA - :qTolerancia)))  then
                                        begin
                                        Exception "..." 'QUANTIDADE INFORMADA FORA DA TOLERANCIA DA FAMILIA PERMITIDA PARA O PRODUTO "' || PRODUTO_DESCRICAO || '"! PROJECAO: '||New.Consumo_Kg||' CONSUMO: '||New.Quantidade_Conferencia||' TOLERANCIA: '||qTolerancia||'. ID:' || NEW.ID;
                                        End
                                    End
                                End else
                            if (tTolerancia = 'P') then --Tolerancia em Percentual
                                Begin
                                if (Char_Length(:UMAlternativo) > 0 and New.Quantidade_Conferencia_ML > 0 AND PRODUTO_INVENTARIO = '1') then
                                    begin
                                    if ((New.Quantidade_Conferencia_Ml > (New.Consumo_Ml + ((New.Consumo_Ml + QUANTIDADE_SOBRA) * (:pTolerancia/100.0000)))) or
                                        (New.Quantidade_Conferencia_Ml < (New.Consumo_Ml - ((New.Consumo_Ml + QUANTIDADE_SOBRA) * (:pTolerancia/100.0000))))) then
                                        begin
                                        Exception "..." 'QUANTIDADE INFORMADA FORA DO PERCENTUAL DE TOLERANCIA DA FAMILIA PERMITIDO PARA O PRODUTO "' || PRODUTO_DESCRICAO || '"! PROJECAO: '||New.Consumo_Ml||' CONSUMO: '||New.Quantidade_Conferencia_Ml||' TOLERANCIA: '||pTolerancia||'%. ID:' || NEW.ID;
                                        End
                                    end else
                                    Begin
                                    if ((New.Quantidade_Conferencia > (New.Consumo_Kg + ((New.Consumo_Kg + QUANTIDADE_SOBRA) * (:pTolerancia/100.0000)))) or
                                        (New.Quantidade_Conferencia < (New.Consumo_Kg - ((New.Consumo_Kg + QUANTIDADE_SOBRA) * (:pTolerancia/100.0000))))) then
                                        begin
                                        Exception "..." 'QUANTIDADE INFORMADA FORA DO PERCENTUAL DE TOLERANCIA DA FAMILIA PERMITIDO PARA O PRODUTO "' || PRODUTO_DESCRICAO || '"! PROJECAO: '||New.Consumo_Kg||' CONSUMO: '||New.Quantidade_Conferencia||' TOLERANCIA: '||pTolerancia||'%. ID:' || NEW.ID;
                                        End
                                    End
                                End
                         End
                    End
    
                    */
        End
    end
End;

CREATE OR ALTER procedure spc_dados_consumo (
    consumo_id integer)
returns (
    talao_id integer,
    produto_id integer,
    produto_descricao varchar(100),
    gp_id integer,
    perfil varchar(10),
    quantidade_projetada numeric(15,4),
    fator_unidade numeric(15,4),
    quantidade_produzida numeric(15,4),
    quantidade_defeito numeric(15,4),
    quantidade_utilizada numeric(15,4),
    quantidade_alocada numeric(15,4))
as
begin

    SELECT
            X.TALAO_ID,
            X.PRODUTO_ID,
            X.PRODUTO_DESCRICAO,
            X.CONSUMO_ID,
            X.GP_ID,
            X.PERFIL,
            sum(x.QUANTIDADE_DEFEITO) as QUANTIDADE_DEFEITO,
            SUM(X.QUANTIDADE) QUANTIDADE_PROJETADA,
            max(x.fator_unidade) as fator_unidade,
            SUM(x.QTD_PROD) as QTD_PROD,
            round((SUM(x.QTD_PROD) + sum(x.QUANTIDADE_DEFEITO)) * max(x.fator_unidade),4) as QUANTIDADE_UTILIZADA,
            coalesce((SELECT SUM(V.QUANTIDADE)
               FROM TBREMESSA_TALAO_VINCULO V
              WHERE V.TALAO_ID = X.TALAO_ID
                AND V.PRODUTO_ID = X.PRODUTO_ID),0) QUANTIDADE_ALOCADA
        from(
            SELECT
                T.ID TALAO_ID,
                C.PRODUTO_ID,
                P.DESCRICAO PRODUTO_DESCRICAO,
                C.QUANTIDADE,
        
                c.quantidade_saldo,
                c.fator_unidade,
                c.fator_unidade_altern,
        
                iif( c.remessa_talao_detalhe_id > 0,
                   coalesce((select sum(d.quantidade_producao_tmp) from vwremessa_talao_detalhe d where d.id = c.remessa_talao_detalhe_id),0),
                   coalesce((select sum(d.quantidade_producao_tmp) from vwremessa_talao_detalhe d where d.remessa_id = c.remessa_id and d.remessa_talao_id = c.remessa_talao_id),0)
                ) as QTD_PROD,

                iif( c.remessa_talao_detalhe_id > 0,

                    COALESCE((SELECT SUM(a.QUANTIDADE)
                       FROM TBDEFEITO_TRANSACAO_ITEM A, vwremessa_talao_detalhe d, TBSAC_DEFEITO B
                      WHERE A.DEFEITO_ID        = B.CODIGO
                        AND A.REMESSA           = d.remessa_id
                        and d.id                = c.remessa_talao_detalhe_id
                        AND A.REMESSA_CONTROLE  = d.id),0),

                    COALESCE((SELECT SUM(a.QUANTIDADE)
                       FROM TBDEFEITO_TRANSACAO_ITEM A, vwremessa_talao_detalhe d, TBSAC_DEFEITO B
                      WHERE A.DEFEITO_ID        = B.CODIGO
                        AND A.REMESSA           = d.remessa_id
                        and d.remessa_id        = c.remessa_id
                        and d.remessa_talao_id  = c.remessa_talao_id
                        AND A.REMESSA_CONTROLE  = d.id),0)

                ) as  QUANTIDADE_DEFEITO,
        
                (SELECT MAX(C1.ID)
                   FROM VWREMESSA_CONSUMO C1
                  WHERE C1.REMESSA_ID = C.REMESSA_ID
                    AND C1.REMESSA_TALAO_ID = C.REMESSA_TALAO_ID
                    AND C1.PRODUTO_ID = C.PRODUTO_ID) CONSUMO_ID,

                t.gp_id,
                u.perfil
            FROM
                VWREMESSA_TALAO T,
                TBPRODUTO P,
                VWREMESSA_CONSUMO C,
                tbup u
        
            WHERE
                T.REMESSA_ID        = C.REMESSA_ID
            AND T.REMESSA_TALAO_ID  = C.REMESSA_TALAO_ID
            AND P.CODIGO            = C.PRODUTO_ID
            and c.id                = :CONSUMO_ID
            AND u.id                = t.up_id
        ) X
        
        GROUP BY 1,2,3,4,5,6
        
    INTO
        :TALAO_ID,
        :PRODUTO_ID,
        :PRODUTO_DESCRICAO,
        :CONSUMO_ID,
        :GP_ID,
        :PERFIL,
        :QUANTIDADE_DEFEITO,
        :QUANTIDADE_PROJETADA,
        :FATOR_UNIDADE,
        :QUANTIDADE_PRODUZIDA,
        :QUANTIDADE_UTILIZADA,
        :QUANTIDADE_ALOCADA;

  suspend;
end;
