create or replace PROCEDURE ATUALIZA_QTDE_RECEITA (
P_CDFILIAL IN FILIAL.CDFILIAL%TYPE,
P_CDSERVFILI IN SERVICO.CDSERVFILI%TYPE,
P_CDFILAUXPRAT IN PRATO.CDFILAUXPRAT%TYPE,
P_CDPRATO IN PRATO.CDPRATO%TYPE,
P_CDPRODUTO IN PRODUTO.CDPRODUTO%TYPE,
P_QTDE IN FLOAT,
P_TIPORECE IN VARCHAR2
) 
IS 
    V_QTDE_BRUTA FLOAT(126);
    V_QTDE_ESTOQUE FLOAT(126);
    V_QTDE_BASECALC_NUTR FLOAT(126);
    V_QTDE_NUTRIENTE FLOAT(126);
    V_GANHO_COC FLOAT(126);
    V_PERDA_LIMP FLOAT(126);
    V_PERDA_DEGELO FLOAT(126);
    V_PERCENT_NUTR FLOAT(126);
    V_SGUNIDADE VARCHAR2(10);
    V_SGUNIDADE_PROD VARCHAR2(10);
    V_QTDE_TEMP FLOAT(126);

    /*FUNCAO PARA RETORNAR O FATOR DE CONVERSAO DO PRODUTO E JA CALCULAR A QTDE REQUERIDA DE ESTOQUE*/
    FUNCTION PROC_RETORNA_CONVERSAO (
       P_CDPRODUTO     IN  PRODUTO.CDPRODUTO%TYPE,
       P_SGUNIDADEORI  IN  PRODUTO.SGUNIDADE%TYPE,
       P_SGUNIDADEDEST IN  PRODUTO.SGUNIDADE%TYPE,
       P_QTDE_BRUTA    IN FLOAT
    ) RETURN FLOAT AS
       V_OPERACAO VARCHAR2(1);
       V_VRFATOCONVES FLOAT(126);
       V_FATOR VARCHAR2(1);
    BEGIN
       /*SE NAO MUDOU A UNIDADE DA RECEITA RETORNA A QTDE BRUTA*/ 
       IF P_SGUNIDADEORI IS NULL OR P_SGUNIDADEORI = P_SGUNIDADEDEST THEN
          RETURN P_QTDE_BRUTA;
       END IF;
       BEGIN
          SELECT TO_NUMBER(C.VRFATOCONVES) AS VRFTCONVER, RPAD('/', 1, ' ') AS IDTIPOPE, 'S' AS FATOR
            INTO V_VRFATOCONVES, V_OPERACAO, V_FATOR
            FROM CONVPRODUTO C LEFT JOIN PRODUTO P ON P.CDPRODUTO = C.CDPRODUTO
           WHERE (C.CDPRODUTO = P_CDPRODUTO) AND
                 (P.SGUNIDADE = P_SGUNIDADEORI) AND 
                 (C.SGUNIDADE = P_SGUNIDADEDEST);
       EXCEPTION
          WHEN NO_DATA_FOUND THEN
            V_FATOR := 'N';
       END;
       IF V_FATOR = 'N' THEN          
          BEGIN
             SELECT TO_NUMBER(C.VRFATOCONVES) AS VRFTCONVER, RPAD('*', 1, ' ') AS IDTIPOPE, 'S' AS FATOR
               INTO V_VRFATOCONVES, V_OPERACAO, V_FATOR
               FROM CONVPRODUTO C LEFT JOIN PRODUTO P ON P.CDPRODUTO = C.CDPRODUTO
              WHERE (C.CDPRODUTO = P_CDPRODUTO) AND
                    (P.SGUNIDADE = P_SGUNIDADEDEST) AND
                    (C.SGUNIDADE = P_SGUNIDADEORI);
          EXCEPTION
             WHEN NO_DATA_FOUND THEN
               V_FATOR := 'N';
          END;
       END IF;
       IF V_FATOR = 'N' THEN          
          BEGIN
             SELECT TO_NUMBER(VRFTCONVER)  AS VRFTCONVER, RPAD(IDTIPOPE, 1, ' ') AS IDTIPOPE, 'S' AS FATOR
               INTO V_VRFATOCONVES, V_OPERACAO, V_FATOR
               FROM CONVUNID 
              WHERE (SGUNIDPARA = P_SGUNIDADEDEST) AND
                    (SGUNIDDE = P_SGUNIDADEORI);
          EXCEPTION
             WHEN NO_DATA_FOUND THEN
               V_FATOR := 'N';
          END;
       END IF;
       IF V_FATOR = 'N' THEN          
          BEGIN
             SELECT TO_NUMBER(VRFTCONVER)  AS VRFTCONVER, CASE WHEN IDTIPOPE = '*' THEN RPAD('/', 1, ' ') ELSE RPAD(IDTIPOPE, 1, ' ') END AS IDTIPOPE, 'S' AS FATOR
               INTO V_VRFATOCONVES, V_OPERACAO, V_FATOR
               FROM CONVUNID
              WHERE (SGUNIDPARA = P_SGUNIDADEORI) AND
                    (SGUNIDDE = P_SGUNIDADEDEST);
          EXCEPTION
             WHEN NO_DATA_FOUND THEN
               V_FATOR := 'N';
          END;
       END IF;
       /*SE NAO ENCONTROU FATOR DE CONVERSAO OU RETORNA 0 RETORNA 0*/
       IF V_FATOR = 'N' OR V_VRFATOCONVES = 0 THEN
          RETURN 0;
       END IF;
       RETURN CASE WHEN V_OPERACAO = '*' THEN ROUND(P_QTDE_BRUTA * V_VRFATOCONVES,5) ELSE ROUND(P_QTDE_BRUTA / V_VRFATOCONVES,5) END;
    END;    
