CREATE OR REPLACE FUNCTION EXPORTSTRUCTURE_GOP
 (P_LFILIAL      IN VARCHAR2,
  P_NRANO        IN VARCHAR2,
  P_CDOPERADOR   IN VARCHAR2,
  P_DETAIL       IN VARCHAR2,
  P_STARTVALUE   IN FLOAT) RETURN EXPORTSTRUCTURE_GOP_TABLE PIPELINED
IS
  V_SEQ                      NUMBER;
  V_CODIGO                   VARCHAR2(50);
  V_DESCRICAO                VARCHAR2(100);
  V_CODIGOAUX                VARCHAR2(50);
  V_DESCRICAOAUX             VARCHAR2(100);
  V_DETAIL                   NUMBER;
  C_UNIDADE_IDUTILPERCFILGOP VARCHAR2(01);
  C_ITEM_NRITEMOPERACIONAL   NUMBER;
  C_UNIDADE_CDFILIAL         VARCHAR2(04);
  V_CDARVPROD                VARCHAR2(50);
  V_NMPRODUTO                VARCHAR2(100);
  V_DET                      VARCHAR2(01);
  V_IDSERVFATROP             VARCHAR2(01);
  V_CDGRUPPROD               VARCHAR2(10);
  V_EXEC                     NUMBER;
  
  CURSOR C_STRUCTURE IS
     SELECT PD.CDPRODUTO, PD.CDIMPOSTO, PD.CDTIPOOPER, PD.IDENTRSAIDOP, PD.CDINVEST,
            PD.CDDESPADMFAT, PD.CDDESPPREV, PD.CDFILIALMO, PD.IDDESPPREV, PD.CDORCAMENTOMO,
            PD.CDFATUDIVER, PD.CDSUBGRPROD, PD.CDSERVFILI, PD.CDTPCTPAGAR, PD.CDCONTCTBL,
            PD.CDGRUPPROD
       FROM PERCITEMDETALGOP PD INNER JOIN PERCITEMGOP P ON PD.NRPERCITEMGOP = P.NRPERCITEMGOP
      WHERE P.NRSEQITEMORCA = C_ITEM_NRITEMOPERACIONAL
        AND C_UNIDADE_IDUTILPERCFILGOP = 'N'
        AND ((C_ITEM_NRITEMOPERACIONAL = 3 AND PD.CDFILIALMO IS NOT NULL AND PD.CDORCAMENTOMO IS NOT NULL) OR C_ITEM_NRITEMOPERACIONAL <> 3)
        AND P_DETAIL = 'S'
      UNION
     SELECT PDF.CDPRODUTO, PDF.CDIMPOSTO, PDF.CDTIPOOPER, PDF.IDENTRSAIDOP, PDF.CDINVEST,
            PDF.CDDESPADMFAT, PDF.CDDESPPREV, PDF.CDFILIALMO, PDF.IDDESPPREV, PDF.CDORCAMENTOMO,
            PDF.CDFATUDIVER, PDF.CDSUBGRPROD, PDF.CDSERVFILI, PDF.CDTPCTPAGAR, PDF.CDCONTCTBL,
            PDF.CDGRUPPROD
       FROM PERCITFILGOP PF INNER JOIN PERCITDETALFILGOP PDF ON PDF.NRPERCITFILGOP = PF.NRPERCITFILGOP
      WHERE PDF.CDFILIAL = C_UNIDADE_CDFILIAL
        AND PF.NRSEQITEMORCA = C_ITEM_NRITEMOPERACIONAL
        AND ((PDF.CDSERVFILI IS NULL AND C_ITEM_NRITEMOPERACIONAL = 0) OR C_ITEM_NRITEMOPERACIONAL <> 0)
        AND ((C_ITEM_NRITEMOPERACIONAL = 3 AND PDF.CDFILIALMO IS NOT NULL AND PDF.CDORCAMENTOMO IS NOT NULL) OR C_ITEM_NRITEMOPERACIONAL <> 3)
        AND C_UNIDADE_IDUTILPERCFILGOP = 'S'
        AND P_DETAIL = 'S';
        
  R_STRUCTURE C_STRUCTURE%ROWTYPE;
  BO_STRUCTURE BOOLEAN := FALSE;

  OUT_RECORD EXPORTSTRUCTURE_GOP_TYPE := EXPORTSTRUCTURE_GOP_TYPE(NULL, NULL, NULL, NULL, NULL,
                                                                  NULL, NULL, NULL, NULL, NULL,
                                                                  NULL, NULL, NULL, NULL, NULL,
                                                                  NULL, NULL, NULL, NULL, NULL,
                                                                  NULL, NULL);
