create or replace PROCEDURE USR_IMPORTA_MERCADORIA(P_MENSAGEMERRO OUT VARCHAR2)
IS
V_IDENTRSAID       USR_ENTR_MERC.IDENTRSAID%TYPE; 
V_CDEXFILIAL       USR_ENTR_MERC.CDEXFILIAL%TYPE;
V_DTENTRADA        USR_ENTR_MERC.DTENTRADA%TYPE;
V_NRLANCTOUSR      USR_ENTR_MERC.NRLANCTOUSR%TYPE;
V_CDCODOC          USR_ENTR_MERC.CDCODOC%TYPE;
V_CDPRODINTE       PRODUTO.CDPRODINTE%TYPE;
V_VRQUANTIDADE     USR_ITEM_ENTR_MERC.VRQUANTIDADE%TYPE;
V_VRUNITARIO       USR_ITEM_ENTR_MERC.VRUNITARIO%TYPE;
V_DTINCLUSAO       USR_ITEM_ENTR_MERC.DTINCLUSAO%TYPE;
V_DSDESCRICAO      USR_ITEM_ENTR_MERC.DSDESCRICAO%TYPE;
V_CDPRODESTO       PRODUTO.CDPRODESTO%TYPE;
V_CDPRODUTO        PRODUTO.CDPRODUTO%TYPE;
V_CDARVPROD        PRODUTO.CDARVPROD%TYPE;
V_NMPRODUTO        PRODUTO.NMPRODUTO%TYPE;
V_CDALMOXARIFE_E   PRODFILI.CDALMOXARIFE%TYPE;
V_CDLOCALESTOQ_E   PRODFILI.CDLOCALESTOQ%TYPE;
V_IDUTILLCESTQ     PARAMFILIAL.IDUTILLCESTQ%TYPE;
V_DSPERMMOVI       VARCHAR2(3);
V_IDNEWLANCEST     VARCHAR2(1);
V_NRLANCESTQ_E     VARCHAR2(20);
V_ERRO             VARCHAR2(3000);
V_NRLOTEESTQ       VARCHAR2(20);
V_IDUTILLOTE       VARCHAR2(1);
V_IDUTCTRLLOTE     VARCHAR2(1);
V_NRSEQITENTR      NUMBER;
V_QTPRODIMPORTADO  NUMBER;
V_QTTOTALPROD      NUMBER;

V_DTPROCESSA       DATE;
V_IDLANCDTMAIFIL   VARCHAR2(1);
V_IDLANCDTMAI      VARCHAR2(1);
V_IDLANCDTMENFIL   VARCHAR2(1);
V_IDLANCDTMEN      VARCHAR2(1);
V_NRDIASENTRFIL    FLOAT;
V_NRDIASENTR       FLOAT;
V_NRDIASENTRPDFIL  FLOAT;
V_NRDIASENTRPD     FLOAT;

V_CDCODOC_EXISTE   USR_ENTR_MERC.CDCODOC%TYPE; 

CURSOR C_CABEC IS
SELECT USR.IDENTRSAID, USR.CDEXFILIAL, USR.DTENTRADA, USR.NRLANCTOUSR, USR.CDCODOC, USRIT.QTPRODIMPORTADO, TOT.QTTOTALPROD, USR.DSDESCRICAO
  FROM USR_ENTR_MERC USR
 INNER JOIN (SELECT CDEXFILIAL, NRLANCTOUSR, SUM(QTPRODIMPORTADO) AS QTPRODIMPORTADO
               FROM(SELECT IT.CDEXFILIAL, IT.NRLANCTOUSR,
                           CASE WHEN (NVL(PR.CDPRODINTE, PR.CDPRODUTO) = IT.CDPRODINTE) THEN 1 ELSE 0 END AS QTPRODIMPORTADO
                      FROM USR_ITEM_ENTR_MERC IT
                     INNER JOIN USR_ENTR_MERC USR
                        ON USR.CDEXFILIAL = IT.CDEXFILIAL
                       AND USR.NRLANCTOUSR = IT.NRLANCTOUSR
                      LEFT JOIN PRODUTO PR
                        ON NVL(PR.CDPRODINTE, PR.CDPRODUTO) = IT.CDPRODINTE
                     WHERE USR.NRLANCESTQ IS NULL
                     ORDER BY IT.CDEXFILIAL, IT.NRLANCTOUSR)
               GROUP BY CDEXFILIAL, NRLANCTOUSR) USRIT
    ON USR.CDEXFILIAL = USRIT.CDEXFILIAL
   AND USR.NRLANCTOUSR = USRIT.NRLANCTOUSR
 INNER JOIN (SELECT IT.CDEXFILIAL, IT.NRLANCTOUSR, COUNT(1) QTTOTALPROD
               FROM USR_ITEM_ENTR_MERC IT
              INNER JOIN USR_ENTR_MERC USR
                 ON USR.CDEXFILIAL = IT.CDEXFILIAL
                AND USR.NRLANCTOUSR = IT.NRLANCTOUSR
               LEFT JOIN PRODUTO PR
                 ON PR.CDPRODINTE = IT.CDPRODINTE
              WHERE USR.NRLANCESTQ IS NULL
              GROUP BY IT.CDEXFILIAL, IT.NRLANCTOUSR) TOT
    ON USR.CDEXFILIAL = TOT.CDEXFILIAL
   AND USR.NRLANCTOUSR = TOT.NRLANCTOUSR
 WHERE NRLANCESTQ IS NULL
   AND LOG_ERRO IS NULL;

