CREATE OR REPLACE
PROCEDURE MENSAL_DATA_ENTR_MES
  (P_CDFILIAL     IN VARCHAR2,
   P_CDPERIENTR   IN VARCHAR2,
   P_DTINICIAL    IN DATE,
   P_IDDIANUTIL   IN VARCHAR2,
   P_DTPROCESSA   IN DATE) IS
   V_CONTAUXI   NUMBER;
   V_DIENTREGA  VARCHAR2(2);
   V_DTDIAENTR  DATE;
   V_IDDIASEM   NUMBER;
   V_DTENTRAUX  DATE;
   V_PRIMVEZ    NUMBER;
   V_DIPRIMVEZ  VARCHAR2(2);
   V_JAEXISTE   NUMBER;
   V_DTENTREGA_ANT DATE;
   V_DTENTREGA_PROX DATE;
   V_PERFILPROD_SITENTR VARCHAR2(1); -- Parametro que define se atrasa (A) ou adianta (D) a entrega do produto

/*-------- CURSOR QUE CONTEM TODOS OS DIAS DE ENTREGA DE DETERMINADA PERIODICIDADE ------*/
   CURSOR C_DIAS_ENTR IS
      SELECT DIENTREGA
      FROM DIASENTR
      WHERE
        CDPERIENTR = P_CDPERIENTR
      ORDER BY DIENTREGA;
BEGIN
    V_DTENTRAUX     := P_DTINICIAL;
    V_DTENTREGA_ANT := NULL;

    OPEN C_DIAS_ENTR;
    LOOP
      FETCH C_DIAS_ENTR
      INTO V_DIENTREGA;
      EXIT WHEN C_DIAS_ENTR%NOTFOUND;

     V_DTDIAENTR := (P_DTINICIAL - 1) + V_DIENTREGA;
     IF V_DTDIAENTR > LAST_DAY(P_DTINICIAL) THEN
        V_DTDIAENTR := LAST_DAY(P_DTINICIAL);
     END IF;

     SELECT NVL(MAX(IDSITUENTREGA), 'A')
       INTO V_PERFILPROD_SITENTR
       FROM PERFILPROD PFP
      WHERE PFP.CDFILIAL   = P_CDFILIAL
        AND PFP.CDPERIENTR = P_CDPERIENTR
        AND NVL(PFP.IDSITUENTREGA, 'A') = 'D';

     IF V_DTDIAENTR >= P_DTPROCESSA THEN

   /*- CALCULA UMA DATA DE ENTREGA ANTERIOR A UMA DATA NAO UTIL -*/
        IF P_IDDIANUTIL = 'S' THEN
          V_CONTAUXI := 1;
           WHILE V_CONTAUXI > 0 LOOP
             SELECT COUNT(*) INTO V_CONTAUXI
             FROM FERICOMP
             WHERE
             CDFILIAL = P_CDFILIAL AND
             DTFERICOMP = V_DTDIAENTR;
             IF V_CONTAUXI > 0 THEN
                IF NVL(V_PERFILPROD_SITENTR, 'A') <> 'D' THEN
                   V_DTDIAENTR := V_DTDIAENTR - 1;
                ELSE
                   V_DTDIAENTR := V_DTDIAENTR + 1;
                END IF;
             END IF;
           END LOOP;
         END IF;
   /* - Verifica se ja existe a data de entrega que foi calculada por um dia nao util -*/
        SELECT COUNT(*) INTO V_JAEXISTE
        FROM CALECOMP
        WHERE
          CDFILIAL = P_CDFILIAL AND
          CDPERIENTR = P_CDPERIENTR AND
          DTENTREGA = V_DTDIAENTR;
   /*- Se ja existir a data pula -*/
        IF V_JAEXISTE = 0 THEN

     /*- VERIFICA SE JA EXISTE ALGUMA DATA DE ENTREGA CALCULADA PARA  -*/
     /*- INCLUIR A DATA ANTERIOR A PROXIMA ENTREGA  -*/

           SELECT COUNT(*) INTO V_PRIMVEZ
           FROM CALECOMP
           WHERE
           CDFILIAL = P_CDFILIAL AND
           CDPERIENTR = P_CDPERIENTR AND
           DTENTREGA = V_DTENTRAUX;

     /*- INCLUI A DATA ANTERIOR A PROXIMA ENTREGA  -*/
