CREATE OR REPLACE PROCEDURE GERA_CKLIST_REQUISICAOINF
(
P_CDFILIAL IN VARCHAR2,
P_NRCKLISTPRODINF IN NUMBER,
P_CDOPERADOR IN VARCHAR2,
P_NRORG IN NUMBER,
P_NRLISTAERROS OUT NUMBER
)
AS
   V_IDSITUACAO VARCHAR2(30);
   V_CDCKLISTPRODINF VARCHAR2(20);
   V_NRREQUISICAOINF NUMBER;
   V_DTPRODUCAO DATE;   
   V_CDSETOR VARCHAR2(4);
   V_NRTURNO VARCHAR2(2);   
   V_SEQ VARCHAR2(20);   
   V_NRPRODREQUISICAOINF NUMBER;   
   V_NRORDEM NUMBER;
   V_NRTIPONEGOCIOINF NUMBER;   
   V_QUANTIDADE_PRODUTOS NUMBER;

   PROCEDURE INCLUI_PRODUTOS_RECEITA(P_CDRECEITA IN VARCHAR2, P_QTRECEITA IN FLOAT)
   AS
      V_CDSETOR_REC VARCHAR2(4);
      V_CODRECEITA VARCHAR2(20);
      V_DSRECEITA VARCHAR2(200);
      V_IDRECFLEXIVEL VARCHAR2(1);
      V_NRCATEGORIAPROD NUMBER;
      V_NRSUBCATEGORIAPROD NUMBER;
      V_NRVARIACAOREC NUMBER;
      V_QTRENDIMENTOREC FLOAT;
      V_VRFATOR FLOAT;
      V_NRSEQUTILRECFLEX NUMBER;
      V_QTPRODUTO FLOAT;
      V_DIVISOR FLOAT;
      V_NUM_PROD NUMBER;
   BEGIN
      DADOS_RECEITA_PRODUCAO( P_CDFILIAL, P_CDRECEITA,  V_DTPRODUCAO, P_CDOPERADOR,  P_NRORG,
                              'R', NULL,  P_NRLISTAERROS,  V_NRORDEM, V_CODRECEITA,  V_DSRECEITA,  V_IDRECFLEXIVEL, 
                              V_NRVARIACAOREC, V_QTRENDIMENTOREC,  V_NRSEQUTILRECFLEX);

      DETERMINA_PRODUCAO_RECEITA(P_CDFILIAL, P_CDRECEITA, V_NRTIPONEGOCIOINF, P_NRORG, V_CDSETOR_REC, V_NRCATEGORIAPROD, V_NRSUBCATEGORIAPROD);


      IF V_CDSETOR_REC = V_CDSETOR THEN
         V_VRFATOR := CASE WHEN V_QTRENDIMENTOREC = 0 THEN 0 ELSE P_QTRECEITA/V_QTRENDIMENTOREC END;

         FOR CUR_PROD IN
         (
         SELECT PR.CDPRODUTO, NVL(PR.QTPRODREC, 0.00) AS QTPRODREC, PT.VRPEFATOCORR
           FROM PRORECEITAM PR
                INNER JOIN PRODUTO PT ON PT.CDPRODUTO = PR.CDPRODUTO
          WHERE PR.CDRECEITA = P_CDRECEITA
            AND PR.NRVARIACAOREC = V_NRVARIACAOREC
            AND (V_IDRECFLEXIVEL = 'N' OR
                 (COMPOSICAO_EM_PRODUCAO(P_CDFILIAL, P_CDRECEITA, P_NRORG, V_NRSEQUTILRECFLEX, PR.CDPRODUTO, 'P') = 'S') OR
                 (V_NRSEQUTILRECFLEX IS NULL AND PR.IDPREFERENCIA = 'S')
                )
         ) LOOP
            
            V_DIVISOR := 1 - NVL(CUR_PROD.VRPEFATOCORR, 0)/100;
            IF V_DIVISOR = 0 THEN
               V_QTPRODUTO := ROUND(V_VRFATOR * CUR_PROD.QTPRODREC, 3);
            ELSE
               /*Calcula quantidade do produto considerando a perda*/
               V_QTPRODUTO := ROUND(V_VRFATOR * CUR_PROD.QTPRODREC / V_DIVISOR, 3);
            END IF;
            /*Apenas produtos com quantidade maior que zero*/
            IF V_QTPRODUTO > 0 THEN            
               SELECT COUNT(*) INTO V_NUM_PROD FROM PRODREQUISICAOINF
               WHERE CDFILIAL = P_CDFILIAL
                 AND NRREQUISICAOINF = V_NRREQUISICAOINF
                 AND CDPRODUTO = CUR_PROD.CDPRODUTO
                 AND NRORG = P_NRORG;

               IF V_NUM_PROD = 0 THEN
                 /*Insere produto na requisicao*/
                 NOVO_CODIGO_NT('PRODREQUISICAOINF' || P_CDFILIAL, V_SEQ);
                 V_NRPRODREQUISICAOINF := TO_NUMBER(V_SEQ);

                 INSERT INTO PRODREQUISICAOINF
                 (CDFILIAL, NRPRODREQUISICAOINF, NRREQUISICAOINF, 
                 CDPRODUTO, QTPRODUTOCALC, QTPRODUTOINF, DSJUSTIFICATIVA,
                 NRORG, NRORGINCLUSAO, NRORGULTATU,  
                 DTINCLUSAO, DTULTATU,  
                 CDOPERINCLUSAO, CDOPERULTATU, IDATIVO)
                 VALUES
                 (P_CDFILIAL, V_NRPRODREQUISICAOINF, V_NRREQUISICAOINF,
                 CUR_PROD.CDPRODUTO, V_QTPRODUTO, V_QTPRODUTO, NULL,
                 P_NRORG, P_NRORG, P_NRORG,  
                 SYSDATE, SYSDATE,  
                 P_CDOPERADOR, P_CDOPERADOR, 'S');
               ELSE
                 UPDATE PRODREQUISICAOINF
                 SET QTPRODUTOCALC = QTPRODUTOCALC + V_QTPRODUTO,
                     NRORGULTATU = P_NRORG,
                     CDOPERULTATU = P_CDOPERADOR,
                     DTULTATU = SYSDATE
                 WHERE CDFILIAL = P_CDFILIAL
                   AND NRREQUISICAOINF = V_NRREQUISICAOINF
                   AND CDPRODUTO = CUR_PROD.CDPRODUTO
                   AND NRORG = P_NRORG;
               END IF;
               
            END IF;
         END LOOP;
         FOR CUR_SUB IN
         (
         SELECT SR.CDSUBRECEITA, NVL(SR.QTRENDSUBREC, 0.00) AS QTRENDSUBREC
           FROM SUBRECEITAM SR                
          WHERE SR.CDRECEITA = P_CDRECEITA
            AND SR.NRVARIACAOREC = V_NRVARIACAOREC
            AND ( V_IDRECFLEXIVEL = 'N' OR
                  (COMPOSICAO_EM_PRODUCAO(P_CDFILIAL, P_CDRECEITA, P_NRORG, V_NRSEQUTILRECFLEX, SR.CDSUBRECEITA, 'S') = 'S') OR
                  (V_NRSEQUTILRECFLEX IS NULL AND SR.IDPREFERENCIA = 'S') )
         ) LOOP
            INCLUI_PRODUTOS_RECEITA(CUR_SUB.CDSUBRECEITA, CUR_SUB.QTRENDSUBREC);
         END LOOP;
      END IF;
   END;

