create or replace
PROCEDURE GERA_MRP_PRODUTO
   (P_CDFILIAL      IN FILIAL.CDFILIAL%TYPE,
    P_DTMRP         IN PROGPRODU.DTPROGPRODU%TYPE,
    P_CDPRODUTO     IN PRODUTO.CDPRODUTO%TYPE,
    P_IDPRODPROD    IN PRODUTO.IDPRODPROD%TYPE,
    P_DTENTPROD     IN PROGPRODU.DTENTPROD%TYPE,
    P_QTESTQINI     IN PROGPRODU.QTESTDIAPCP%TYPE,
    P_QTESTOQMIN    IN PROGPRODU.QTESTMINPCP%TYPE,
    P_QTPADPROCFAB  IN PROGPRODU.QTPADPRODPCP%TYPE,
    P_QTLOTEFABPCP  IN PROGPRODU.QTLOTEFABPCP%TYPE,
    P_QTVENDAPCP    IN PROGPRODU.QTVENDAPCP%TYPE,
    P_QTEMPRODUCAO  IN PROGPRODU.QTEMPRODUPCP%TYPE,
    P_DTINI         IN PROGPRODU.DTPERINIPCP%TYPE,
    P_DTFIN         IN PROGPRODU.DTPERFINPCP%TYPE,
    P_CDPRODINIPCP  IN PRODUTO.CDARVPROD%TYPE,
    P_CDPRODFINPCP  IN PRODUTO.CDARVPROD%TYPE,
    P_IDMRPPEDPREV  IN PROGPRODU.IDMRPPEDPREV%TYPE,
    P_IDESTOQUE     IN PROGPRODU.IDESTOQUEMRP%TYPE,
    P_IDCONSDEMA    IN PROGPRODU.IDCONSDEMA%TYPE,
    P_NRORDENAOP    IN CALEPRODMRP.NRORDENAOP%TYPE,
    P_NRORDENASUBOP IN CALEPRODMRP.NRORDENASUBOP%TYPE,
    P_CDPRODFINAL   IN PRODUTO.CDPRODUTO%TYPE ,
    P_DTENTPRODACAB IN ITEMPEDIDO.DTENTITPED%TYPE,
    P_NRORDEMPROD   IN FLOAT,
    P_QTANDPROD     IN PROGPRODU.QTRECPROGR%TYPE,
    P_QTTOTALPROD   IN PROGPRODU.QTRECPROGR%TYPE,
    P_IDSEMIACETAP  IN INSUMETAPA.IDSEMIACETAP%TYPE DEFAULT 'N',
    P_IDSUBOPINSU   IN INSUMETAPA.IDSUBOPINSU%TYPE DEFAULT 'N',
    P_IDGERSEMIACA  in VARCHAR2 DEFAULT 'A'
   )
IS
   V_QTAFABRICARR     DOUBLE PRECISION;
   V_CDPRODPROD       PRODUTO.CDPRODPROD%TYPE;
   V_VRFATOCONVPR     PRODUTO.VRFATOCONVPR%TYPE;
   V_CDPRODMRP        PRODUTO.CDPRODUTO%TYPE;
   V_QTEMPRODUPCP     PROGPRODU.QTEMPRODUPCP%TYPE;
   V_QTESTQINI        PROGPRODU.QTESTDIAPCP%TYPE;
   V_QTESTOQMIN       PROGPRODU.QTESTMINPCP%TYPE;
   V_QTPADPROCFAB     PROGPRODU.QTPADPRODPCP%TYPE;
   V_QTLOTEFABPCP     PROGPRODU.QTLOTEFABPCP%TYPE;
   V_CDPRODUTO        PRODUTO.CDPRODUTO%TYPE;
   V_QTESTOQUEPCP     PROGPRODU.QTESTOQUEPCP%TYPE;
   V_QTAFABRICPCP     PROGPRODU.QTAFABRICPCP%TYPE;
   V_QTVENDAPCP       PROGPRODU.QTVENDAPCP%TYPE;
   V_QTVENDADATA      PROGPRODU.QTVENDAPCP%TYPE;
   V_QTESTANT         PROGPRODU.QTESTOQUEPCP%TYPE; 
   V_QTHORASPROD      NUMBER; 
   V_DTENTSEMIAC      PROGPRODU.DTENTPROD%TYPE; 
   V_NRORDENAOP       CALEPRODMRP.NRORDENAOP%TYPE; 
   V_NRORDENASUBOP    CALEPRODMRP.NRORDENASUBOP%TYPE; 
   V_NRORDEMPROD      FLOAT; 
   V_IDGERAOPCONF     PARAMPRODMRP.IDGERAOPCONF%TYPE; 
   V_QTRECPROGR       PROGPRODU.QTRECPROGR%TYPE; 
   V_DTENTPROD        ITEMPEDIDO.DTENTITPED%TYPE; 
   V_QTAPRODPREOPDIA  PROGPRODU.QTRECPROGR%TYPE; 
   V_PRODUTOOP        PRODUTO.CDPRODUTO%TYPE; 
   V_ESTRESRANTE      PROGPRODU.QTRECPROGR%TYPE; 
   V_PROXDATA         FLOAT; 
   V_ESTOQUEPLAN      FLOAT; 
   V_PROD             PRODUTO.CDPRODUTO%TYPE; 
   V_ESTANTERIOR      FLOAT; 
   V_QTFABRICACALENDA FLOAT; 
   V_DTANTERIOR       DATE; 
   V_VRFABRICA        FLOAT; 
   V_QTESTOQMIN2      FLOAT; 
   V_QTPRIMDIAPROD    FLOAT;
   V_IDGERSEMIACA     VARCHAR2(1);
   V_IDVALIDACALE     VARCHAR2(1);