/*           IF V_PRIMVEZ > 0 THEN
              UPDATE CALECOMP SET DTANTPROXENT = V_DTDIAENTR - 1
              WHERE CDFILIAL = P_CDFILIAL AND
              CDPERIENTR = P_CDPERIENTR AND
              DTENTREGA = V_DTENTRAUX;
           ELSE
              V_DIPRIMVEZ := V_DIENTREGA;
           END IF;                       */

     /*- INCLUI A DATA DE ENTREGA CALCULADA NO CALENDARIO DE COMPRAS -*/
           INSERT INTO CALECOMP
             (CDFILIAL,
              CDPERIENTR,
              DTENTREGA,
              DTANTPROXENT)
             VALUES
             (P_CDFILIAL,
              P_CDPERIENTR,
              V_DTDIAENTR,
              V_DTENTRAUX);

           COMMIT;   

           V_DTENTRAUX := V_DTDIAENTR;
        END IF;

        UPDATE CALECOMP
        SET DTANTPROXENT = V_DTDIAENTR - 1
        WHERE
          CDFILIAL   = P_CDFILIAL AND
          CDPERIENTR = P_CDPERIENTR AND
          DTENTREGA  = V_DTENTREGA_ANT;

        COMMIT;
        
        V_DTENTREGA_ANT := V_DTDIAENTR;
     END IF;
    END LOOP;
    CLOSE C_DIAS_ENTR;

    -- Calcula a data anterior a proxima entrega da ultima data de entrega calculada.
    SELECT
      MIN(DIENTREGA) INTO V_DIENTREGA
    FROM
      DIASENTR
    WHERE
      CDPERIENTR = P_CDPERIENTR;

    V_DTENTREGA_PROX := LAST_DAY(P_DTINICIAL) + V_DIENTREGA;

   /*- CALCULA UMA DATA DE ENTREGA ANTERIOR A UMA DATA NAO UTIL -*/
    IF (P_IDDIANUTIL = 'S') THEN
       V_CONTAUXI := 1;
       WHILE (V_CONTAUXI > 0) LOOP
         SELECT COUNT(*) INTO V_CONTAUXI
         FROM FERICOMP
         WHERE
         CDFILIAL   = P_CDFILIAL AND
         DTFERICOMP = V_DTENTREGA_PROX;
         IF (V_CONTAUXI > 0) THEN
            V_DTENTREGA_PROX := V_DTENTREGA_PROX - 1;
         END IF;
       END LOOP;
    END IF;

    UPDATE CALECOMP
    SET DTANTPROXENT = V_DTENTREGA_PROX - 1
    WHERE
      CDFILIAL   = P_CDFILIAL AND
      CDPERIENTR = P_CDPERIENTR AND
      DTENTREGA  = V_DTENTREGA_ANT;

    COMMIT;  
/*
-- PEGA A PRIMEIRA DATA ANTERIOR A PROXIMA ENTREGA
    V_DTDIAENTR := LAST_DAY(P_DTINICIAL) + V_DIPRIMVEZ;
    IF V_DTDIAENTR > LAST_DAY(LAST_DAY(P_DTINICIAL) + 1) THEN
       V_DTDIAENTR := LAST_DAY(LAST_DAY(P_DTINICIAL) + 1);
    END IF;

    IF V_DTDIAENTR >= P_DTPROCESSA THEN

   -- CALCULA UMA DATA DE ENTREGA ANTERIOR A UMA DATA NAO UTIL
       IF P_IDDIANUTIL = 'S' THEN
          V_CONTAUXI := 1;
           WHILE V_CONTAUXI > 0 LOOP
             SELECT COUNT(*) INTO V_CONTAUXI
             FROM FERICOMP
             WHERE
             CDFILIAL = P_CDFILIAL AND
             DTFERICOMP = V_DTDIAENTR;
             IF V_CONTAUXI > 0 THEN
                V_DTDIAENTR := V_DTDIAENTR - 1;
             END IF;
           END LOOP;
         END IF;
         V_DTDIAENTR := V_DTDIAENTR - 1;

   -- VERIFICA SE JA EXISTE A ULTIMA DATA DE ENTREGA QUE RECEBERA
   -- A DATA ANTERIOR A PROXIMA ENTREGA

       SELECT COUNT(*) INTO V_PRIMVEZ
       FROM CALECOMP
       WHERE
         CDFILIAL   = P_CDFILIAL AND
         CDPERIENTR = P_CDPERIENTR AND
         DTENTREGA  = V_DTENTRAUX;

       IF V_PRIMVEZ > 0 THEN
   -- INCLUI A DATA ANTERIOR A PROXIMA ENTREGA PARA A A ULTIMA DATA DE ENTREGA DO MES
         UPDATE CALECOMP SET DTANTPROXENT = V_DTDIAENTR
         WHERE CDFILIAL = P_CDFILIAL AND
         CDPERIENTR = P_CDPERIENTR AND
         DTENTREGA = V_DTENTRAUX;
       END IF;
    END IF; */
END;
/