BEGIN
   V_SEQ := 1;
   
   FOR C_UNIDADE IN (SELECT F.CDFILIAL, NVL(F.IDUTILPERCFILGOP,'N') IDUTILPERCFILGOP, F.NRORG
                       FROM FILIAL F INNER JOIN LISTA L ON L.CDLISTA = F.CDFILIAL
                                     INNER JOIN FILIOPER O ON O.CDFILIAL = F.CDFILIAL
                                                          AND O.CDOPERADOR = P_CDOPERADOR
                      WHERE L.NRLISTA = P_LFILIAL
                        AND F.IDCNTRRESC <> 'S') LOOP
                        
      C_UNIDADE_IDUTILPERCFILGOP := C_UNIDADE.IDUTILPERCFILGOP;
      C_UNIDADE_CDFILIAL := C_UNIDADE.CDFILIAL;
      V_EXEC := 1;
                  
      SELECT NVL(MAX(IDSERVFATROP),'N'), MAX(CDGRUPPROD)
        INTO V_IDSERVFATROP, V_CDGRUPPROD
        FROM PARFILIALROP
       WHERE CDFILIAL = TIPOPARAM_DRO(C_UNIDADE.CDFILIAL);
                        
      FOR C_ITEM IN (SELECT NRITEMOPERACIONAL, IDTIPOORCAOP
                       FROM ITEMOPERACIONAL
                      ORDER BY NRITEMOPERACIONAL) LOOP
                      
         C_ITEM_NRITEMOPERACIONAL := C_ITEM.NRITEMOPERACIONAL;
         
         OPEN C_STRUCTURE;
         FETCH C_STRUCTURE INTO R_STRUCTURE;
         
         IF C_STRUCTURE%FOUND THEN
            LOOP
               EXIT WHEN C_STRUCTURE%NOTFOUND;
               V_DET := 'N';
               
               V_CDARVPROD := NULL;
               V_NMPRODUTO := NULL;
               
               IF C_ITEM.NRITEMOPERACIONAL = 0 AND V_EXEC = 1 THEN
                  V_EXEC := 2;
               
                  FOR C_DETSERV IN (SELECT S.CDSERVFILI, S.NMSERVICO
                                      FROM SERVICOROP SC, SERVICO S
                                     WHERE SC.CDFILIAL = TIPOPARAM_DRO(C_UNIDADE.CDFILIAL)
                                       AND IDTPSERVICOROP = 'E'
                                       AND V_IDSERVFATROP <> 'S'
                                       AND SC.CDSERVFILI = S.CDSERVFILI
                                       AND S.CDFILIAL = C_UNIDADE.CDFILIAL
                                     UNION
                                    SELECT S.CDSERVFILI, S.NMSERVICO
                                      FROM SERVICO S
                                     WHERE S.CDFILIAL = C_UNIDADE.CDFILIAL
                                       AND V_IDSERVFATROP = 'S'
                                       AND (QTCOMESTISEG IS NOT NULL OR
                                            QTCOMESTITER IS NOT NULL OR
                                            QTCOMESTIQUA IS NOT NULL OR
                                            QTCOMESTIQUI IS NOT NULL OR
                                            QTCOMESTISEX IS NOT NULL OR
                                            QTCOMESTISAB IS NOT NULL OR
                                            QTCOMESTIDOM IS NOT NULL OR
                                            QTCOMESTIFER IS NOT NULL)) LOOP
                     
                     OUT_RECORD.NREXPORTSTRUCTURE_GOP := V_SEQ;
                     OUT_RECORD.CDFILIAL := C_UNIDADE.CDFILIAL;
                     OUT_RECORD.NRANO := P_NRANO;
                     OUT_RECORD.CDORCAMENTO := C_ITEM.NRITEMOPERACIONAL;
                     OUT_RECORD.NMORCAMENTO := C_ITEM.IDTIPOORCAOP;
                     OUT_RECORD.CODIGO := C_DETSERV.CDSERVFILI;
                     OUT_RECORD.DESCRICAO := C_DETSERV.NMSERVICO;
                     OUT_RECORD.CDARVPROD := NULL;
                     OUT_RECORD.NMPRODUTO := NULL;
                     OUT_RECORD.JANEIRO := P_STARTVALUE;
                     OUT_RECORD.FEVEREIRO := P_STARTVALUE;
                     OUT_RECORD.MARCO := P_STARTVALUE;
                     OUT_RECORD.ABRIL := P_STARTVALUE;
                     OUT_RECORD.MAIO := P_STARTVALUE;
                     OUT_RECORD.JUNHO := P_STARTVALUE;
                     OUT_RECORD.JULHO := P_STARTVALUE;
                     OUT_RECORD.AGOSTO := P_STARTVALUE;
                     OUT_RECORD.SETEMBRO := P_STARTVALUE;
                     OUT_RECORD.OUTUBRO := P_STARTVALUE;
                     OUT_RECORD.NOVEMBRO := P_STARTVALUE;
                     OUT_RECORD.DEZEMBRO := P_STARTVALUE;
                     OUT_RECORD.NRORG := C_UNIDADE.NRORG;
                     PIPE ROW (OUT_RECORD);
               
                     V_SEQ := V_SEQ + 1;
                  END LOOP;
               END IF;
               
               IF R_STRUCTURE.CDORCAMENTOMO IS NOT NULL THEN
                  SELECT MAX(CDORCAMENTOMO), MAX(DSORCAMENTOMO)
                    INTO V_CODIGO, V_DESCRICAO
                    FROM ORCAMENTOMO
                   WHERE CDORCAMENTOMO = R_STRUCTURE.CDORCAMENTOMO
                     AND CDFILIAL = R_STRUCTURE.CDFILIALMO;
                     
                  FOR C_DET IN (SELECT DF.CDDESPADMFAT, DF.DSDESPADMFAT
                                  FROM DESPADMFATUR DF INNER JOIN DESPORCAMO DO ON DF.CDDESPADMFAT = DO.CDDESPADMFAT
                                 WHERE DO.CDFILIAL = R_STRUCTURE.CDFILIALMO
                                   AND DO.CDORCAMENTOMO = R_STRUCTURE.CDORCAMENTOMO) LOOP
                                   
                     V_DET := 'S';
                     
                     OUT_RECORD.NREXPORTSTRUCTURE_GOP := V_SEQ;
                     OUT_RECORD.CDFILIAL := C_UNIDADE.CDFILIAL;
                     OUT_RECORD.NRANO := P_NRANO;
                     OUT_RECORD.CDORCAMENTO := C_ITEM.NRITEMOPERACIONAL;
                     OUT_RECORD.NMORCAMENTO := C_ITEM.IDTIPOORCAOP;
                     OUT_RECORD.CODIGO := V_CODIGO;
                     OUT_RECORD.DESCRICAO := V_DESCRICAO;
                     OUT_RECORD.CDARVPROD := C_DET.CDDESPADMFAT;
                     OUT_RECORD.NMPRODUTO := C_DET.DSDESPADMFAT;
                     OUT_RECORD.JANEIRO := P_STARTVALUE;
                     OUT_RECORD.FEVEREIRO := P_STARTVALUE;
                     OUT_RECORD.MARCO := P_STARTVALUE;
                     OUT_RECORD.ABRIL := P_STARTVALUE;
                     OUT_RECORD.MAIO := P_STARTVALUE;
                     OUT_RECORD.JUNHO := P_STARTVALUE;
                     OUT_RECORD.JULHO := P_STARTVALUE;
                     OUT_RECORD.AGOSTO := P_STARTVALUE;
                     OUT_RECORD.SETEMBRO := P_STARTVALUE;
                     OUT_RECORD.OUTUBRO := P_STARTVALUE;
                     OUT_RECORD.NOVEMBRO := P_STARTVALUE;
                     OUT_RECORD.DEZEMBRO := P_STARTVALUE;
                     OUT_RECORD.NRORG := C_UNIDADE.NRORG;
                     PIPE ROW (OUT_RECORD);
                     
                     V_SEQ := V_SEQ + 1;
                  END LOOP;
               ELSIF R_STRUCTURE.CDSERVFILI IS NOT NULL THEN
                  SELECT MAX(CDSERVFILI), MAX(NMSERVICO)
                    INTO V_CODIGO, V_DESCRICAO
                    FROM SERVICO
                   WHERE CDSERVFILI = R_STRUCTURE.CDSERVFILI
                     AND CDFILIAL = C_UNIDADE.CDFILIAL;
               ELSIF R_STRUCTURE.CDCONTCTBL IS NOT NULL THEN
                  SELECT MAX(CDCONTCTBL), MAX(NMCONTCTBL)
                    INTO V_CODIGO, V_DESCRICAO
                    FROM CONTCTBL
                   WHERE CDCONTCTBL = R_STRUCTURE.CDCONTCTBL;
               ELSIF R_STRUCTURE.CDTPCTPAGAR IS NOT NULL THEN
                  SELECT MAX(CDTPCTPAGAR), MAX(DSTPCTPAGAR)
                    INTO V_CODIGO, V_DESCRICAO
                    FROM TIPOCTPAGAR
                   WHERE CDTPCTPAGAR = R_STRUCTURE.CDTPCTPAGAR;
               ELSIF R_STRUCTURE.CDSUBGRPROD IS NOT NULL THEN
                  SELECT MAX(CDSUBGRPROD), MAX(NMSUBGRPROD)
                    INTO V_CODIGO, V_DESCRICAO
                    FROM SUBGRUPPROD
                   WHERE CDSUBGRPROD = R_STRUCTURE.CDSUBGRPROD
                     AND CDGRUPPROD = V_CDGRUPPROD;
               ELSIF R_STRUCTURE.CDFATUDIVER IS NOT NULL THEN
                  SELECT MAX(CDFATUDIVER), MAX(DSFATUDIVER)
                    INTO V_CODIGO, V_DESCRICAO
                    FROM FATUDIVER
                   WHERE CDFATUDIVER = R_STRUCTURE.CDFATUDIVER;
               ELSIF R_STRUCTURE.CDDESPPREV IS NOT NULL THEN
                  SELECT MAX(CDDESPPREV), MAX(NMDESPPREV)
                    INTO V_CODIGO, V_DESCRICAO
                    FROM DESPPREV
                   WHERE CDDESPPREV = R_STRUCTURE.CDDESPPREV;
                     
                  FOR C_DET IN (SELECT P.CDARVPROD CDARVPROD, P.NMPRODUTO NMPRODUTO
                                  FROM PRODDESPPREV PD INNER JOIN PRODUTO P ON P.CDPRODUTO = PD.CDPRODUTO
                                 WHERE PD.CDDESPPREV = V_CODIGO
                                 UNION 
                                SELECT C.CDCONTCTBL CDARVPROD, C.NMCONTCTBL NMPRODUTO
                                  FROM CTBLDESPPREV CD INNER JOIN CONTCTBL C ON C.CDCONTCTBL = CD.CDCONTCTBL
                                 WHERE CD.CDDESPPREV = V_CODIGO
                                 UNION 
                                SELECT P.CDTPCTPAGAR CDARVPROD, P.DSTPCTPAGAR NMPRODUTO
                                  FROM TPCTPAGDESPPREV PD INNER JOIN TIPOCTPAGAR P ON P.CDTPCTPAGAR = PD.CDTPCTPAGAR
                                 WHERE PD.CDDESPPREV = V_CODIGO) LOOP

                     V_DET := 'S';
                     
                     OUT_RECORD.NREXPORTSTRUCTURE_GOP := V_SEQ;
                     OUT_RECORD.CDFILIAL := C_UNIDADE.CDFILIAL;
                     OUT_RECORD.NRANO := P_NRANO;
                     OUT_RECORD.CDORCAMENTO := C_ITEM.NRITEMOPERACIONAL;
                     OUT_RECORD.NMORCAMENTO := C_ITEM.IDTIPOORCAOP;
                     OUT_RECORD.CODIGO := V_CODIGO;
                     OUT_RECORD.DESCRICAO := V_DESCRICAO;
                     OUT_RECORD.CDARVPROD := C_DET.CDARVPROD;
                     OUT_RECORD.NMPRODUTO := C_DET.NMPRODUTO;
                     OUT_RECORD.JANEIRO := P_STARTVALUE;
                     OUT_RECORD.FEVEREIRO := P_STARTVALUE;
                     OUT_RECORD.MARCO := P_STARTVALUE;
                     OUT_RECORD.ABRIL := P_STARTVALUE;
                     OUT_RECORD.MAIO := P_STARTVALUE;
                     OUT_RECORD.JUNHO := P_STARTVALUE;
                     OUT_RECORD.JULHO := P_STARTVALUE;
                     OUT_RECORD.AGOSTO := P_STARTVALUE;
                     OUT_RECORD.SETEMBRO := P_STARTVALUE;
                     OUT_RECORD.OUTUBRO := P_STARTVALUE;
                     OUT_RECORD.NOVEMBRO := P_STARTVALUE;
                     OUT_RECORD.DEZEMBRO := P_STARTVALUE;
                     OUT_RECORD.NRORG := C_UNIDADE.NRORG;
                     PIPE ROW (OUT_RECORD);
               
                     V_SEQ := V_SEQ + 1;
                  END LOOP;
               ELSIF R_STRUCTURE.CDINVEST IS NOT NULL THEN
                  SELECT MAX(CDINVEST), MAX(NMINVEST)
                    INTO V_CODIGO, V_DESCRICAO
                    FROM INVESTIMENTOS
                   WHERE CDINVEST = R_STRUCTURE.CDINVEST;
               ELSIF R_STRUCTURE.CDTIPOOPER IS NOT NULL THEN
                  SELECT MAX(CDTIPOOPER), MAX(NMTIPOOPER)
                    INTO V_CODIGO, V_DESCRICAO
                    FROM TIPOOPERAC
                   WHERE CDTIPOOPER = R_STRUCTURE.CDTIPOOPER
                     AND IDENTRSAIDOP = R_STRUCTURE.IDENTRSAIDOP;
               ELSIF R_STRUCTURE.CDIMPOSTO IS NOT NULL THEN
                  SELECT MAX(CDIMPOSTO), MAX(NMIMPOSTO)
                    INTO V_CODIGO, V_DESCRICAO
                    FROM IMPOSTO
                   WHERE CDIMPOSTO = R_STRUCTURE.CDIMPOSTO;
               ELSIF R_STRUCTURE.CDPRODUTO IS NOT NULL THEN
                  SELECT MAX(CDARVPROD), MAX(NMPRODUTO)
                    INTO V_CODIGO, V_DESCRICAO
                    FROM PRODUTO
                   WHERE CDPRODUTO = R_STRUCTURE.CDPRODUTO;
               END IF;
               
               IF V_DET = 'N' THEN
                  OUT_RECORD.NREXPORTSTRUCTURE_GOP := V_SEQ;
                  OUT_RECORD.CDFILIAL := C_UNIDADE.CDFILIAL;
                  OUT_RECORD.NRANO := P_NRANO;
                  OUT_RECORD.CDORCAMENTO := C_ITEM.NRITEMOPERACIONAL;
                  OUT_RECORD.NMORCAMENTO := C_ITEM.IDTIPOORCAOP;
                  OUT_RECORD.CODIGO := V_CODIGO;
                  OUT_RECORD.DESCRICAO := V_DESCRICAO;
                  OUT_RECORD.CDARVPROD := NULL;
                  OUT_RECORD.NMPRODUTO := NULL;
                  OUT_RECORD.JANEIRO := P_STARTVALUE;
                  OUT_RECORD.FEVEREIRO := P_STARTVALUE;
                  OUT_RECORD.MARCO := P_STARTVALUE;
                  OUT_RECORD.ABRIL := P_STARTVALUE;
                  OUT_RECORD.MAIO := P_STARTVALUE;
                  OUT_RECORD.JUNHO := P_STARTVALUE;
                  OUT_RECORD.JULHO := P_STARTVALUE;
                  OUT_RECORD.AGOSTO := P_STARTVALUE;
                  OUT_RECORD.SETEMBRO := P_STARTVALUE;
                  OUT_RECORD.OUTUBRO := P_STARTVALUE;
                  OUT_RECORD.NOVEMBRO := P_STARTVALUE;
                  OUT_RECORD.DEZEMBRO := P_STARTVALUE;
                  OUT_RECORD.NRORG := C_UNIDADE.NRORG;
                  PIPE ROW (OUT_RECORD);
                  
                  V_SEQ := V_SEQ + 1;
               END IF;
               
               FETCH C_STRUCTURE INTO R_STRUCTURE;
            END LOOP;
         ELSE
            OUT_RECORD.NREXPORTSTRUCTURE_GOP := V_SEQ;
            OUT_RECORD.CDFILIAL := C_UNIDADE.CDFILIAL;
            OUT_RECORD.NRANO := P_NRANO;
            OUT_RECORD.CDORCAMENTO := C_ITEM.NRITEMOPERACIONAL;
            OUT_RECORD.NMORCAMENTO := C_ITEM.IDTIPOORCAOP;
            OUT_RECORD.CODIGO := NULL;
            OUT_RECORD.DESCRICAO := NULL;
            OUT_RECORD.CDARVPROD := NULL;
            OUT_RECORD.NMPRODUTO := NULL;
            OUT_RECORD.JANEIRO := P_STARTVALUE;
            OUT_RECORD.FEVEREIRO := P_STARTVALUE;
            OUT_RECORD.MARCO := P_STARTVALUE;
            OUT_RECORD.ABRIL := P_STARTVALUE;
            OUT_RECORD.MAIO := P_STARTVALUE;
            OUT_RECORD.JUNHO := P_STARTVALUE;
            OUT_RECORD.JULHO := P_STARTVALUE;
            OUT_RECORD.AGOSTO := P_STARTVALUE;
            OUT_RECORD.SETEMBRO := P_STARTVALUE;
            OUT_RECORD.OUTUBRO := P_STARTVALUE;
            OUT_RECORD.NOVEMBRO := P_STARTVALUE;
            OUT_RECORD.DEZEMBRO := P_STARTVALUE;
            OUT_RECORD.NRORG := C_UNIDADE.NRORG;
            PIPE ROW (OUT_RECORD);
            
            V_SEQ := V_SEQ + 1;
         END IF;

         CLOSE C_STRUCTURE;
      END LOOP;
   END LOOP;
END;
/