create or replace PROCEDURE APP_MOBILE_IMPORTA_INVENTARIO
(
   V_ERRO OUT VARCHAR2)
IS
   V_IDLANCCRIADO  VARCHAR2(1);

   V_CDFILIMOVI    VARCHAR2(4);
   V_NRLANCESTQ    VARCHAR2(20);
   V_NRSEQITPROD   VARCHAR2(4);

   V_CDPRODESTO    VARCHAR2(10);
   V_CDPRODUTO     VARCHAR2(10);
   V_QTESTCONV     FLOAT;

   V_CDALMOXARIFE  VARCHAR2(6);
   V_CDLOCALESTOQ  VARCHAR2(6);
   V_NRLOTEESTQ    VARCHAR2(20);
   V_NRSUBLOTE     VARCHAR2(4);
   V_VRESTOQBRUT  FLOAT;
   V_QTESTOQDIA   FLOAT;
   V_VRUNITITEM   FLOAT;

   V_DATA         DATE;
   V_DTFINAL      DATE;

   V_IDORDAJUINVE    VARCHAR2(1);
   V_IDORDEMCLC      VARCHAR2(1);

   V_DTPROCESSA      DATE;
   V_IDLANCDTMAIFIL  VARCHAR2(1);
   V_IDLANCDTMAI     VARCHAR2(1);
   V_IDLANCDTMENFIL  VARCHAR2(1);
   V_IDLANCDTMEN     VARCHAR2(1);
   V_NRDIASAJUSFIL   FLOAT;
   V_NRDIASAJUS      FLOAT;
   V_NRDIASAJUSPDFIL FLOAT;
   V_NRDIASAJUSPD    FLOAT;
   V_IRREG           VARCHAR2(1);