CURSOR C_ITEM (C_NRLANCTOUSR IN VARCHAR2, C_CDEXFILIAL IN VARCHAR2) IS
SELECT USR.CDPRODINTE, USR.VRQUANTIDADE, USR.VRUNITARIO, USR.CDEXFILIAL, USR.DTINCLUSAO, R.CDPRODESTO, PR.CDPRODUTO, PR.CDARVPROD, PR.NMPRODUTO,
       NVL(NVL(PF.CDALMOXARIFE,PFL.CDALMOXARIFE),' ') AS CDALMOXARIFE_E, NVL(NVL(PF.CDLOCALESTOQ,PFL.CDLOCALESTOQ),' ') AS CDLOCALESTOQ_E, PFL.IDUTILLCESTQ,
       CASE WHEN PFL.IDUTILALMOX = 'S'
            THEN (CASE WHEN NVL(PF.CDALMOXARIFE,PFL.CDALMOXARIFE) IS NULL
                       THEN 'NAO'
                       ELSE 'SIM'
                  END)
            ELSE (CASE WHEN PFL.IDUTILLCESTQ = 'S'
                       THEN (CASE WHEN NVL(PF.CDLOCALESTOQ,PFL.CDLOCALESTOQ) IS NULL
                                  THEN 'NAO'
                                  ELSE 'SIM'
                             END)
                       ELSE 'SIM'
                  END)
       END AS DSPERMMOVI, PFL.IDUTILLOTE, PF.IDUTCTRLLOTE
  FROM USR_ITEM_ENTR_MERC USR
 INNER JOIN PRODUTO PR
    ON USR.CDPRODINTE = NVL(PR.CDPRODINTE, PR.CDPRODUTO)
 INNER JOIN FILIAL F
    ON F.CDFILIAL = C_CDEXFILIAL
 INNER JOIN PARAMFILIAL PFL
    ON PFL.CDFILIAL = C_CDEXFILIAL
 INNER JOIN PRODUTO R
    ON R.CDPRODUTO = PR.CDPRODUTO
 INNER JOIN PRODFILI PF
    ON PF.CDFILIAL = C_CDEXFILIAL
   AND PF.CDPRODUTO = R.CDPRODESTO
 WHERE USR.NRLANCTOUSR = C_NRLANCTOUSR
   AND USR.CDEXFILIAL = C_CDEXFILIAL;