BEGIN
    /*PREENCHE VARIAVEIS PARA CALCULOS*/
    IF P_TIPORECE = 'P' THEN 
       SELECT R.VRPEFATCORPR, R.VRPEFATCOCPR, R.VRPERCDEGELO, R.SGUNIDADE, P.SGUNIDADE, R.VRPEFATNUTPR
         INTO V_PERDA_LIMP, V_GANHO_COC, V_PERDA_DEGELO, V_SGUNIDADE, V_SGUNIDADE_PROD, V_PERCENT_NUTR
         FROM RECEPADR R INNER JOIN PRODUTO P ON P.CDPRODUTO = R.CDPRODUTO
        WHERE R.CDFILAUXPRAT = P_CDFILAUXPRAT AND R.CDPRATO = P_CDPRATO AND R.CDPRODUTO = P_CDPRODUTO; 
    END IF;
    IF P_TIPORECE = 'L' THEN 
       SELECT R.VRPEFATCORLO, R.VRPEFATCOCLO, R.VRPERCDEGELO, R.SGUNIDADE, P.SGUNIDADE, R.VRPEFATNUTLO
         INTO V_PERDA_LIMP, V_GANHO_COC, V_PERDA_DEGELO, V_SGUNIDADE, V_SGUNIDADE_PROD, V_PERCENT_NUTR
         FROM RECEFILI R INNER JOIN PRODUTO P ON P.CDPRODUTO = R.CDPRODUTO
        WHERE R.CDFILIAL = P_CDFILIAL AND R.CDFILAUXPRAT = P_CDFILAUXPRAT AND R.CDPRATO = P_CDPRATO AND R.CDPRODUTO = P_CDPRODUTO; 
    END IF;    
    IF P_TIPORECE = 'S' THEN 
       SELECT R.VRPEFATCORSE, R.VRPEFATCOCSE, R.VRPERCDEGELO, R.SGUNIDADE, P.SGUNIDADE, R.VRPEFATNUTSE
         INTO V_PERDA_LIMP, V_GANHO_COC, V_PERDA_DEGELO, V_SGUNIDADE, V_SGUNIDADE_PROD, V_PERCENT_NUTR
         FROM RECESERV R INNER JOIN PRODUTO P ON P.CDPRODUTO = R.CDPRODUTO
        WHERE R.CDFILIAL = P_CDFILIAL AND R.CDSERVFILI = P_CDSERVFILI AND R.CDFILAUXPRAT = P_CDFILAUXPRAT AND R.CDPRATO = P_CDPRATO AND R.CDPRODUTO = P_CDPRODUTO; 
    END IF;        
    V_GANHO_COC    := NVL(V_GANHO_COC,0);
    V_PERDA_LIMP   := NVL(V_PERDA_LIMP,0);
    V_PERDA_DEGELO := NVL(V_PERDA_DEGELO, 0);
    V_PERCENT_NUTR := NVL(V_PERCENT_NUTR,100);
    
    /*CALCULA QTDE BRUTA = QTDE LIQUIDA - GANHO DE COCCAO + PERDA DE LIMPEZA + PERDA DE DEGELO*/
    V_QTDE_TEMP  := P_QTDE / (1 + (V_GANHO_COC/100));
    V_QTDE_TEMP  := V_QTDE_TEMP / (1 - (V_PERDA_LIMP/100));
    V_QTDE_BRUTA := ROUND(V_QTDE_TEMP  / (1 - (V_PERDA_DEGELO/100)),5); 

    /*QUANTIDADE PARA REQUISICAO AO ESTOQUE E A QUANTIDADE BRUTA CORRIGIDA PELO FATOR DE CONVERSAO*/
    V_QTDE_ESTOQUE := PROC_RETORNA_CONVERSAO(P_CDPRODUTO,V_SGUNIDADE,V_SGUNIDADE_PROD,V_QTDE_BRUTA);
    
    /*BASE DE CALCULO PARA APROVEITAMENTO DE NUTRIENTE*/
    V_QTDE_TEMP := V_QTDE_ESTOQUE * (1 - (V_PERDA_DEGELO/100));
    V_QTDE_BASECALC_NUTR := V_QTDE_TEMP * (1 - (V_PERDA_LIMP/100));
    /*QTDE DO NUTRIENTE CALCULADO PELA BASE DE CALCULO DO NUTRIENTE X PERCENTUAL DE APROVEITAMENTO*/
    V_QTDE_NUTRIENTE := ROUND((V_QTDE_BASECALC_NUTR * V_PERCENT_NUTR)/100,5);
    
    /*ATUALIZA RECEITA RECALCULADA*/
    IF P_TIPORECE = 'P' THEN
       UPDATE RECEPADR
          SET QTPRODPRAT = P_QTDE, /*QUANTIDADE LIQUIDA INFORMADA*/
              QTUNIDESTPR = V_QTDE_ESTOQUE, /*QUANTIDADE REQUERIDA NA UNIDADE DE ESTOQUE*/
              QTBRUTAPR = V_QTDE_ESTOQUE, /*QUANTIDADE REQUERIDA NA UNIDADE DE ESTOQUE*/
              QTCALCNUTRPR = V_QTDE_NUTRIENTE, /*QUANTIDADE DO PRODUTO PARA BASE DE CALCULO DE APROVEITAMENTO DE NUTRIENTES E NA UNIDADE DE ESTOQUE*/
              QTBRUTAPRUNR = V_QTDE_BRUTA /*QUANTIDADE BRUTA DO PRODUTO NA UNIDADE DA RECEITA*/
         WHERE CDFILAUXPRAT = P_CDFILAUXPRAT AND CDPRATO = P_CDPRATO AND CDPRODUTO = P_CDPRODUTO;
    END IF;
    IF P_TIPORECE = 'L' THEN
       UPDATE RECEFILI
          SET QTPRODRECLOC = P_QTDE, /*QUANTIDADE LIQUIDA INFORMADA*/
              QTUNIDESTLO = V_QTDE_ESTOQUE, /*QUANTIDADE REQUERIDA NA UNIDADE DE ESTOQUE*/
              QTBRUTALO = V_QTDE_ESTOQUE, /*QUANTIDADE REQUERIDA NA UNIDADE DE ESTOQUE*/
              QTCALCNUTRLO = V_QTDE_NUTRIENTE, /*QUANTIDADE DO PRODUTO PARA BASE DE CALCULO DE APROVEITAMENTO DE NUTRIENTES E NA UNIDADE DE ESTOQUE*/
              QTBRUTALOUNR = V_QTDE_BRUTA /*QUANTIDADE BRUTA DO PRODUTO NA UNIDADE DA RECEITA*/
         WHERE CDFILIAL = P_CDFILIAL AND CDFILAUXPRAT = P_CDFILAUXPRAT AND CDPRATO = P_CDPRATO AND CDPRODUTO = P_CDPRODUTO;
    END IF;
    IF P_TIPORECE = 'S' THEN
       UPDATE RECESERV
          SET QTPRODRECSER = P_QTDE, /*QUANTIDADE LIQUIDA INFORMADA*/
              QTUNIDESTSE = V_QTDE_ESTOQUE, /*QUANTIDADE REQUERIDA NA UNIDADE DE ESTOQUE*/
              QTBRUTASE = V_QTDE_ESTOQUE, /*QUANTIDADE REQUERIDA NA UNIDADE DE ESTOQUE*/
              QTCALCNUTRSE = V_QTDE_NUTRIENTE, /*QUANTIDADE DO PRODUTO PARA BASE DE CALCULO DE APROVEITAMENTO DE NUTRIENTES E NA UNIDADE DE ESTOQUE*/
              QTBRUTASEUNR = V_QTDE_BRUTA /*QUANTIDADE BRUTA DO PRODUTO NA UNIDADE DA RECEITA*/
         WHERE CDFILIAL = P_CDFILIAL AND CDSERVFILI = P_CDSERVFILI AND CDFILAUXPRAT = P_CDFILAUXPRAT AND CDPRATO = P_CDPRATO AND CDPRODUTO = P_CDPRODUTO;
    END IF;    
    COMMIT;
END;
/
