create or replace
PROCEDURE IMPORTA_PRODUCTO
IS
   V_PRODUTO    VARCHAR2(20);
   V_SGUNPROD   INTEGER;
   V_FATOCONV   FLOAT;
   V_MASCARA    VARCHAR2(20);
   V_ULTNIVEL   INTEGER;
   V_POSULTNV   INTEGER;
   V_NIVEL      VARCHAR2(1);
   V_CODEERRO   VARCHAR2(10);
   V_MENSERRO   VARCHAR2(300);
   V_PRODOK     VARCHAR2(1);
   V_MARCA      VARCHAR2(5);
   V_STRREGEXP   VARCHAR2(20);
   V_POSNVPRDCMP INTEGER;
   V_NVPRODCMP   VARCHAR2(20);
   V_POSNVPRDEST INTEGER;
   V_NVPRODEST   VARCHAR2(20);
   V_PRODSAP     VARCHAR2(20);
   
   FUNCTION INSERE_PRODUTO(P_IDPRODESTOQ IN VARCHAR2, P_PRODSAP IN VARCHAR2, P_NVPRODEST IN VARCHAR2,
                           P_NVPRODCMP IN VARCHAR2, P_NMPRODUTO IN VARCHAR2, P_SGUNIDADE IN VARCHAR2,
                           P_ULTNIVEL IN INTEGER, P_FATOCONV IN FLOAT, P_VRFATOCORR IN FLOAT,
                           P_NIVEL IN VARCHAR2, P_IDINTERFACE IN FLOAT, P_TPINTERFACE IN VARCHAR2) RETURN VARCHAR2
   IS
      V_PRODESTTAM    INTEGER;
      V_NVNOVO        VARCHAR2(20);
      V_INCLUINV      INTEGER;
      V_NIVELZERO     VARCHAR2(10);
      V_CDPRODUTO     VARCHAR2(20);
      V_TAMPROD       INTEGER;
      V_PRODNOVO      VARCHAR2(20);
      V_NIVELPRODEST  VARCHAR2(1);
      V_TAMARVPRODEST INTEGER;
      V_PRODESTNOVO   VARCHAR2(20);
      V_AJUSTE        VARCHAR2(20);
      V_PRODUTOESTOQ  VARCHAR2(20);
      V_CDPRODESTO    VARCHAR2(20);
      ARVNIVEL        INTEGER;
   BEGIN
      V_PRODESTTAM := LENGTH(P_PRODSAP);
      V_CDPRODESTO := ' ';
      
      IF (P_IDPRODESTOQ = 'S') THEN
         V_TAMARVPRODEST := LENGTH(REGEXP_REPLACE(P_NVPRODEST, '\W'));
         ARVNIVEL := 1;
      ELSE
         V_TAMARVPRODEST := LENGTH(REGEXP_REPLACE(P_NVPRODCMP, '\W'));
         ARVNIVEL := 0;
      END IF;
      
      IF (V_PRODESTTAM <> V_TAMARVPRODEST) THEN
         BEGIN
            SELECT MAX(P.CDARVPROD), P.CDNVPRODUTO, MIN(CDARVPROD)
              INTO V_PRODESTNOVO, V_NIVELPRODEST, V_PRODUTOESTOQ
              FROM PRODUTO P
             WHERE P.CDNVPRODUTO = (SELECT MIN(PR.CDNVPRODUTO)
                                      FROM PRODUTO PR
                                     WHERE REGEXP_LIKE(PR.CDARVPROD, '^'||P_PRODSAP||'\w'))
               AND REGEXP_LIKE(P.CDARVPROD, '^'||P_PRODSAP||'\w')
             GROUP BY P.CDNVPRODUTO;
            
            SELECT LENGTH(CDARVPROD)
              INTO V_TAMPROD
              FROM PRODUTO
             WHERE CDNVPRODUTO = (V_NIVELPRODEST-ARVNIVEL)
               AND ROWNUM = 1;
            
            IF P_IDPRODESTOQ = 'S' THEN
               V_AJUSTE   := SUBSTR(V_PRODESTNOVO, V_TAMPROD+1, (LENGTH(V_PRODESTNOVO)-V_TAMPROD))+1;
               V_NVNOVO   := LPAD(V_AJUSTE, (LENGTH(V_PRODESTNOVO)-V_TAMPROD), '0');
               V_PRODESTNOVO := SUBSTR(V_PRODESTNOVO,1, LENGTH(V_PRODESTNOVO)-LENGTH(V_NVNOVO));
            ELSE
               V_AJUSTE   := SUBSTR(V_PRODESTNOVO, (V_PRODESTTAM-P_ULTNIVEL))+1;
               V_NVNOVO   := LPAD(V_AJUSTE, (P_ULTNIVEL-V_PRODESTTAM),'0');
               V_PRODESTNOVO :=SUBSTR(V_PRODESTNOVO,1,(LENGTH(V_PRODESTNOVO)-(P_ULTNIVEL-V_PRODESTTAM)));
               
               SELECT CDPRODUTO
                 INTO V_CDPRODESTO
                 FROM PRODUTO
                WHERE CDARVPROD = V_PRODUTOESTOQ;
            END IF;
            
            V_PRODNOVO := V_PRODESTNOVO||V_NVNOVO;
         EXCEPTION
            WHEN OTHERS THEN
               V_PRODESTNOVO  := NULL;
               
               INSERT INTO USR_SAP_LOG(IDINTERFACE, IDSEQLOG, IDPROCESSO, DTLOG, STATUS, OBSSTATUS)
               VALUES(P_IDINTERFACE, P_TPINTERFACE, 4, SYSDATE, 1, 'Nivel inexistente en el nuestro arbol');
               
               COMMIT;
               RETURN '';
         END;
         
         IF (V_PRODESTNOVO IS NOT NULL) THEN
            WHILE V_NIVELPRODEST <= P_NIVEL LOOP
               NOVO_CODIGO('PRODUTO', V_CDPRODUTO);
               V_CDPRODUTO := SUBSTR(V_CDPRODUTO, -10);
               
               IF ((V_NIVELPRODEST = P_NIVEL) AND (TRIM(V_CDPRODESTO) IS NULL)) THEN
                  V_CDPRODESTO := V_CDPRODUTO;
               END IF;
               
               BEGIN
                  INSERT INTO PRODUTO(CDPRODUTO, CDNVPRODUTO, CDARVPROD, NMPRODUTO,
                                      SGUNIDADE, VRFATOCONV,
                                      VRPEFATOCORR, CDPRODESTO)
                  VALUES(V_CDPRODUTO, V_NIVELPRODEST, V_PRODNOVO, P_NMPRODUTO, 
                         DECODE(V_NIVELPRODEST, P_NIVEL, P_SGUNIDADE),  DECODE(V_NIVELPRODEST, P_NIVEL, P_FATOCONV), 
                         DECODE(V_NIVELPRODEST, P_NIVEL, P_VRFATOCORR), DECODE(V_NIVELPRODEST, P_NIVEL, V_CDPRODESTO));
                  COMMIT;
                  
                  V_PRODNOVO := V_PRODNOVO||LPAD('0', (P_ULTNIVEL-LENGTH(V_PRODNOVO)), '0');
                  V_NIVELPRODEST := V_NIVELPRODEST+1;
               EXCEPTION
                  WHEN OTHERS THEN
                     V_CODEERRO := SQLCODE;
                     V_MENSERRO := SQLERRM;
                     
                     INSERT INTO USR_SAP_LOG(IDINTERFACE, IDSEQLOG, IDPROCESSO, DTLOG, STATUS, OBSSTATUS)
                     VALUES(P_IDINTERFACE, P_TPINTERFACE, 4, SYSDATE, 1, 'Error al ingresar el producto. Error: '||V_CODEERRO || '- '||V_MENSERRO);
                     
                     COMMIT;
                     
                     RETURN '';
                     EXIT;
               END;
            END LOOP;
            
            RETURN V_CDPRODUTO;
         END IF;
      ELSE
         INSERT INTO USR_SAP_LOG(IDINTERFACE, IDSEQLOG, IDPROCESSO, DTLOG, STATUS, OBSSTATUS)
         VALUES(P_IDINTERFACE, P_TPINTERFACE, 4, SYSDATE, 1, 'Tama'||CHR(241)||'o del c'||CHR(243)||'digo inv'||CHR(225)||'lido');
         
         RETURN '';
      END IF;
   END;
   