BEGIN
   V_NRORDEM := 1;
   
   /*Busca informacoes do checklist*/
   SELECT MAX(CDCKLISTPRODINF), MAX(CDSETOR), MAX(NRTURNO), MAX(NRTIPONEGOCIOINF), MAX(IDSITUACAO), MAX(NRREQUISICAOINF), MAX(DTPRODUCAOINF)
     INTO V_CDCKLISTPRODINF, V_CDSETOR, V_NRTURNO, V_NRTIPONEGOCIOINF, V_IDSITUACAO, V_NRREQUISICAOINF, V_DTPRODUCAO
     FROM CKLISTPRODINF
    WHERE CDFILIAL = P_CDFILIAL
      AND NRCKLISTPRODINF = P_NRCKLISTPRODINF;

   IF V_CDCKLISTPRODINF IS NULL THEN
      RETURN;
   END IF;

   IF V_NRREQUISICAOINF IS NOT NULL THEN
      /*Requisicao ja gerada para o checklist $param[0]*/
      RAISE_APPLICATION_ERROR(-20501, 'APPERRMSGSTR' || 'APP-00157' || '$$' ||
                                       V_CDCKLISTPRODINF
                                       || 'APPERRMSGEND');
   END IF;

   IF V_IDSITUACAO IN ('PENDENTE', 'APROVADOMRP') THEN
      /*Operacao bloqueada. Checklist [CDCKLISTPRODINF] nao aprovado pela producao.*/
      RAISE_APPLICATION_ERROR(-20501, 'APPERRMSGSTR' || 'APP-00128' || '$$' || V_CDCKLISTPRODINF || 'APPERRMSGEND');
   END IF;

   /*Insere nova requisicao*/
   NOVO_CODIGO_NT('REQUISICAOINF' || P_CDFILIAL, V_SEQ);
   V_NRREQUISICAOINF := TO_NUMBER(V_SEQ);

   INSERT INTO REQUISICAOINF
   (CDFILIAL, NRREQUISICAOINF, DTREQUISICAOINF,  
   CDSETOR, NRTURNO,  
   IDSITUACAO, IDORIGEM,  
   NRORG, NRORGINCLUSAO, NRORGULTATU,  
   DTINCLUSAO, DTULTATU,  
   CDOPERINCLUSAO, CDOPERULTATU, IDATIVO)
   VALUES
   (P_CDFILIAL, V_NRREQUISICAOINF, V_DTPRODUCAO,
   V_CDSETOR, V_NRTURNO,  
   'PENDENTE', 'CKLISTPRODINF',
   P_NRORG, P_NRORG, P_NRORG,  
   SYSDATE, SYSDATE,  
   P_CDOPERADOR, P_CDOPERADOR, 'S');

   /*Percorre as receitas do checklist, incluindo os produtos correspondentes*/
   FOR CUR_REC IN
   (
   SELECT CDRECEITA, ROUND(QTRECEITAINF - QTRECEITAEST, 3) AS QTRECEITA
     FROM RECCKLISTPRODINF
    WHERE CDFILIAL = P_CDFILIAL
      AND NRCKLISTPRODINF = P_NRCKLISTPRODINF
   ) LOOP
      INCLUI_PRODUTOS_RECEITA(CUR_REC.CDRECEITA, CUR_REC.QTRECEITA);
   END LOOP;


   SELECT COUNT(1)
     INTO V_QUANTIDADE_PRODUTOS
     FROM PRODREQUISICAOINF
    WHERE CDFILIAL = P_CDFILIAL
      AND NRREQUISICAOINF = V_NRREQUISICAOINF;

   IF V_QUANTIDADE_PRODUTOS = 0 THEN
      /*Operacao bloqueada. Nao ha produtos para requisicao na composicao das receitas do checklist $param[0]*/
      RAISE_APPLICATION_ERROR(-20501, 'APPERRMSGSTR' || 'APP-00155' || '$$' ||
                                       V_CDCKLISTPRODINF
                                       || 'APPERRMSGEND');
   END IF;

   /*Vincula ao checklist a requisicao correspondente*/
   UPDATE CKLISTPRODINF
      SET NRREQUISICAOINF = V_NRREQUISICAOINF,
          NRORGULTATU = P_NRORG,
          CDOPERULTATU = P_CDOPERADOR,
          DTULTATU = SYSDATE
    WHERE CDFILIAL = P_CDFILIAL
      AND NRCKLISTPRODINF = P_NRCKLISTPRODINF;

END;
/