BEGIN 

   V_NRORDENAOP    := P_NRORDENAOP; 
   V_NRORDENASUBOP := P_NRORDENASUBOP; 
   IF NOT P_IDPRODPROD = 'S' THEN  

      SELECT MAX(CDPRODPROD), MAX(VRFATOCONVPR)
      INTO V_CDPRODPROD, V_VRFATOCONVPR
      FROM PRODUTO
      WHERE (CDPRODUTO = P_CDPRODUTO);

      IF NOT V_CDPRODPROD IS NULL THEN
         V_CDPRODMRP := V_CDPRODPROD;
         SELECT SUM(A.QTPRODUCAO)
         INTO V_QTEMPRODUPCP
         FROM (SELECT NVL(SUM(L.QTPRODLOTE), 0) AS QTPRODUCAO
               FROM LOTE L, PARAMPRODMRP P
               WHERE (L.CDFILIAL     = P_CDFILIAL)
                 AND (L.CDPRODUTO    = V_CDPRODMRP)
                 AND (L.IDSTPRODLOTE = '3')
                 AND (P.CDFILIAL = L.CDFILIAL)
                 AND (P.CDPRODUTO = L.CDPRODUTO)
                 AND (P.IDGERAOPCONF = 'S')
               UNION ALL
               SELECT NVL(SUM(QTAPRODPREOP),0) AS QTPRODUCAO
               FROM ORDPRODUCAO O, PARAMPRODMRP P
               WHERE (O.CDFILIAL     = P_CDFILIAL)
                 AND (O.CDPRODUTO    = V_CDPRODMRP)
                 AND (O.IDSITORDPROD = '1')
                 AND (O.IDCONFIRMAOP = 'S')
                 AND (P.CDFILIAL = O.CDFILIAL  )
                 AND (P.CDPRODUTO = O.CDPRODUTO)
                 AND (P.IDGERAOPCONF = 'S')
              ) A;

         SELECT MAX(QTPADPROCFAB), MAX(QTLOTEFABDIA)
         INTO V_QTPADPROCFAB, V_QTLOTEFABPCP
         FROM PROCFABRICA
         WHERE CDFILIAL     = P_CDFILIAL
           AND CDPRODUTO    = V_CDPRODMRP
           AND IDPROFABPADR = 'S';

         IF V_VRFATOCONVPR > 0 THEN
            V_QTEMPRODUPCP := (V_QTEMPRODUPCP / V_VRFATOCONVPR);
         END IF;
      END IF;
   ELSE
      V_CDPRODMRP    := P_CDPRODUTO;
      V_VRFATOCONVPR := 1;
      V_QTEMPRODUPCP := P_QTEMPRODUCAO;
      V_QTPADPROCFAB := P_QTPADPROCFAB;
      V_QTLOTEFABPCP := P_QTLOTEFABPCP;
   END IF;

   BEGIN
      SELECT IDGERAOPCONF
      INTO V_IDGERAOPCONF
      FROM PARAMPRODMRP
      WHERE CDFILIAL  = P_CDFILIAL
        AND CDPRODUTO = V_CDPRODMRP;
   EXCEPTION
      WHEN NO_DATA_FOUND THEN
         V_IDGERAOPCONF := 'N';
   END;


   IF NOT V_CDPRODMRP IS NULL THEN

      SELECT MAX(QTAFABRICARR)
      INTO V_VRFABRICA
      FROM PROGPRODU
      WHERE DTPROGPRODU = (SELECT MAX(DTPROGPRODU)
                           FROM PROGPRODU
                          )
        AND CDFILIAL  = P_CDFILIAL
        AND CDPRODUTO = V_CDPRODMRP;

       IF V_VRFABRICA > 0 THEN
         V_QTESTOQMIN2 := 0;
       ELSE
         V_QTESTOQMIN2 := P_QTESTOQMIN;
       END IF;
         V_QTESTOQMIN := P_QTESTOQMIN;
      
      SELECT MAX(CDPRODUTO), MAX(QTVENDAPCP)
      INTO V_CDPRODUTO, V_QTVENDADATA
      FROM PROGPRODU
      WHERE (CDFILIAL    = P_CDFILIAL)
        AND (DTPROGPRODU = P_DTMRP)
        AND (CDPRODUTO   = V_CDPRODMRP)
        AND (DTENTPROD   = TRUNC(P_DTENTPROD));

      IF (V_CDPRODUTO IS NULL) THEN

         SELECT MAX(CDPRODUTO)
         INTO V_CDPRODUTO
         FROM PROGPRODU
         WHERE (CDFILIAL    = P_CDFILIAL)
           AND (DTPROGPRODU = P_DTMRP)
           AND (CDPRODUTO   = V_CDPRODMRP);


         
         BEGIN
            SELECT SUM(QTESTOQUEPCP)+SUM(NVL(QTAFABRICARR,0))
            INTO V_QTPRIMDIAPROD
            FROM PROGPRODU
            WHERE (CDFILIAL    = P_CDFILIAL)
              AND (DTPROGPRODU = (select max(dtprogprodu)
                                  from PROGPRODU
                                 ))
              AND (CDPRODUTO   = P_CDPRODUTO)
              AND (DTENTPROD   < TRUNC(P_DTENTPROD)) ;
         EXCEPTION
            WHEN NO_DATA_FOUND THEN
               V_QTPRIMDIAPROD := 0;
         END;
         
         IF (V_QTPRIMDIAPROD = 0) OR (V_QTPRIMDIAPROD IS NULL) THEN
            V_CDPRODUTO := NULL;
         END IF;

         SELECT NVL(SUM(OP.QTAPRODPREOP), 0)
         INTO V_QTAPRODPREOPDIA
         FROM ORDPRODUCAO OP, PARAMPRODMRP P
         WHERE (OP.CDFILIAL     = P_CDFILIAL)
           AND (OP.CDPRODUTO    = P_CDPRODUTO)
           AND (TRUNC(OP.DTHRFIMPREOP) = TRUNC(P_DTENTPROD))
           AND (OP.IDSITORDPROD = '2')
           AND P.CDFILIAL = OP.CDFILIAL
           AND P.CDPRODUTO = OP.CDPRODUTO
           AND P.IDGERAOPCONF = 'S';

         IF P_IDSEMIACETAP = 'N' THEN

            V_PROD := P_CDPRODUTO;

            BEGIN
               SELECT NVL((QTAFABRICARR - QTAFABRICPCP),0), QTESTOQUEPCP
               INTO V_ESTOQUEPLAN, V_ESTANTERIOR
               FROM PROGPRODU
               WHERE TRUNC(DTENTPROD) = (SELECT MAX(TRUNC(DTENTPROD))
                                         FROM PROGPRODU
                                         WHERE TRUNC(DTENTPROD) < TRUNC(P_DTENTPROD)
                                           AND CDPRODUTO = V_PROD
                                           AND CDFILIAL = P_CDFILIAL
                                           AND dtprogprodu = (select max(dtprogprodu)
                                                              from PROGPRODU
                                                             ))
                 AND CDPRODUTO = V_PROD
                 AND CDFILIAL = P_CDFILIAL
                 AND dtprogprodu = (select max(dtprogprodu)
                                    from PROGPRODU
                                   );
            EXCEPTION
               WHEN NO_DATA_FOUND THEN
                  V_ESTOQUEPLAN := 0;
                  V_ESTANTERIOR := 0;
            END;

            IF V_ESTOQUEPLAN > 0 THEN

               UPDATE PROGPRODU
               SET QTESTOQUEPCP = QTAFABRICARR - QTAFABRICPCP
               WHERE CDFILIAL  = P_CDFILIAL
                 AND CDPRODUTO = V_PROD
                 AND dtprogprodu = (select max(dtprogprodu)
                                    from PROGPRODU
                                   )
                 AND TRUNC(DTENTPROD) = (SELECT MAX(TRUNC(DTENTPROD))
                                         FROM PROGPRODU
                                         WHERE TRUNC(DTENTPROD) < TRUNC(P_DTENTPROD)
                                           AND CDPRODUTO = V_PROD
                                           AND CDFILIAL = P_CDFILIAL
                                           AND dtprogprodu = (select max(dtprogprodu)
                                                              from PROGPRODU
                                                             )
                                        );


               IF (V_QTAFABRICPCP-V_ESTOQUEPLAN) > 0 THEN
                  V_QTAFABRICPCP := V_QTAFABRICPCP-V_ESTOQUEPLAN;
               END IF;
            END IF;
         END IF;

         
         IF (V_CDPRODUTO IS NULL) THEN

            IF (V_IDGERAOPCONF = 'N')THEN
               V_QTESTOQUEPCP := (P_QTESTQINI + V_QTEMPRODUPCP) - P_QTVENDAPCP;
            ELSE
               V_QTESTOQUEPCP := (P_QTESTQINI + V_QTEMPRODUPCP + V_QTAPRODPREOPDIA) - P_QTVENDAPCP;
            END IF;

            IF V_QTESTOQUEPCP < 0 THEN
               V_QTAFABRICPCP := ABS(V_QTESTOQUEPCP) + V_QTESTOQMIN;
            ELSE
               IF V_QTESTOQUEPCP < V_QTESTOQMIN THEN
                  V_QTAFABRICPCP := V_QTESTOQMIN - V_QTESTOQUEPCP;
               ELSE
                  V_QTAFABRICPCP := 0;
               END IF;
            END IF;
         ELSE
            SELECT MAX(P.QTESTOQUEPCP), MAX(P.QTAFABRICARR)
            INTO V_QTESTOQUEPCP, V_QTAFABRICARR
            FROM (SELECT MAX(DTENTPROD) AS DTENTPROD
                  FROM PROGPRODU
                  WHERE CDFILIAL    = P_CDFILIAL
                    AND DTPROGPRODU = P_DTMRP
                    AND CDPRODUTO   = V_CDPRODMRP
                 ) A,
                 PROGPRODU P
            WHERE P.CDFILIAL    = P_CDFILIAL
              AND P.DTPROGPRODU = P_DTMRP
              AND P.CDPRODUTO   = V_CDPRODMRP
              AND P.DTENTPROD   = A.DTENTPROD;

            IF (V_IDGERAOPCONF = 'S')THEN

               V_QTESTOQUEPCP := (V_QTESTOQUEPCP + V_QTAFABRICARR + V_QTAPRODPREOPDIA) - P_QTVENDAPCP;
            ELSE
               V_QTESTOQUEPCP := V_QTESTOQUEPCP - P_QTVENDAPCP;
            END IF;
            IF V_QTESTOQUEPCP < 0 THEN
               IF (V_IDGERAOPCONF = 'S')THEN
                  V_QTAFABRICPCP := ABS(V_QTESTOQUEPCP) + V_QTESTOQMIN;
               ELSE
                  V_QTAFABRICPCP := ABS(V_QTESTOQUEPCP) + V_QTESTOQMIN2;
               END IF;
            ELSE
               IF V_QTESTOQUEPCP < V_QTESTOQMIN THEN
                  V_QTAFABRICPCP := V_QTESTOQMIN - V_QTESTOQUEPCP;
               ELSE
                  V_QTAFABRICPCP := 0;
               END IF;
            END IF;
         END IF;


         IF (P_IDESTOQUE = 'S') OR (V_IDGERAOPCONF = 'S')THEN
            V_QTESTQINI := (P_QTESTQINI    * V_VRFATOCONVPR);
            IF (V_IDGERAOPCONF = 'S') THEN
               V_QTESTQINI := V_QTESTQINI +(V_QTEMPRODUPCP * V_VRFATOCONVPR);
            END IF;
            V_QTESTOQUEPCP := (V_QTESTOQUEPCP * V_VRFATOCONVPR);
            V_QTAFABRICPCP := (V_QTAFABRICPCP * V_VRFATOCONVPR);
         ELSE
            V_QTESTQINI    := 0;
            V_QTESTOQUEPCP := 0;
            V_QTAFABRICPCP := (P_QTVENDAPCP * V_VRFATOCONVPR);
         END IF;
         V_QTESTOQMIN   := (V_QTESTOQMIN   * V_VRFATOCONVPR);
         V_QTVENDAPCP   := (P_QTVENDAPCP   * V_VRFATOCONVPR);
         V_QTEMPRODUPCP := (V_QTEMPRODUPCP * V_VRFATOCONVPR);

         IF V_QTESTOQUEPCP < 0 THEN
            V_QTESTOQUEPCP := 0;
         END IF; 

         INSERT INTO PROGPRODU
            (CDFILIAL,     DTPROGPRODU,  CDPRODUTO,    DTENTPROD,   QTESTDIAPCP,
             QTESTMINPCP,  QTPADPRODPCP, QTLOTEFABPCP, QTVENDAPCP,  QTESTOQUEPCP,
             QTEMPRODUPCP, QTAFABRICPCP, DTPERINIPCP,  DTPERFINPCP, CDPRODINIPCP,
             CDPRODFINPCP, IDMRPPEDPREV, IDCONSDEMA, DTENTPRODACAB, IDESTOQUEMRP,
             QTRECPROGR, QTTOTALPRODU, IDSEMIACABADO)
         VALUES
            (P_CDFILIAL,   P_DTMRP,        P_CDPRODUTO,    TRUNC(P_DTENTPROD), V_QTESTQINI,
             P_QTESTOQMIN, V_QTPADPROCFAB, V_QTLOTEFABPCP, V_QTVENDAPCP,   V_QTESTOQUEPCP,
             V_QTEMPRODUPCP, V_QTAFABRICPCP, P_DTINI,      P_DTFIN,        P_CDPRODINIPCP,
             P_CDPRODFINPCP, P_IDMRPPEDPREV, P_IDCONSDEMA, P_DTENTPRODACAB, P_IDESTOQUE,
             V_QTAPRODPREOPDIA, NVL(P_QTTOTALPROD,0), P_IDSEMIACETAP);
      ELSE
         V_QTVENDAPCP := V_QTVENDADATA + P_QTVENDAPCP;

         IF(P_IDESTOQUE = 'S')OR( V_IDGERAOPCONF = 'S' )THEN
            SELECT MAX(P.QTESTOQUEPCP)
            INTO V_QTESTANT
            FROM (SELECT MAX(DTENTPROD) AS DTENTPROD
                  FROM PROGPRODU
                  WHERE CDFILIAL    = P_CDFILIAL
                    AND DTPROGPRODU = P_DTMRP
                    AND CDPRODUTO   = V_CDPRODMRP
                    AND DTENTPROD   <= TRUNC(P_DTENTPROD)
                  ) A,
                  PROGPRODU P
            WHERE P.CDFILIAL    = P_CDFILIAL
              AND P.DTPROGPRODU = P_DTMRP
              AND P.CDPRODUTO   = V_CDPRODMRP
              AND P.DTENTPROD   = A.DTENTPROD;

            V_QTESTOQUEPCP := NVL(V_QTESTANT,0) - P_QTVENDAPCP;

            IF V_QTESTOQUEPCP <= 0 THEN
               V_QTAFABRICPCP :=  ABS(V_QTESTOQUEPCP) + V_QTESTOQMIN2;
            ELSE
               IF V_QTESTOQUEPCP >= V_QTESTOQMIN THEN
                  V_QTAFABRICPCP := 0;
               ELSE
                  V_QTAFABRICPCP := V_QTESTOQMIN2 - V_QTESTOQUEPCP;
               END IF;
            END IF;
         ELSE
            V_QTESTOQUEPCP := 0;
            V_QTAFABRICPCP := P_QTVENDAPCP;
         END IF;

         IF V_QTESTOQUEPCP < 0 THEN
            V_QTESTOQUEPCP := 0;
         END IF; 

         UPDATE PROGPRODU
         SET QTVENDAPCP   = V_QTVENDAPCP,
             QTESTOQUEPCP = V_QTESTOQUEPCP,
             QTAFABRICPCP = QTAFABRICPCP + V_QTAFABRICPCP
         WHERE (CDFILIAL    = P_CDFILIAL)
           AND (DTPROGPRODU = P_DTMRP)
           AND (CDPRODUTO   = V_CDPRODMRP)
           AND (DTENTPROD   = TRUNC(P_DTENTPROD));
      END IF;

      IF V_QTAFABRICPCP > 0 THEN
         IF P_IDGERSEMIACA IN ('P','A') THEN
            V_IDVALIDACALE := 'S';
         ELSE
            V_IDVALIDACALE := 'N';
         END IF;



         V_NRORDEMPROD := GERA_CALE_PRODU(P_CDFILIAL, P_DTMRP, P_IDESTOQUE, V_CDPRODMRP, P_DTENTPROD, P_NRORDENAOP, P_NRORDENASUBOP, P_IDSUBOPINSU, P_CDPRODFINAL, V_QTAFABRICPCP, P_NRORDEMPROD, P_QTESTQINI,V_IDVALIDACALE, P_IDSEMIACETAP);
      END IF;

      IF P_IDSEMIACETAP = 'S' THEN
         BEGIN
            SELECT NVL((QTAFABRICARR - QTAFABRICPCP),0), QTESTOQUEPCP
            INTO V_ESTOQUEPLAN, V_ESTANTERIOR
            FROM PROGPRODU
            WHERE CDPRODUTO = P_CDPRODUTO
              AND CDFILIAL = P_CDFILIAL
              AND dtprogprodu = (SELECT MAX(dtprogprodu)
                                 FROM PROGPRODU
                                 WHERE CDPRODUTO = P_CDPRODUTO
                                   AND CDFILIAL = P_CDFILIAL
                                   AND TRUNC(DTPROGPRODU) =  TRUNC(P_DTMRP)
                                   AND TRUNC(DTENTPROD) = TRUNC(P_DTENTPROD)
                                )
              AND DTENTPROD = (SELECT MAX(DTENTPROD)
                                 FROM PROGPRODU
                                 WHERE CDPRODUTO = P_CDPRODUTO
                                   AND CDFILIAL = P_CDFILIAL
                                   AND TRUNC(DTPROGPRODU) =  TRUNC(P_DTMRP)
                                   AND TRUNC(DTENTPROD) = TRUNC(P_DTENTPROD)
                                )
              AND ROWNUM = 1;
         EXCEPTION
            WHEN NO_DATA_FOUND THEN
               V_ESTOQUEPLAN := 0;
               V_ESTANTERIOR := 0;
         END;

         IF V_ESTOQUEPLAN > 0 THEN
            UPDATE PROGPRODU
            SET QTESTOQUEPCP = V_ESTOQUEPLAN
            WHERE CDFILIAL  = P_CDFILIAL
              AND CDPRODUTO = P_CDPRODUTO
              AND dtprogprodu = (SELECT MAX(dtprogprodu)
                                 FROM PROGPRODU
                                 WHERE CDPRODUTO = P_CDPRODUTO
                                   AND CDFILIAL = P_CDFILIAL
                                   AND TRUNC(DTPROGPRODU) =  TRUNC(P_DTMRP)
                                   AND TRUNC(DTENTPROD) = TRUNC(P_DTENTPROD)
                                )
              AND DTENTPROD = (SELECT MAX(DTENTPROD)
                                 FROM PROGPRODU
                                 WHERE CDPRODUTO = P_CDPRODUTO
                                   AND CDFILIAL = P_CDFILIAL
                                   AND TRUNC(DTPROGPRODU) =  TRUNC(P_DTMRP)
                                   AND TRUNC(DTENTPROD) = TRUNC(P_DTENTPROD)
                                );
         END IF;
      END IF;
      IF V_QTAFABRICPCP > 0 THEN
         FOR C_SEMIACABADO IN
            (SELECT SEMI.CDPRODINSUMO, SEMI.IDSUBOPINSU, SEMI.NRORDENAOP, SEMI.NRORDENASUBOP,
                    SEMI.IDPRODPROD, SEMI.QTESTOQMIN, SEMI.QTPRODUCAO, SEMI.QTDEESTO,
                    SEMI.QTPADPROCFAB, SEMI.QTLOTEFABDIA, SEMI.DTCONCPROMRP, SEMI.QTSEMITOTAL,
                    SEMI.IDSEMIACETAP,  SEMI.IDTPPROPOPF, SEMI.IDTPARREDPF, SEMI.QUANTIDADE
             FROM (SELECT INS.CDPRODINSUMO, INS.IDSUBOPINSU, CL.NRORDENAOP, CL.NRORDENASUBOP,
                          PROD2.IDPRODPROD, NVL(PRF.QTESTOSEGU, 0) AS QTESTOQMIN,
                          NVL(SUM(PR.QTPRODLOTE), 0) AS QTPRODUCAO,
                          DECODE(P_IDESTOQUE, 'S', NVL(P.QTESTDIACON, 0),0) AS QTDEESTO,
                          NVL(PF2.QTPADPROCFAB, 0) AS QTPADPROCFAB,
                          NVL(PF2.QTLOTEFABDIA, 0) AS QTLOTEFABDIA,
                          DTCONCPROMRP, QTSEMITOTAL, INS.IDSEMIACETAP, PF2.IDTPPROPOPF,
                          PF2.IDTPARREDPF, NVL(SUM(QTPREVI_MATPRIMA(P_CDFILIAL, V_CDPRODMRP, INS.CDPROCFABRIC, INS.CDETAPAPROD, INS.CDPRODINSUMO, CL.QTAFABRICMRP)), 0) AS QUANTIDADE
                   FROM ESTOSEGU PRF, PRODUTO PROD, PRODUTO PROD2, PROCFABRICA PF, PROCFABRICA PF2,
                        INSUMETAPA INS, POSESTCONS P, CALEPRODMRP CL,
                        (SELECT CDPRODUTO, IDGERAOPCONF, SUM(QTPRODLOTE) AS QTPRODLOTE, SUM(QTSEMITOTAL) AS QTSEMITOTAL
                         FROM (SELECT O.CDPRODUTO, P.IDGERAOPCONF, NVL(SUM(QTAPRODPREOP),0) AS QTPRODLOTE,
                                      NVL(SUM(QTAPRODPREOP),0) AS QTSEMITOTAL
                               FROM ORDPRODUCAO O, PARAMPRODMRP P
                               WHERE (O.CDFILIAL     = P_CDFILIAL)
                                 AND (O.IDSITORDPROD = '1')
                                 AND (O.IDCONFIRMAOP = 'S')
                                 AND (P.CDFILIAL  = O.CDFILIAL )
                                 AND (P.CDPRODUTO = O.CDPRODUTO)
                                 AND (P.IDGERAOPCONF = 'S')
                               GROUP BY O.CDPRODUTO, P.IDGERAOPCONF
                               UNION
                               SELECT O.CDPRODUTO, P.IDGERAOPCONF, 0 AS QTPRODLOTE, NVL(SUM(QTAPRODPREOP),0) AS QTSEMITOTAL
                               FROM ORDPRODUCAO O, PARAMPRODMRP P
                               WHERE (O.CDFILIAL     = P_CDFILIAL)
                                 AND (O.IDSITORDPROD = '2')
                                 AND (O.IDCONFIRMAOP = 'S')
                                 AND (P.CDFILIAL  = O.CDFILIAL )
                                 AND (P.CDPRODUTO = O.CDPRODUTO)
                                 AND (P.IDGERAOPCONF = 'S')
                               GROUP BY O.CDPRODUTO, P.IDGERAOPCONF
                              )
                         GROUP BY CDPRODUTO, IDGERAOPCONF
                        ) PR
                   WHERE (PROD.CDPRODUTO     = V_CDPRODMRP)
                     AND (PF.CDFILIAL        = P_CDFILIAL)
                     AND (PF.CDPRODUTO       = PROD.CDPRODUTO)
                     AND (PF.IDPROFABPADR    = 'S')
                     AND (INS.CDFILIAL       = PF.CDFILIAL)
                     AND (INS.CDPRODUTO      = PF.CDPRODUTO)
                     AND (INS.CDPROCFABRIC   = PF.CDPROCFABRIC)
                     AND (INS.IDSEMIACETAP   = 'S')
                     AND (PRF.CDFILIAL   (+) = INS.CDFILIAL)
                     AND (PRF.CDPRODESTO (+) = INS.CDPRODINSUMO)
                     AND (INS.CDPRODINSUMO   = PR.CDPRODUTO (+))
                     AND (CL.CDFILIAL        = P_CDFILIAL)
                     AND (CL.CDPRODUTO       = V_CDPRODMRP)
                     AND (CL.DTPROGPRODCP    = P_DTMRP)
                     AND (CL. NRORDEMPROD    = V_NRORDEMPROD )
                     AND (P.CDFILIAL     (+) = P_CDFILIAL)
                     AND (P.CDPRODUTO    (+) = INS.CDPRODINSUMO)
                     AND ((P.DTPOSESTCON     = (SELECT MAX(PO.DTPOSESTCON)
                                                FROM POSESTCONS PO
                                                WHERE PO.CDFILIAL    = P_CDFILIAL
                                                  AND PO.CDPRODUTO   = INS.CDPRODINSUMO
                                                  AND PO.DTPOSESTCON <= (SYSDATE + 1)
                                               ))
                          OR P.DTPOSESTCON IS NULL)
                     AND (PROD2.CDPRODUTO   = INS.CDPRODINSUMO)
                     AND (PF2.CDFILIAL      = P_CDFILIAL)
                     AND (PF2.CDPRODUTO     = INS.CDPRODINSUMO)
                     AND (PF2.IDPROFABPADR  = 'S')
                     AND (CL.IDGERADO <> 'S')
                   GROUP BY INS.CDPRODINSUMO, INS.IDSUBOPINSU, CL.NRORDENAOP, CL.NRORDENASUBOP,
                            PROD2.IDPRODPROD, NVL(PRF.QTESTOSEGU, 0), DECODE(P_IDESTOQUE, 'S', NVL(P.QTESTDIACON, 0),0),
                            NVL(PF2.QTPADPROCFAB, 0), NVL(PF2.QTLOTEFABDIA, 0), DTCONCPROMRP, QTSEMITOTAL,
                            INS.IDSEMIACETAP, PF2.IDTPPROPOPF, PF2.IDTPARREDPF
                   UNION ALL
                   SELECT INS.CDPRODINSUMO, INS.IDSUBOPINSU, CL.NRORDENAOP, CL.NRORDENASUBOP,
                          PROD2.IDPRODPROD, NVL(PRF.QTESTOSEGU, 0) AS QTESTOQMIN,
                          NVL(SUM(PR.QTPRODLOTE), 0) AS QTPRODUCAO,
                          DECODE(P_IDESTOQUE, 'S', NVL(P.QTESTDIACON, 0),0) AS QTDEESTO,
                          NVL(PF2.QTPADPROCFAB, 0) AS QTPADPROCFAB,
                          NVL(PF2.QTLOTEFABDIA, 0) AS QTLOTEFABDIA,
                          ORD.DTHRFIMPREOP AS DTCONCPROMRP, QTSEMITOTAL, INS.IDSEMIACETAP, PF2.IDTPPROPOPF,
                          PF2.IDTPARREDPF, 0 QUANTIDADE
                   FROM ESTOSEGU PRF, PRODUTO PROD, PRODUTO PROD2, PROCFABRICA PF, PROCFABRICA PF2,
                        INSUMETAPA INS, POSESTCONS P, CALEPRODMRP CL, PARAMPRODMRP PP, ORDPRODUCAO ORD,
                        (SELECT CDPRODUTO, IDGERAOPCONF, SUM(QTPRODLOTE) AS QTPRODLOTE, SUM(QTSEMITOTAL) AS QTSEMITOTAL
                         FROM (SELECT O.CDPRODUTO, P.IDGERAOPCONF, NVL(SUM(QTAPRODPREOP),0) AS QTPRODLOTE,
                                      NVL(SUM(QTAPRODPREOP),0) AS QTSEMITOTAL
                               FROM ORDPRODUCAO O, PARAMPRODMRP P
                               WHERE (O.CDFILIAL     = P_CDFILIAL)
                                 AND (O.IDSITORDPROD = '1')
                                 AND (O.IDCONFIRMAOP = 'S')
                                 AND (P.CDFILIAL  = O.CDFILIAL )
                                 AND (P.CDPRODUTO = O.CDPRODUTO)
                                 AND (P.IDGERAOPCONF = 'S')
                               GROUP BY O.CDPRODUTO, P.IDGERAOPCONF
                               UNION
                               SELECT O.CDPRODUTO, P.IDGERAOPCONF, 0 AS QTPRODLOTE, NVL(SUM(QTAPRODPREOP),0) AS QTSEMITOTAL
                               FROM ORDPRODUCAO O, PARAMPRODMRP P
                               WHERE (O.CDFILIAL     = P_CDFILIAL)
                                 AND (O.IDSITORDPROD = '2')
                                 AND (O.IDCONFIRMAOP = 'S')
                                 AND (P.CDFILIAL  = O.CDFILIAL )
                                 AND (P.CDPRODUTO = O.CDPRODUTO)
                                 AND (P.IDGERAOPCONF = 'S')
                               GROUP BY O.CDPRODUTO, P.IDGERAOPCONF
                              )
                         GROUP BY CDPRODUTO, IDGERAOPCONF
                        ) PR
                   WHERE (PROD.CDPRODUTO     = V_CDPRODMRP)
                     AND (PF.CDFILIAL        = P_CDFILIAL)
                     AND (PF.CDPRODUTO       = PROD.CDPRODUTO)
                     AND (PF.IDPROFABPADR    = 'S')
                     AND (INS.CDFILIAL       = PF.CDFILIAL)
                     AND (INS.CDPRODUTO      = PF.CDPRODUTO)
                     AND (INS.CDPROCFABRIC   = PF.CDPROCFABRIC)
                     AND (INS.IDSEMIACETAP   = 'S')
                     AND (PRF.CDFILIAL   (+) = INS.CDFILIAL)
                     AND (PRF.CDPRODESTO (+) = INS.CDPRODINSUMO)
                     AND (INS.CDPRODINSUMO   = PR.CDPRODUTO (+))
                     AND (CL.CDFILIAL        = P_CDFILIAL)
                     AND (CL.CDPRODUTO       = V_CDPRODMRP)
                     AND (CL.DTPROGPRODCP    = P_DTMRP)
                     AND (CL. NRORDEMPROD    = V_NRORDEMPROD )
                     AND (P.CDFILIAL     (+) = P_CDFILIAL)
                     AND (P.CDPRODUTO    (+) = INS.CDPRODINSUMO)
                     AND ((P.DTPOSESTCON     = (SELECT MAX(PO.DTPOSESTCON)
                                                FROM POSESTCONS PO
                                                WHERE PO.CDFILIAL    = P_CDFILIAL
                                                  AND PO.CDPRODUTO   = INS.CDPRODINSUMO
                                                  AND PO.DTPOSESTCON <= (SYSDATE + 1)
                                               ))
                           OR P.DTPOSESTCON IS NULL)
                     AND (PROD2.CDPRODUTO   = INS.CDPRODINSUMO)
                     AND (PF2.CDFILIAL      = P_CDFILIAL)
                     AND (PF2.CDPRODUTO     = INS.CDPRODINSUMO)
                     AND (PF2.IDPROFABPADR  = 'S')
                     AND (PP.CDFILIAL       = P_CDFILIAL)
                     AND (PP.CDPRODUTO      = INS.CDPRODINSUMO)
                     AND (PP.IDGERAOPCONF   = 'S')
                     AND (ORD.CDFILIAL      = P_CDFILIAL)
                     AND (ORD.CDPRODUTO     = INS.CDPRODINSUMO)
                     AND (ORD.IDSITORDPROD  = '2')
                     AND ((ORD.DTHRFIMPREOP > SYSDATE) OR (ORD.DTHRFIMPREOP = SYSDATE))
                     AND (PF2.CDPRODUTO      = ORD.CDPRODUTO)
                     AND (CL.IDGERADO <> 'S')
                     AND (INS.CDPRODINSUMO||CL.NRORDENAOP NOT IN (SELECT CM.CDPRODUTO||CM.NRORDENAOP
                                                                  FROM CALEPRODMRP CM
                                                                  WHERE CM.CDFILIAL    = P_CDFILIAL
                                                                    AND CM.CDPRODFINAL = P_CDPRODFINAL
                                                                    AND CM.DTPROGPRODCP    = P_DTMRP
                                                                  ))
                   GROUP BY INS.CDPRODINSUMO, INS.IDSUBOPINSU, CL.NRORDENAOP, CL.NRORDENASUBOP,
                            PROD2.IDPRODPROD, NVL(PRF.QTESTOSEGU, 0),
                            DECODE(P_IDESTOQUE, 'S', NVL(P.QTESTDIACON, 0),0),
                            NVL(PF2.QTPADPROCFAB, 0), NVL(PF2.QTLOTEFABDIA, 0), ORD.DTHRFIMPREOP,
                            QTSEMITOTAL, INS.IDSEMIACETAP, PF2.IDTPPROPOPF, PF2.IDTPARREDPF
                  ) SEMI
             ORDER BY SEMI.DTCONCPROMRP
            )
         LOOP




            IF NOT C_SEMIACABADO.CDPRODINSUMO IS NULL THEN
               IF C_SEMIACABADO.IDSUBOPINSU = 'S' THEN
                  V_NRORDENASUBOP := TO_CHAR(TO_NUMBER(C_SEMIACABADO.NRORDENASUBOP) + 1);
                  V_NRORDENAOP    := C_SEMIACABADO.NRORDENAOP;
               ELSE
                  SELECT LPAD(TO_CHAR(TO_NUMBER(NVL(MAX(NRORDENAOP),'0')) + 1),10,'0')
                  INTO V_NRORDENAOP
                  FROM CALEPRODMRP
                  WHERE CDFILIAL = P_CDFILIAL
                    AND DTPROGPRODCP = P_DTMRP;

                  V_NRORDENASUBOP := '0';
               END IF;

            
               IF P_IDGERSEMIACA IN ('S','A') THEN
                  V_IDGERSEMIACA := 'A';
               ELSE
                  IF P_IDGERSEMIACA = 'P' THEN
                     V_IDGERSEMIACA := 'N';
                  END IF;
               END IF;

               GERA_MRP_PRODUTO(P_CDFILIAL, P_DTMRP, C_SEMIACABADO.CDPRODINSUMO, C_SEMIACABADO.IDPRODPROD,
                                C_SEMIACABADO.DTCONCPROMRP, C_SEMIACABADO.QTDEESTO, C_SEMIACABADO.QTESTOQMIN, C_SEMIACABADO.QTPADPROCFAB,
                                C_SEMIACABADO.QTLOTEFABDIA, C_SEMIACABADO.QUANTIDADE, C_SEMIACABADO.QTPRODUCAO, P_DTINI,
                                P_DTFIN,  P_CDPRODINIPCP, P_CDPRODFINPCP, P_IDMRPPEDPREV,
                                P_IDESTOQUE, P_IDCONSDEMA, V_NRORDENAOP, V_NRORDENASUBOP,
                                V_CDPRODMRP, P_DTENTPRODACAB, V_NRORDEMPROD, 0,
                                C_SEMIACABADO.QTSEMITOTAL, C_SEMIACABADO.IDSEMIACETAP, C_SEMIACABADO.IDSUBOPINSU,V_IDGERSEMIACA);
               UPDATE CALEPRODMRP
               SET IDGERADO = 'S'
               WHERE CDFILIAL    = P_CDFILIAL
                 AND CDPRODFINAL = P_CDPRODFINAL
                 AND CDPRODUTO   = C_SEMIACABADO.CDPRODINSUMO
                 AND DTPROGPRODCP = P_DTMRP;
            END IF;
         END LOOP;
      END IF;
   END IF;
END;
/