BEGIN
   SELECT CDPICTPROD
     INTO V_MASCARA
     FROM PARAMGERAL
    WHERE CDPARGERAL = '0001';
   
   V_ULTNIVEL := LENGTH(REGEXP_REPLACE(V_MASCARA, '\W'));
   V_POSULTNV := LENGTH(SUBSTR(V_MASCARA, INSTR(V_MASCARA,'.', -1)-LENGTH(V_MASCARA)));
   
   V_STRREGEXP := '[^[:punct:]]*$';
   V_POSNVPRDCMP := REGEXP_INSTR(V_MASCARA, V_STRREGEXP)-2;
   V_NVPRODCMP := SUBSTR(V_MASCARA, 1, V_POSNVPRDCMP);
   V_POSNVPRDEST := REGEXP_INSTR(V_NVPRODCMP, V_STRREGEXP)-2;
   V_NVPRODEST := SUBSTR(V_MASCARA, 1, V_POSNVPRDEST);
   
   SELECT MAX(CDNVPRODUTO) CDNVPRODUTO
     INTO V_NIVEL
     FROM PRODUTO;
   
   FOR C_PRODUTOS IN
       (SELECT U.CDPRODUTO, U.CDPRODSAP, U.NMPRODUTO, U.SGUNIDADE, 
               U.IDPRODESTOQ, U.VRFATOCORR, U.VRFATOCONV, U.CDMARCA,
               U.IDINTERFACE, U.TPINTERFACE
          FROM USR_SAP_PRODUTO U
         WHERE U.DTINTERFACEDEST IS NULL
         ORDER BY U.DTINTERFACEORI)
   LOOP
      V_PRODOK := 'N';
      BEGIN
         SELECT CDMARCA
           INTO V_MARCA
           FROM MARCA
          WHERE CDMARCA = C_PRODUTOS.CDMARCA;
      EXCEPTION
         WHEN NO_DATA_FOUND THEN
            V_MARCA := NULL;
            
            INSERT INTO USR_SAP_LOG(IDINTERFACE, IDSEQLOG, IDPROCESSO, DTLOG, STATUS, OBSSTATUS)
            VALUES(C_PRODUTOS.IDINTERFACE, C_PRODUTOS.TPINTERFACE, 4, SYSDATE, 1, 'C'||CHR(243)||'digo de la marca no registrado');
      END;
      
      IF (V_MARCA IS NOT NULL) THEN
         IF (C_PRODUTOS.VRFATOCONV = 0) THEN
            V_FATOCONV := 1;
         ELSE
            V_FATOCONV := C_PRODUTOS.VRFATOCONV;
         END IF;
        
         V_PRODSAP := REGEXP_REPLACE(C_PRODUTOS.CDPRODUTO, '\W');
         BEGIN
            SELECT M.CDPRODUTO
              INTO V_PRODUTO
              FROM MARCPROD M, PRODUTO P
             WHERE M.CDPRODUTO  = P.CDPRODUTO
               AND M.CDPRODSAP  = C_PRODUTOS.CDPRODSAP
               AND M.CDMARCA    = V_MARCA
               AND P.VRFATOCONV = V_FATOCONV;
         EXCEPTION
            WHEN NO_DATA_FOUND THEN
               V_PRODUTO := NULL;
            
            WHEN TOO_MANY_ROWS THEN
               V_PRODUTO := 'ERRO';
               
               INSERT INTO USR_SAP_LOG(IDINTERFACE, IDSEQLOG, IDPROCESSO, DTLOG, STATUS, OBSSTATUS)
               VALUES(C_PRODUTOS.IDINTERFACE, C_PRODUTOS.TPINTERFACE, 4, SYSDATE, 1, 'M'||CHR(225)||'s de un producto encontrado con las mismas especificaciones');
         END;
         
         BEGIN
            IF (C_PRODUTOS.TPINTERFACE <> 'E') THEN
               IF (C_PRODUTOS.TPINTERFACE = 'I') THEN
                  SELECT COUNT(1) SGUNIDADE
                    INTO V_SGUNPROD
                    FROM UNIDMEDIDA UN
                   WHERE SGUNIDADE = C_PRODUTOS.SGUNIDADE;
                  
                  IF (V_SGUNPROD > 0) THEN
                     IF (V_PRODUTO IS NULL) THEN
                        V_PRODUTO := INSERE_PRODUTO(C_PRODUTOS.IDPRODESTOQ, V_PRODSAP, V_NVPRODEST,
                                                    V_NVPRODCMP, C_PRODUTOS.NMPRODUTO, C_PRODUTOS.SGUNIDADE,
                                                    V_ULTNIVEL, V_FATOCONV, C_PRODUTOS.VRFATOCORR,
                                                    V_NIVEL, C_PRODUTOS.IDINTERFACE, C_PRODUTOS.TPINTERFACE);
                     
                        IF (TRIM(V_PRODUTO) IS NOT NULL) THEN
                           INSERT INTO MARCPROD(CDPRODUTO, CDMARCA, CDPRODSAP)
                           VALUES(V_PRODUTO, V_MARCA, C_PRODUTOS.CDPRODSAP);
                           
                           INSERT INTO USR_SAP_LOG(IDINTERFACE, IDSEQLOG, IDPROCESSO, DTLOG, STATUS, OBSSTATUS)
                           VALUES(C_PRODUTOS.IDINTERFACE, C_PRODUTOS.TPINTERFACE, 4, SYSDATE, 0, 'Producto '|| C_PRODUTOS.CDPRODUTO ||' registrado con '||CHR(233)||'xito.');
                           
                           V_PRODOK := 'S';
                        END IF;
                     ELSE
                        IF V_PRODUTO <> 'ERRO' THEN
                           INSERT INTO USR_SAP_LOG(IDINTERFACE, IDSEQLOG, IDPROCESSO, DTLOG, STATUS, OBSSTATUS)
                           VALUES(C_PRODUTOS.IDINTERFACE, C_PRODUTOS.TPINTERFACE, 4, SYSDATE, 1, 'Producto ya registrado');
                        END IF;
                     END IF;
                  ELSE
                     INSERT INTO USR_SAP_LOG(IDINTERFACE, IDSEQLOG, IDPROCESSO, DTLOG, STATUS, OBSSTATUS)
                     VALUES(C_PRODUTOS.IDINTERFACE, C_PRODUTOS.TPINTERFACE, 4, SYSDATE, 1, 'Unidad de medida inexistente');
                  END IF;
               ELSE
                  IF (V_PRODUTO IS NOT NULL) THEN
                     UPDATE PRODUTO
                        SET VRPEFATOCORR = NVL(TRIM(C_PRODUTOS.VRFATOCORR), 0)
                      WHERE CDPRODUTO = V_PRODUTO;
                     
                     INSERT INTO USR_SAP_LOG(IDINTERFACE, IDSEQLOG, IDPROCESSO, DTLOG, STATUS, OBSSTATUS)
                     VALUES(C_PRODUTOS.IDINTERFACE, C_PRODUTOS.TPINTERFACE, 4, SYSDATE, 0, 'Producto atualizado con '||CHR(233)||'xito');
                     
                     V_PRODOK := 'S';
                  ELSE
                     BEGIN
                        SELECT CDPRODUTO
                          INTO V_PRODUTO
                          FROM PRODUTO
                         WHERE REGEXP_LIKE(CDARVPROD, '^'||V_PRODSAP||'\w')
                           AND VRFATOCONV = V_FATOCONV
                           AND SGUNIDADE = C_PRODUTOS.SGUNIDADE;
                     EXCEPTION
                        WHEN TOO_MANY_ROWS THEN
                           V_PRODUTO := NULL;
                           INSERT INTO USR_SAP_LOG(IDINTERFACE, IDSEQLOG, IDPROCESSO, DTLOG, STATUS, OBSSTATUS)
                           VALUES(C_PRODUTOS.IDINTERFACE, C_PRODUTOS.TPINTERFACE, 4, SYSDATE, 1, 'M'||CHR(225)||'s de un producto encontrado con las mismas especificaciones');
                           
                        WHEN NO_DATA_FOUND THEN
                           V_PRODUTO := NULL;
                           INSERT INTO USR_SAP_LOG(IDINTERFACE, IDSEQLOG, IDPROCESSO, DTLOG, STATUS, OBSSTATUS)
                           VALUES(C_PRODUTOS.IDINTERFACE, C_PRODUTOS.TPINTERFACE, 4, SYSDATE, 1, 'Producto a ser actualizado no existe');
                     END;
                     
                     IF (V_PRODUTO IS NOT NULL) THEN
                        UPDATE PRODUTO
                           SET VRPEFATOCORR = NVL(TRIM(C_PRODUTOS.VRFATOCORR), 0)
                         WHERE CDPRODUTO = V_PRODUTO;
                         
                        INSERT INTO MARCPROD(CDPRODUTO, CDMARCA, CDPRODSAP)
                        VALUES(V_PRODUTO, V_MARCA, C_PRODUTOS.CDPRODSAP);
                     END IF;
                  END IF;
               END IF;
            ELSE
               IF (V_PRODUTO IS NOT NULL) THEN
                  DELETE FROM MARCPROD CASCADE
                   WHERE CDPRODUTO  = V_PRODUTO
                     AND CDMARCA    = V_MARCA;
                  
                  DELETE FROM QFOMARPROD CASCADE
                   WHERE CDPRODUTO = V_PRODUTO;
                  
                  DELETE FROM PRODUTO CASCADE
                   WHERE CDPRODUTO = V_PRODUTO;
                  
                  INSERT INTO USR_SAP_LOG(IDINTERFACE, IDSEQLOG, IDPROCESSO, DTLOG, STATUS, OBSSTATUS)
                  VALUES(C_PRODUTOS.IDINTERFACE, C_PRODUTOS.TPINTERFACE, 4, SYSDATE, 0, 'Producto excluido con '||CHR(233)||'xito');
                  
                  V_PRODOK := 'S';
               ELSE
                  INSERT INTO USR_SAP_LOG(IDINTERFACE, IDSEQLOG, IDPROCESSO, DTLOG, STATUS, OBSSTATUS)
                  VALUES(C_PRODUTOS.IDINTERFACE, C_PRODUTOS.TPINTERFACE, 4, SYSDATE, 1, 'Producto a ser excluido no existe');
               END IF;
            END IF;
         EXCEPTION
            WHEN OTHERS THEN
               V_PRODOK := 'N';
               V_CODEERRO := SQLCODE;
               V_MENSERRO := SQLERRM;
               INSERT INTO USR_SAP_LOG(IDINTERFACE, IDSEQLOG, IDPROCESSO, DTLOG, STATUS, OBSSTATUS)
               VALUES(C_PRODUTOS.IDINTERFACE, C_PRODUTOS.TPINTERFACE, 4, SYSDATE, 1, 'Error en la importaci'||CHR(243)||'n de productos. Error: '||V_CODEERRO || '- '||V_MENSERRO);
               
               COMMIT;
         END;
      
      END IF;
      
      IF (V_PRODOK = 'S') THEN
         UPDATE USR_SAP_PRODUTO SET DTINTERFACEDEST = SYSDATE, STATUS = 0
          WHERE IDINTERFACE = C_PRODUTOS.IDINTERFACE;
      ELSE
         UPDATE USR_SAP_PRODUTO SET STATUS = 2
          WHERE IDINTERFACE = C_PRODUTOS.IDINTERFACE;
      END IF;
   END LOOP;
   
   COMMIT;
END;
/

-- VERSAO --
BEGIN ATUVEROBJ('IMPORTA_PRODUCTO','5.45.XXX'); END;
/