BEGIN
   V_IDLANCCRIADO := 'N';
   V_ERRO         := NULL;
   V_NRLANCESTQ   := NULL;

   V_IRREG := 'N';

   FOR C_MOV IN (SELECT CDFILIAL AS CDFILIMOVI,
                        DATARETIRADA AS DTLANCAMENTO,
                        CDOPERADOR AS CDOPERADOR,
                        DESCRICAO AS DSLANCESTQ,
                        CODPRODUTO AS CDPRODUTO,
                        QUANTIDADE AS VALQTDE
                   FROM USR_PRODMOVI
                  WHERE IDMOVIMENTACAO = '1'
                  ORDER BY 1, 5)
   LOOP
      IF V_IDLANCCRIADO = 'N' THEN

         V_CDFILIMOVI := C_MOV.CDFILIMOVI;

         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.NRDIASAJUSFIL, PE.NRDIASAJUS, PF.NRDIASAJUSPDFIL, PE.NRDIASAJUSPD
              INTO V_DTPROCESSA,
                   V_IDLANCDTMAIFIL, V_IDLANCDTMAI, V_IDLANCDTMENFIL, V_IDLANCDTMEN,
                   V_NRDIASAJUSFIL, V_NRDIASAJUS, V_NRDIASAJUSPDFIL, V_NRDIASAJUSPD
              FROM PARAMESTOQUE PE, PARAMGERAL PG, PARAMFILIAL PF
             WHERE PE.CDPARESTOQ = '1'
               AND PG.CDPARGERAL = '0001'
               AND PF.CDFILIAL = C_MOV.CDFILIMOVI;
         EXCEPTION
            WHEN NO_DATA_FOUND THEN
               V_DTPROCESSA := SYSDATE;
               V_IDLANCDTMAIFIL := 'N'; V_IDLANCDTMAI := 'N'; V_IDLANCDTMENFIL := 'N'; V_IDLANCDTMEN := 'N';
               V_NRDIASAJUSFIL := NULL; V_NRDIASAJUS := NULL; V_NRDIASAJUSPDFIL := NULL; V_NRDIASAJUSPD := NULL;
         END;

         BEGIN
            SELECT NVL(IDORDAJUINVE, 'P')
              INTO V_IDORDAJUINVE
              FROM PARAMFILIAL
             WHERE CDFILIAL = C_MOV.CDFILIMOVI;
         EXCEPTION
            WHEN NO_DATA_FOUND THEN
               V_IDORDAJUINVE := 'P';
         END;

         IF V_IDORDAJUINVE = 'P' THEN
            V_IDORDEMCLC := '0';
         ELSE
            V_IDORDEMCLC := 'U';
         END IF;


         V_DATA := TO_DATE(C_MOV.DTLANCAMENTO);

         IF V_DATA > V_DTPROCESSA THEN
            V_DTFINAL := V_DATA;
         ELSE
            V_DTFINAL := V_DTPROCESSA;
         END IF;

         IF V_DATA IS NULL THEN
            V_ERRO := 'Data do ajuste deve ser informada.';
         END IF;

         IF (V_IDLANCDTMAIFIL = 'N') AND (V_IDLANCDTMAI = 'N') AND (V_DATA > V_DTPROCESSA) THEN
            V_ERRO := 'Data do ajuste deve ser menor ou igual a data de processamento da filial.';
         END IF;

         IF (V_IDLANCDTMENFIL = 'N') AND (V_IDLANCDTMEN = 'N') AND (V_DATA < V_DTPROCESSA) THEN
            V_ERRO := 'Data do ajuste deve ser maior ou igual a data de processamento da filial.';
         END IF;

         IF (V_IDLANCDTMENFIL = 'S') AND (V_DATA < V_DTPROCESSA) THEN
            IF (V_DATA < (V_DTPROCESSA - V_NRDIASAJUSFIL)) THEN
               V_ERRO := 'Data do ajuste fora do periodo permitido.';
            END IF;
         END IF;

         IF (V_IDLANCDTMEN = 'S') AND (V_DATA < V_DTPROCESSA) THEN
            IF (V_DATA < (V_DTPROCESSA - V_NRDIASAJUS)) THEN
               V_ERRO := 'Data do ajuste fora do periodo permitido.';
            END IF;
         END IF;

         IF (V_IDLANCDTMAIFIL = 'S') AND (V_DATA > V_DTPROCESSA) THEN
            IF (V_DATA > (V_DTPROCESSA + V_NRDIASAJUSPDFIL)) THEN
               V_ERRO := 'Data do ajuste fora do periodo permitido.';
            END IF;
         END IF;

         IF (V_IDLANCDTMAI = 'S') AND (V_DATA > V_DTPROCESSA) THEN
            IF (V_DATA > (V_DTPROCESSA + V_NRDIASAJUSPD)) THEN
              --raise_application_error(-20501, V_DTPROCESSA||'***'||V_NRDIASAJUSPD, true);
               V_ERRO := 'Data do ajuste fora do periodo permitido.';
            END IF;
         END IF;

         IF V_ERRO IS NULL THEN
            /* Sequencial do produto */
            V_NRSEQITPROD := 1;

            NOVO_CODIGO_SC('LANCTOEST' || C_MOV.CDFILIMOVI, V_NRLANCESTQ);
            V_NRLANCESTQ := SUBSTR(V_NRLANCESTQ, -10);

            INSERT INTO LANCTOESTOQ
              (CDFILIAL, NRLANCESTQ, IDTPLANCTO, DTLANCESTQ, DSLANCESTQ, IDALTCUSMED,
               CDFILIMOVI, CDOPERADOR)
            VALUES
              (C_MOV.CDFILIMOVI, V_NRLANCESTQ, '1', C_MOV.DTLANCAMENTO, SUBSTR(C_MOV.DSLANCESTQ, 1, 60), 'N',
               C_MOV.CDFILIMOVI, C_MOV.CDOPERADOR);

            V_IDLANCCRIADO := 'S';
         END IF;
      END IF;

      IF V_ERRO IS NULL THEN
         /* Verifica informacao do produto de estoque relacionado ao lancamento */
         BEGIN
            SELECT MAX(P.CDPRODUTO), MAX(P.CDPRODESTO), MAX(C_MOV.VALQTDE * NVL(P.VRFATOCONV,1))
              INTO V_CDPRODUTO, V_CDPRODESTO, V_QTESTCONV
              FROM PRODUTO P
             WHERE P.CDARVPROD = C_MOV.CDPRODUTO;
         EXCEPTION
            WHEN NO_DATA_FOUND THEN
               V_CDPRODUTO := NULL; V_CDPRODESTO := NULL; V_QTESTCONV := 0;
         END;

         BEGIN
            SELECT NVL(NVL(P.CDALMOXARIFE, F.CDALMOXARIFE), ' '), NVL(NVL(P.CDLOCALESTOQ, F.CDLOCALESTOQ), ' ')
              INTO V_CDALMOXARIFE, V_CDLOCALESTOQ
              FROM PRODFILI P, PARAMFILIAL F
             WHERE F.CDFILIAL  = C_MOV.CDFILIMOVI
               AND P.CDFILIAL  = C_MOV.CDFILIMOVI
               AND P.CDPRODUTO = V_CDPRODESTO;
         EXCEPTION
            WHEN NO_DATA_FOUND THEN
               V_CDALMOXARIFE := ' '; V_CDLOCALESTOQ := ' ';
         END;

         /* Retorna custo do produto em estoque */
         BEGIN
            SELECT NVL(MAX(NRLOTEESTQ), ' '), NVL(MAX(NRSUBLOTE), ' '),
                   MAX(VRESTOQBRUT), MAX(QTESTOQDIA), (MAX(VRESTOQDIA)/MAX(QTESTOQDIA))
              INTO V_NRLOTEESTQ, V_NRSUBLOTE,
                   V_VRESTOQBRUT, V_QTESTOQDIA, V_VRUNITITEM
              FROM POSESTDIA P
             WHERE P.CDFILIAL     = C_MOV.CDFILIMOVI
               AND P.CDPRODUTO    = V_CDPRODESTO
               AND P.CDALMOXARIFE = V_CDALMOXARIFE
               AND P.CDLOCALESTOQ = V_CDLOCALESTOQ
               AND P.QTESTOQDIA <> 0
               AND P.DTPOSIESTQ   = (SELECT MAX(DTPOSIESTQ)
                                       FROM POSESTDIA
                                      WHERE CDFILIAL = P.CDFILIAL
                                        AND CDALMOXARIFE = P.CDALMOXARIFE
                                        AND CDLOCALESTOQ = P.CDLOCALESTOQ
                                        AND NRLOTEESTQ = P.NRLOTEESTQ
                                        AND NRSUBLOTE = P.NRSUBLOTE
                                        AND CDPRODUTO = P.CDPRODUTO
                                        AND DTPOSIESTQ <= TO_DATE(C_MOV.DTLANCAMENTO)+1);

         EXCEPTION
            WHEN NO_DATA_FOUND THEN
               V_NRLOTEESTQ := ' '; V_NRSUBLOTE := ' ';
               V_VRESTOQBRUT := 0;
         END;

         INSERT INTO ITLANCTOEST
            (CDFILIAL, NRLANCESTQ, NRSEQUITEM, IDTIPOMOVI,
             CDPRODUTO, QTTOTLANCTO,  VRUNILANCTO, VRTOTLANCTO,
             DTLANCMOVI, IDORDEMCLC, CDPRODMOVI, QTLANCTOEST,
             VRLANCTOBRUT, VRLANCTOEST, CDFILIMOVI, IDEVOLESTOQ,
             CDALMOXARIFE, CDLOCALESTOQ, NRLOTEESTQ, NRSUBLOTE,
             CDOPERADOR)
         VALUES
            (C_MOV.CDFILIMOVI, V_NRLANCESTQ, LPAD(TO_CHAR(V_NRSEQITPROD), 4, '0'), '1',
             V_CDPRODUTO, C_MOV.VALQTDE, V_VRUNITITEM, (V_VRUNITITEM * C_MOV.VALQTDE),
             C_MOV.DTLANCAMENTO, V_IDORDEMCLC, V_CDPRODESTO, V_QTESTCONV,
             (V_VRESTOQBRUT/V_QTESTOQDIA), V_VRUNITITEM, C_MOV.CDFILIMOVI, 'S',
             V_CDALMOXARIFE, V_CDLOCALESTOQ, V_NRLOTEESTQ, V_NRSUBLOTE,
             C_MOV.CDOPERADOR);

         V_NRSEQITPROD := V_NRSEQITPROD + 1;
      END IF;
   END LOOP;

   ATUALIZA_ESTOQUE(V_CDFILIMOVI, V_DATA, V_DTFINAL, V_CDFILIMOVI, V_NRLANCESTQ);

   -- Atualizar a Itlanctoest para não evoluir estoque caso encontre erro ao atualizar o estoque
   FOR C_PRODIRREG IN (SELECT M.NRMOVILOTE, M.CDFILIAL, M.CDALMOXARIFE, M.CDLOCALESTOQ,
                              M.CDPRODUTO, M.NRLOTEESTQ, M.NRSUBLOTE, P.CDARVPROD
                         FROM MOVILOTE M, PRODUTO P
                        WHERE M.NRMOVILOTE = V_CDFILIMOVI||V_NRLANCESTQ
                          AND M.CDFILIAL   = V_CDFILIMOVI
                          AND P.CDPRODUTO = M.CDPRODUTO) LOOP
      UPDATE ITLANCTOEST
         SET IDEVOLESTOQ  = 'N'
       WHERE CDFILIAL     = V_CDFILIMOVI
         AND NRLANCESTQ   = V_NRLANCESTQ
         AND CDALMOXARIFE = C_PRODIRREG.CDALMOXARIFE
         AND CDLOCALESTOQ = C_PRODIRREG.CDLOCALESTOQ
         AND CDPRODUTO    = C_PRODIRREG.CDPRODUTO
         AND NRLOTEESTQ   = C_PRODIRREG.NRLOTEESTQ
         AND NRSUBLOTE    = C_PRODIRREG.NRSUBLOTE;

         V_ERRO := V_ERRO || C_PRODIRREG.CDARVPROD || ',';

         V_IRREG := 'S';
   END LOOP;

   DELETE MOVILOTE
    WHERE NRMOVILOTE = V_CDFILIMOVI||V_NRLANCESTQ;

   IF V_IRREG = 'S' THEN
      V_ERRO := SUBSTR(TO_CHAR(V_DATA, 'DD/MM/YYYY') || '. Inventario realizado por importacao ' || V_ERRO || ' Movimentacao tornariam o estoque irregular.', 1, 4000);
   END IF;

   IF (V_ERRO IS NULL) OR (V_IRREG = 'S') THEN
      COMMIT;
   ELSE
      ROLLBACK;
   END IF;
END;
/

-- VERSAO --
BEGIN ATUVEROBJ('APP_MOBILE_IMPORTA_INVENTARIO','0.00.000'); END;
/