BEGIN
   V_QTPRODIMPORTADO := 0;
   V_QTTOTALPROD     := 0;

   OPEN C_CABEC;
   LOOP
      FETCH C_CABEC INTO V_IDENTRSAID, V_CDEXFILIAL, V_DTENTRADA, V_NRLANCTOUSR, V_CDCODOC, V_QTPRODIMPORTADO, V_QTTOTALPROD, V_DSDESCRICAO;
      EXIT WHEN C_CABEC%NOTFOUND;

      V_IDNEWLANCEST  := 'S';
      V_NRSEQITENTR   := 0;
      P_MENSAGEMERRO  := NULL;
      V_ERRO := NULL;

      BEGIN
         SELECT CDCODOC
           INTO V_CDCODOC_EXISTE
           FROM USR_ENTR_MERC
          WHERE CDCODOC = V_CDCODOC
            AND NOT NRLANCESTQ IS NULL;
      EXCEPTION
         WHEN NO_DATA_FOUND THEN
            V_CDCODOC_EXISTE := NULL;
      END;

      IF V_CDCODOC_EXISTE IS NULL THEN

         -- verifica data de lancamento dentro do periodo
         BEGIN
            SELECT DECODE(PG.IDUTILDTPROC,'S',NVL(PF.DTPROCESSA, TO_DATE(SYSDATE)),TO_DATE(SYSDATE)) AS DTPROCESSA,
                   PF.IDLANCDTMAIFIL, PE.IDLANCDTMAI, PF.IDLANCDTMENFIL, PE.IDLANCDTMEN,
                   PF.NRDIASENTRFIL, PE.NRDIASENTR, PF.NRDIASENTRPDFIL, PE.NRDIASENTRPD
              INTO V_DTPROCESSA,
                   V_IDLANCDTMAIFIL, V_IDLANCDTMAI, V_IDLANCDTMENFIL, V_IDLANCDTMEN,
                   V_NRDIASENTRFIL, V_NRDIASENTR, V_NRDIASENTRPDFIL, V_NRDIASENTRPD
              FROM PARAMESTOQUE PE, PARAMGERAL PG, PARAMFILIAL PF
             WHERE PE.CDPARESTOQ = '1'
               AND PG.CDPARGERAL = '0001'
               AND PF.CDFILIAL = V_CDEXFILIAL;
         EXCEPTION
            WHEN NO_DATA_FOUND THEN
               V_DTPROCESSA := SYSDATE;
               V_IDLANCDTMAIFIL := 'N'; V_IDLANCDTMAI := 'N'; V_IDLANCDTMENFIL := 'N'; V_IDLANCDTMEN := 'N';
               V_NRDIASENTRFIL := NULL; V_NRDIASENTR := NULL; V_NRDIASENTRPDFIL := NULL; V_NRDIASENTRPD := NULL;
         END;

         IF V_DTENTRADA IS NULL THEN
            V_ERRO := 'Data da entrada deve ser informada.';
         END IF;

         IF (V_IDLANCDTMAIFIL = 'N') AND (V_IDLANCDTMAI = 'N') AND (V_DTENTRADA > V_DTPROCESSA) THEN
            V_ERRO := 'Data da entrada fora do periodo permitido.';
         END IF;

         IF (V_IDLANCDTMENFIL = 'N') AND (V_IDLANCDTMEN = 'N') AND (V_DTENTRADA < V_DTPROCESSA) THEN
            V_ERRO := 'Data da entrada fora do periodo permitido.';
         END IF;

         IF (V_IDLANCDTMENFIL = 'S') AND (V_DTENTRADA < V_DTPROCESSA) THEN
            IF (V_DTENTRADA < (V_DTPROCESSA - V_NRDIASENTRFIL)) THEN
               V_ERRO := 'Data da entrada fora do periodo permitido.';
            END IF;
         END IF;

         IF (V_IDLANCDTMEN = 'S') AND (V_DTENTRADA < V_DTPROCESSA) THEN
            IF (V_DTENTRADA < (V_DTPROCESSA - V_NRDIASENTR)) THEN
               V_ERRO := 'Data da entrada fora do periodo permitido.';
            END IF;
         END IF;

         IF (V_IDLANCDTMAIFIL = 'S') AND (V_DTENTRADA > V_DTPROCESSA) THEN
            IF (V_DTENTRADA > (V_DTPROCESSA + V_NRDIASENTRPDFIL)) THEN
               V_ERRO := 'Data da entrada fora do periodo permitido.';
            END IF;
         END IF;

         IF (V_IDLANCDTMAI = 'S') AND (V_DTENTRADA > V_DTPROCESSA) THEN
            IF (V_DTENTRADA > (V_DTPROCESSA + V_NRDIASENTRPD)) THEN
               V_ERRO := 'Data da entrada fora do periodo permitido.';
            END IF;
         END IF;

         IF V_ERRO IS NULL THEN

            IF V_QTPRODIMPORTADO = V_QTTOTALPROD THEN

               OPEN C_ITEM(V_NRLANCTOUSR, V_CDEXFILIAL);
               LOOP
                  FETCH C_ITEM INTO V_CDPRODINTE, V_VRQUANTIDADE, V_VRUNITARIO, V_CDEXFILIAL, V_DTINCLUSAO, V_CDPRODESTO, V_CDPRODUTO, V_CDARVPROD, V_NMPRODUTO,
                                    V_CDALMOXARIFE_E, V_CDLOCALESTOQ_E, V_IDUTILLCESTQ, V_DSPERMMOVI, V_IDUTILLOTE, V_IDUTCTRLLOTE;
                  EXIT WHEN C_ITEM%NOTFOUND;

                  IF (V_DSPERMMOVI = 'SIM') THEN

                     BEGIN
                        INSERT INTO PRODLCESTOQ (CDFILIAL, CDALMOXARIFE, CDLOCALESTOQ, CDPRODUTO)
                        SELECT V_CDEXFILIAL, V_CDALMOXARIFE_E, V_CDLOCALESTOQ_E, V_CDPRODESTO
                          FROM PRODFILI
                         WHERE CDFILIAL  = V_CDEXFILIAL
                           AND CDPRODUTO = V_CDPRODUTO
                           AND NVL(IDCNTRESTOQ, 'S') <> 'N'
                         MINUS
                        SELECT CDFILIAL, CDALMOXARIFE, CDLOCALESTOQ, CDPRODUTO
                          FROM PRODLCESTOQ
                         WHERE CDFILIAL     = V_CDEXFILIAL
                           AND CDALMOXARIFE = V_CDALMOXARIFE_E
                           AND CDLOCALESTOQ = V_CDLOCALESTOQ_E
                           AND CDPRODUTO    = V_CDPRODESTO;

                     EXCEPTION
                        WHEN NO_DATA_FOUND THEN
                           V_ERRO         := SQLERRM(SQLCODE);
                           P_MENSAGEMERRO := V_ERRO;
                     END;

                     IF V_ERRO IS NOT NULL THEN
                        GOTO BREAK_STP;
                     END IF;

                        IF V_IDNEWLANCEST = 'S' THEN
                  
                           NOVO_CODIGO_SC('LANCTOEST' || V_CDEXFILIAL, V_NRLANCESTQ_E);
         
                           BEGIN
                              INSERT INTO LANCTOESTOQ
                                 (CDFILIAL, NRLANCESTQ, DSLANCESTQ, IDTPLANCTO, CDTIPOOPER, DTLANCESTQ, IDENTRSAIDOP, CDFILIMOVI, NRLANCTONF)
                              VALUES
                                 (V_CDEXFILIAL, SUBSTR(V_NRLANCESTQ_E,11,10), V_DSDESCRICAO||'('||V_CDCODOC||')', '2', '10', V_DTENTRADA, 'E', V_CDEXFILIAL, NULL);
                           
                              UPDATE USR_ENTR_MERC
                                 SET NRLANCESTQ  = SUBSTR(V_NRLANCESTQ_E,11,10)
                               WHERE NRLANCTOUSR = V_NRLANCTOUSR
                                 AND CDEXFILIAL  = V_CDEXFILIAL;
                           
                           EXCEPTION
                              WHEN NO_DATA_FOUND THEN
                                 V_ERRO         := SQLERRM(SQLCODE);
                                 P_MENSAGEMERRO := V_ERRO;
                           END;
                     
                           V_IDNEWLANCEST := 'N';
                        END IF;

                        V_NRSEQITENTR := V_NRSEQITENTR + 1;

                        BEGIN
                  
                           IF V_IDUTCTRLLOTE = 'S' THEN
                              PRXLOTEPRODEST(V_CDEXFILIAL, V_DTENTRADA, V_CDPRODESTO, V_NRLOTEESTQ);
                           ELSE
                              V_NRLOTEESTQ := ' ';   
                           END IF;
                     
                  
                           INSERT INTO ITLANCTOEST
                              (CDFILIAL, NRLANCESTQ, NRSEQUITEM, CDPRODUTO,
                               QTLANCTOEST, VRUNILANCTO,VRTOTLANCTO, QTTOTLANCTO,
                               CDPRODMOVI, CDFILIMOVI, CDALMOXARIFE, CDLOCALESTOQ,
                               NRLOTEESTQ, NRSUBLOTE, IDTIPOMOVI, DTLANCMOVI,
                               IDORDEMCLC, VRLANCTOEST, VRLANCTOBRUT, VRCUSTENTR)
                           VALUES
                              (V_CDEXFILIAL, SUBSTR(V_NRLANCESTQ_E,11,10), LPAD(RTRIM(TO_CHAR(V_NRSEQITENTR)), 4, '0'), V_CDPRODUTO,
                               V_VRQUANTIDADE, V_VRUNITARIO, (V_VRQUANTIDADE*V_VRUNITARIO), V_VRQUANTIDADE,
                               V_CDPRODESTO, V_CDEXFILIAL, V_CDALMOXARIFE_E, V_CDLOCALESTOQ_E,
                               V_NRLOTEESTQ, ' ', '2', V_DTENTRADA,
                               '2', V_VRUNITARIO, V_VRUNITARIO, V_VRUNITARIO);

                           -- Atuliza estoque referente a Geracao de Entrada
                           ATUALIZA_ESTOQUE(V_CDEXFILIAL, V_DTENTRADA, TO_DATE(SYSDATE), V_CDEXFILIAL, SUBSTR(V_NRLANCESTQ_E,11,10), NULL);

                           /* Atualiza a Itlanctoest para nAo evoluir estoque caso encontre erro ao atualizar o estoque */
                           FOR C_PRODIRREG IN (SELECT NRMOVILOTE, CDFILIAL, CDALMOXARIFE, CDLOCALESTOQ,
                                                      CDPRODUTO, NRLOTEESTQ, NRSUBLOTE
                                                 FROM MOVILOTE
                                                WHERE NRMOVILOTE = V_CDEXFILIAL||SUBSTR(V_NRLANCESTQ_E,11,10)
                                                  AND CDFILIAL   = V_CDEXFILIAL)
                           LOOP
                              UPDATE ITLANCTOEST
                                 SET IDEVOLESTOQ  = 'N'
                               WHERE CDFILIAL     = V_CDEXFILIAL
                                 AND NRLANCESTQ   = SUBSTR(V_NRLANCESTQ_E,11,10)
                                 AND CDALMOXARIFE = V_CDALMOXARIFE_E
                                 AND CDLOCALESTOQ = V_CDLOCALESTOQ_E
                                 AND CDPRODUTO    = V_CDPRODUTO
                                 AND NRLOTEESTQ   = ' '
                                 AND NRSUBLOTE    = ' ';

                              V_ERRO := 'Operacao Bloqueada! Algum(ns) produto(s) tornariam o estoque irregular.';
                           END LOOP;

                           DELETE MOVILOTE
                            WHERE NRMOVILOTE = V_CDEXFILIAL||SUBSTR(V_NRLANCESTQ_E,11,10);
                        EXCEPTION
                           WHEN NO_DATA_FOUND THEN
                              V_ERRO         := SQLERRM(SQLCODE);
                              P_MENSAGEMERRO := V_ERRO;
                        END;

                  ELSE
                     V_ERRO := 'Operacao Bloqueada! Existe(m) algum(ns) produto(s) com parametrizacao nao definida.';
                     P_MENSAGEMERRO := V_ERRO;
                  END IF;

               END LOOP;

               IF V_ERRO IS NULL THEN
                  IF (C_ITEM%NOTFOUND AND V_NRSEQITENTR = 0) THEN
                     V_ERRO := 'Operacao Bloqueada! Produto(s) nao encontrado.';
                     P_MENSAGEMERRO := V_ERRO;
                  END IF;
               END IF;

               CLOSE C_ITEM;

               <<BREAK_STP>>

               COMMIT;
            ELSE
               V_ERRO := 'Operacao Bloqueada! Existe(em) produto(s) que nao foi(ram) cadastrado(s) na Arvore de produtos.';
               P_MENSAGEMERRO := V_ERRO;
            END IF;

            IF P_MENSAGEMERRO IS NULL THEN

               UPDATE USR_ENTR_MERC
                  SET LOG_ERRO    = 'Operacao realizada com sucesso.'
                WHERE NRLANCTOUSR = V_NRLANCTOUSR
                  AND CDEXFILIAL  = V_CDEXFILIAL;

            ELSE

               UPDATE USR_ENTR_MERC
                  SET LOG_ERRO    = P_MENSAGEMERRO
                WHERE NRLANCTOUSR = V_NRLANCTOUSR
                  AND CDEXFILIAL  = V_CDEXFILIAL;

            END IF;
         ELSE
            P_MENSAGEMERRO := V_ERRO;

            UPDATE USR_ENTR_MERC
               SET LOG_ERRO    = P_MENSAGEMERRO
             WHERE NRLANCTOUSR = V_NRLANCTOUSR
               AND CDEXFILIAL  = V_CDEXFILIAL;
         END IF;
      ELSE
         V_ERRO := 'Documento ja cadastrado.';
         P_MENSAGEMERRO := V_ERRO;

         UPDATE USR_ENTR_MERC
            SET LOG_ERRO    = P_MENSAGEMERRO
          WHERE NRLANCTOUSR = V_NRLANCTOUSR
            AND CDEXFILIAL  = V_CDEXFILIAL;
      END IF;
   END LOOP;
   CLOSE C_CABEC;

   IF P_MENSAGEMERRO IS NULL THEN
      P_MENSAGEMERRO := 'S';
   END IF;

   COMMIT;
END;
/