CREATE OR REPLACE FUNCTION MAX_NIVEL(P_MASCARA VARCHAR2) RETURN VARCHAR2
AS    
   V_DIGITO VARCHAR2(1);   
   V_TAM_MASCARA NUMBER;
   V_NUM_NIVEIS NUMBER;
BEGIN
   V_NUM_NIVEIS := 0;   
   IF(P_MASCARA IS NOT NULL) THEN
      V_TAM_MASCARA := LENGTH(P_MASCARA);      
      V_DIGITO := '';
      FOR I IN 1..V_TAM_MASCARA LOOP         
         V_DIGITO := SUBSTR(P_MASCARA, I, 1);
         IF(V_DIGITO = '.') THEN            
            V_NUM_NIVEIS := V_NUM_NIVEIS + 1;
         ELSE
            IF I = V_TAM_MASCARA THEN 
               V_NUM_NIVEIS := V_NUM_NIVEIS + 1;
            END IF;
         END IF;
      END LOOP;      
   END IF;

   RETURN V_NUM_NIVEIS;
END;
/

CREATE OR REPLACE FUNCTION NIVEL_ANTERIOR(P_MASCARA VARCHAR2,  
                        P_CAMPO VARCHAR2) RETURN VARCHAR2
AS
   V_MASCARA_SEM_SEP VARCHAR2(20);
   V_COD_NIVEL VARCHAR2(20);
   V_COD_NIVEL_ANT VARCHAR2(20);
   V_TAM_MASCARA NUMBER;
   V_TAM_CAMPO NUMBER;
   V_POS_CAMPO NUMBER;
   V_DIGITO VARCHAR2(1);   
BEGIN   
   IF(P_MASCARA IS NOT NULL AND P_CAMPO IS NOT NULL) THEN

      V_MASCARA_SEM_SEP := REPLACE(P_MASCARA, '.', '');
      V_TAM_MASCARA := LENGTH(V_MASCARA_SEM_SEP);
      V_TAM_CAMPO := LENGTH(P_CAMPO);
      IF V_TAM_MASCARA - V_TAM_CAMPO < 0 THEN
         RETURN NULL;
      END IF;

      V_TAM_MASCARA := LENGTH(P_MASCARA);

      V_COD_NIVEL_ANT := '';
      V_COD_NIVEL := '';   
      V_POS_CAMPO := 1;      
      V_DIGITO := '';
      FOR I IN 1..V_TAM_MASCARA LOOP
         IF V_POS_CAMPO > V_TAM_CAMPO THEN
            EXIT;
         END IF;         
         V_DIGITO := SUBSTR(P_MASCARA, I, 1);
         IF(V_DIGITO = '.') THEN            
            V_COD_NIVEL_ANT := V_COD_NIVEL_ANT || V_COD_NIVEL;
            V_COD_NIVEL := '';
         ELSE
            V_COD_NIVEL := V_COD_NIVEL || SUBSTR(P_CAMPO, V_POS_CAMPO, 1);
            V_POS_CAMPO := V_POS_CAMPO + 1;
         END IF; 
      END LOOP;
      RETURN V_COD_NIVEL_ANT;
   END IF;

   RETURN NULL;
END;
/

CREATE OR REPLACE FUNCTION VALOR_NA_LISTA
(
  P_VALOR IN VARCHAR2,
  P_LISTA IN VARCHAR2,
  P_DELIMIT IN VARCHAR2 DEFAULT '_',
  P_TODOS IN VARCHAR2 DEFAULT 'T'
)
RETURN NUMBER
AS
V_EXISTE NUMBER;
BEGIN
  IF (P_LISTA = P_TODOS) THEN
    RETURN 1;
  END IF;
  
  IF (SUBSTR(P_LISTA, 0, 9) = '_NRLISTA=') THEN
    SELECT COUNT(1) INTO V_EXISTE 
      FROM LISTA
        WHERE NRLISTA = SUBSTR(P_LISTA, 10)
          AND CDLISTA = P_VALOR;    
    RETURN V_EXISTE;
  END IF;
  
  SELECT COUNT(1) INTO V_EXISTE 
    FROM DUAL
   WHERE REGEXP_SUBSTR(P_LISTA,'[^'||P_DELIMIT||']+', 1, LEVEL) = P_VALOR
   CONNECT BY REGEXP_SUBSTR(P_LISTA, '[^'||P_DELIMIT||']+', 1, LEVEL) IS NOT NULL;

  RETURN V_EXISTE;
END;
/


CREATE OR REPLACE FUNCTION MSG
(
P_CODIGO IN VARCHAR2,
P_PARAM00 IN VARCHAR2 DEFAULT NULL,
P_PARAM01 IN VARCHAR2 DEFAULT NULL,
P_PARAM02 IN VARCHAR2 DEFAULT NULL,
P_PARAM03 IN VARCHAR2 DEFAULT NULL,
P_PARAM04 IN VARCHAR2 DEFAULT NULL,
P_PARAM05 IN VARCHAR2 DEFAULT NULL,
P_PARAM06 IN VARCHAR2 DEFAULT NULL,
P_PARAM07 IN VARCHAR2 DEFAULT NULL,
P_PARAM08 IN VARCHAR2 DEFAULT NULL,
P_PARAM09 IN VARCHAR2 DEFAULT NULL,
P_PARAM10 IN VARCHAR2 DEFAULT NULL,
P_PARAM11 IN VARCHAR2 DEFAULT NULL,
P_PARAM12 IN VARCHAR2 DEFAULT NULL,
P_PARAM13 IN VARCHAR2 DEFAULT NULL,
P_PARAM14 IN VARCHAR2 DEFAULT NULL,
P_PARAM15 IN VARCHAR2 DEFAULT NULL,
P_PARAM16 IN VARCHAR2 DEFAULT NULL,
P_PARAM17 IN VARCHAR2 DEFAULT NULL,
P_PARAM18 IN VARCHAR2 DEFAULT NULL,
P_PARAM19 IN VARCHAR2 DEFAULT NULL,
P_PARAM20 IN VARCHAR2 DEFAULT NULL
)
RETURN VARCHAR2
AS
   V_MSG VARCHAR2(4000);
   V_INIMSG VARCHAR2(30);
   V_FIMMSG VARCHAR2(30);
   V_PARAMSEPARATOR VARCHAR2(30);
BEGIN
   V_INIMSG := '_MSGSTA_';
   V_FIMMSG := '_MSGEND_';
   V_PARAMSEPARATOR := '$$';

   IF P_CODIGO IS NOT NULL AND LENGTH(P_CODIGO) + LENGTH(V_INIMSG) + LENGTH(V_FIMMSG) <= 4000 THEN     
      
      V_MSG := V_INIMSG;

      V_MSG := V_MSG || P_CODIGO;

      IF P_PARAM00 IS NOT NULL AND (LENGTH(V_MSG) + LENGTH(V_PARAMSEPARATOR || P_PARAM00 || V_FIMMSG) <= 4000) THEN
         V_MSG := V_MSG || V_PARAMSEPARATOR || P_PARAM00;
      END IF;
      IF P_PARAM01 IS NOT NULL AND (LENGTH(V_MSG) + LENGTH(V_PARAMSEPARATOR || P_PARAM01 || V_FIMMSG) <= 4000) THEN
         V_MSG := V_MSG || V_PARAMSEPARATOR || P_PARAM01;
      END IF;
      IF P_PARAM02 IS NOT NULL AND (LENGTH(V_MSG) + LENGTH(V_PARAMSEPARATOR || P_PARAM02 || V_FIMMSG) <= 4000) THEN
         V_MSG := V_MSG || V_PARAMSEPARATOR || P_PARAM02;
      END IF;
      IF P_PARAM03 IS NOT NULL AND (LENGTH(V_MSG) + LENGTH(V_PARAMSEPARATOR || P_PARAM03 || V_FIMMSG) <= 4000) THEN
         V_MSG := V_MSG || V_PARAMSEPARATOR || P_PARAM03;
      END IF;
      IF P_PARAM04 IS NOT NULL AND (LENGTH(V_MSG) + LENGTH(V_PARAMSEPARATOR || P_PARAM04 || V_FIMMSG) <= 4000) THEN
         V_MSG := V_MSG || V_PARAMSEPARATOR || P_PARAM04;
      END IF;
      IF P_PARAM05 IS NOT NULL AND (LENGTH(V_MSG) + LENGTH(V_PARAMSEPARATOR || P_PARAM05 || V_FIMMSG) <= 4000) THEN
         V_MSG := V_MSG || V_PARAMSEPARATOR || P_PARAM05;
      END IF;
      IF P_PARAM06 IS NOT NULL AND (LENGTH(V_MSG) + LENGTH(V_PARAMSEPARATOR || P_PARAM06 || V_FIMMSG) <= 4000) THEN
         V_MSG := V_MSG || V_PARAMSEPARATOR || P_PARAM06;
      END IF;
      IF P_PARAM07 IS NOT NULL AND (LENGTH(V_MSG) + LENGTH(V_PARAMSEPARATOR || P_PARAM07 || V_FIMMSG) <= 4000) THEN
         V_MSG := V_MSG || V_PARAMSEPARATOR || P_PARAM07;
      END IF;
      IF P_PARAM08 IS NOT NULL AND (LENGTH(V_MSG) + LENGTH(V_PARAMSEPARATOR || P_PARAM08 || V_FIMMSG) <= 4000) THEN
         V_MSG := V_MSG || V_PARAMSEPARATOR || P_PARAM08;
      END IF;
      IF P_PARAM09 IS NOT NULL AND (LENGTH(V_MSG) + LENGTH(V_PARAMSEPARATOR || P_PARAM09 || V_FIMMSG) <= 4000) THEN
         V_MSG := V_MSG || V_PARAMSEPARATOR || P_PARAM09;
      END IF;
      IF P_PARAM10 IS NOT NULL AND (LENGTH(V_MSG) + LENGTH(V_PARAMSEPARATOR || P_PARAM10 || V_FIMMSG) <= 4000) THEN
         V_MSG := V_MSG || V_PARAMSEPARATOR || P_PARAM10;
      END IF;
      IF P_PARAM11 IS NOT NULL AND (LENGTH(V_MSG) + LENGTH(V_PARAMSEPARATOR || P_PARAM11 || V_FIMMSG) <= 4000) THEN
         V_MSG := V_MSG || V_PARAMSEPARATOR || P_PARAM11;
      END IF;
      IF P_PARAM12 IS NOT NULL AND (LENGTH(V_MSG) + LENGTH(V_PARAMSEPARATOR || P_PARAM12 || V_FIMMSG) <= 4000) THEN
         V_MSG := V_MSG || V_PARAMSEPARATOR || P_PARAM12;
      END IF;
      IF P_PARAM13 IS NOT NULL AND (LENGTH(V_MSG) + LENGTH(V_PARAMSEPARATOR || P_PARAM13 || V_FIMMSG) <= 4000) THEN
         V_MSG := V_MSG || V_PARAMSEPARATOR || P_PARAM13;
      END IF;
      IF P_PARAM14 IS NOT NULL AND (LENGTH(V_MSG) + LENGTH(V_PARAMSEPARATOR || P_PARAM14 || V_FIMMSG) <= 4000) THEN
         V_MSG := V_MSG || V_PARAMSEPARATOR || P_PARAM14;
      END IF;
      IF P_PARAM15 IS NOT NULL AND (LENGTH(V_MSG) + LENGTH(V_PARAMSEPARATOR || P_PARAM15 || V_FIMMSG) <= 4000) THEN
         V_MSG := V_MSG || V_PARAMSEPARATOR || P_PARAM15;
      END IF;
      IF P_PARAM16 IS NOT NULL AND (LENGTH(V_MSG) + LENGTH(V_PARAMSEPARATOR || P_PARAM16 || V_FIMMSG) <= 4000) THEN
         V_MSG := V_MSG || V_PARAMSEPARATOR || P_PARAM16;
      END IF;
      IF P_PARAM17 IS NOT NULL AND (LENGTH(V_MSG) + LENGTH(V_PARAMSEPARATOR || P_PARAM17 || V_FIMMSG) <= 4000) THEN
         V_MSG := V_MSG || V_PARAMSEPARATOR || P_PARAM17;
      END IF;
      IF P_PARAM18 IS NOT NULL AND (LENGTH(V_MSG) + LENGTH(V_PARAMSEPARATOR || P_PARAM18 || V_FIMMSG) <= 4000) THEN
         V_MSG := V_MSG || V_PARAMSEPARATOR || P_PARAM18;
      END IF;
      IF P_PARAM19 IS NOT NULL AND (LENGTH(V_MSG) + LENGTH(V_PARAMSEPARATOR || P_PARAM19 || V_FIMMSG) <= 4000) THEN
         V_MSG := V_MSG || V_PARAMSEPARATOR || P_PARAM19;
      END IF;
      IF P_PARAM20 IS NOT NULL AND (LENGTH(V_MSG) + LENGTH(V_PARAMSEPARATOR || P_PARAM20 || V_FIMMSG) <= 4000) THEN
         V_MSG := V_MSG || V_PARAMSEPARATOR || P_PARAM20;
      END IF;

      V_MSG := V_MSG || V_FIMMSG;
            
      RETURN V_MSG;
   END IF;
   RETURN NULL;
END;
/


CREATE OR REPLACE FUNCTION RECE_UTIL_TCO
(P_CDFILAUXPRAT IN VARCHAR2,
 P_CDPRATO IN VARCHAR2,
 P_CDFILIAL IN VARCHAR2,
 P_NRSERVICOPROPOSTA IN VARCHAR2,
 P_NRPADRAOQUALIDADE IN NUMBER,  
 P_CDREGIAO IN VARCHAR2,
 P_NRCARDAPIOTRAB IN NUMBER) RETURN VARCHAR2
AS
   V_EXISTE NUMBER := 0;
   V_CDFILIAL VARCHAR2(4);
   V_CDSERVFILI VARCHAR2(5);
BEGIN
   IF P_NRCARDAPIOTRAB IS NOT NULL THEN
      SELECT COUNT(1)
        INTO V_EXISTE
        FROM RECEPRATCARDTRAB
       WHERE NRCARDAPIOTRAB = P_NRCARDAPIOTRAB
         AND CDFILAUXPRAT = P_CDFILAUXPRAT
         AND CDPRATO = P_CDPRATO;
      IF V_EXISTE > 0 THEN
         RETURN 'C';
      END IF;
   END IF;
   IF V_EXISTE = 0 THEN
      IF P_NRPADRAOQUALIDADE IS NOT NULL THEN
         IF P_CDREGIAO IS NOT NULL THEN
            SELECT COUNT(1)
              INTO V_EXISTE
              FROM RECEREGIAO
             WHERE CDFILAUXPRAT = P_CDFILAUXPRAT
               AND CDPRATO = P_CDPRATO
               AND NRPADRAOQUALIDADE = P_NRPADRAOQUALIDADE
               AND CDREGIAO = P_CDREGIAO;
            IF V_EXISTE > 0 THEN
               RETURN 'R';
            END IF;
         END IF;
         
         IF V_EXISTE = 0 THEN
            SELECT COUNT(1)
              INTO V_EXISTE
              FROM RECEPADQUALI
             WHERE CDFILAUXPRAT = P_CDFILAUXPRAT
               AND CDPRATO = P_CDPRATO
               AND NRPADRAOQUALIDADE = P_NRPADRAOQUALIDADE;
            IF V_EXISTE > 0 THEN
               RETURN 'Q';
            END IF;
         END IF;
      END IF;

      IF V_EXISTE = 0 AND P_NRSERVICOPROPOSTA IS NOT NULL THEN
         SELECT MAX(CDFILIAL), MAX(CDSERVFILI)
           INTO V_CDFILIAL, V_CDSERVFILI
           FROM SERVICOPROPOSTA
          WHERE NRSERVICOPROPOSTA = P_NRSERVICOPROPOSTA;

         IF V_CDFILIAL IS NOT NULL AND V_CDSERVFILI IS NOT NULL THEN
            SELECT COUNT(1)
              INTO V_EXISTE
              FROM RECESERV
             WHERE CDFILAUXPRAT = P_CDFILAUXPRAT
               AND CDPRATO = P_CDPRATO
               AND CDFILIAL = V_CDFILIAL
               AND CDSERVFILI = V_CDSERVFILI;
            IF V_EXISTE > 0 THEN
               RETURN 'S';
            END IF;   
         END IF;
      END IF;

      IF V_EXISTE = 0 AND P_CDFILIAL IS NOT NULL THEN
         SELECT COUNT(1)
           INTO V_EXISTE
           FROM RECEFILI
          WHERE CDFILAUXPRAT = P_CDFILAUXPRAT
            AND CDPRATO = P_CDPRATO
            AND CDFILIAL = P_CDFILIAL;
         IF V_EXISTE > 0 THEN
            RETURN 'F';
         END IF;
      END IF;
      
      IF V_EXISTE = 0 THEN
         SELECT COUNT(1)
           INTO V_EXISTE
           FROM RECEPADR
          WHERE CDFILAUXPRAT = P_CDFILAUXPRAT
            AND CDPRATO = P_CDPRATO;
         IF V_EXISTE > 0 THEN
            RETURN 'P';
         END IF;
      END IF;
   END IF;

   RETURN NULL;
END;
/


CREATE OR REPLACE FUNCTION RETORNA_NOVO_CODIGO
(P_CDCONTADOR IN VARCHAR2,
 P_QTDE IN FLOAT,
 P_TAM IN FLOAT DEFAULT 20) RETURN VARCHAR2
AS
V_SEQ VARCHAR2(20);
BEGIN
   IF P_QTDE > 0 THEN
      NOVO_CODIGO_NT(P_CDCONTADOR, V_SEQ, NVL(P_QTDE, 1));   
      IF P_TAM < 20 THEN
         IF P_TAM < 0 THEN
            RETURN V_SEQ;
         ELSE
            RETURN SUBSTR(V_SEQ, (-1 * P_TAM));
         END IF;
      END IF;
      RETURN V_SEQ;
   END IF;
   RETURN NULL;
END;
/

CREATE OR REPLACE FUNCTION SEGMENTO_CARDBASE(P_NRCARDAPIOBASE IN NUMBER) RETURN VARCHAR2
AS
   V_SEGMENTOS VARCHAR2(1000);
BEGIN
   V_SEGMENTOS := '';
   FOR C_SEGS IN
   (SELECT S.DSSEGMER
      FROM SEGMERCARDBASE SC
           INNER JOIN SEGMERCADO S ON S.CDSEGMER = SC.CDSEGMER
     WHERE SC.NRCARDAPIOBASE = P_NRCARDAPIOBASE
     ORDER BY S.DSSEGMER) LOOP
      --Separador de valores
      IF LENGTH(V_SEGMENTOS) > 0 THEN
         V_SEGMENTOS := V_SEGMENTOS || ', ';
      END IF;
      -- Terminador caso limite tenha sido atingido
      IF LENGTH(V_SEGMENTOS) + LENGTH(C_SEGS.DSSEGMER) > 1000 THEN         
         V_SEGMENTOS := V_SEGMENTOS || SUBSTR(C_SEGS.DSSEGMER, 1, 995) || '(...)';
      ELSE
         V_SEGMENTOS := V_SEGMENTOS || C_SEGS.DSSEGMER;
      END IF;
   END LOOP;
   RETURN V_SEGMENTOS;
END;
/


CREATE OR REPLACE PROCEDURE IMPORTAR_CARDBASE
(P_NRCARDAPIOBASEORI IN NUMBER,
P_NRCARDAPIOBASEDEST IN NUMBER,
P_COLUNAS IN VARCHAR2,
P_COMPOSICAO IN VARCHAR2,
P_REGRAS IN VARCHAR2,
P_CDOPERADOR IN VARCHAR2,
P_NRORG IN NUMBER)
AS
   V_QTDIASORI NUMBER;
   V_QTDIASDEST NUMBER;
   V_QTDE NUMBER;
   V_QTDE_A_INCLUIR NUMBER;
   V_I NUMBER;
   V_MAX_SEMANA NUMBER;
   V_MAX_DIASEMANA NUMBER;
   V_SEMANA NUMBER;
   V_DIA NUMBER;
   V_NRDIACARDBASE NUMBER;
   V_NRCONFIGCARDBASE NUMBER;
   V_NRCOMPCARDBASE NUMBER;
   V_NRCOMPCARDBASEORI NUMBER;
   V_NRPRATCOMPCARDBASE NUMBER;
   V_NRREGIAOPRATCARDBASE NUMBER;
   V_NRADESAOCARDBASE NUMBER;
   V_NRSEGMERADESAOCBASE NUMBER;
   V_NRATIVCLIADESAOCBASE NUMBER;
   V_NRITEMADESAOCBASE NUMBER;
   V_NRGRAMATURACARDBASE NUMBER;
   V_NRGRAMATURACARDBASE_EXISTE NUMBER;
   V_NRITEMGRAMCARDBASE NUMBER;
   V_NRPARTSEGCARDBASE NUMBER;
   V_NRPARTSEG_EXISTE NUMBER;
   V_NRITPARTSEGCARDBASE NUMBER;
   V_NRAMOSTRACARDBASE NUMBER;
   V_NRDESCARTCARDBASE NUMBER;
   V_NRLIMPEZACARDBASE NUMBER;   
   V_NRORDEM NUMBER;
   V_CDADESAOCARDBASE VARCHAR2(5);
   V_CDPARTSEGCARDBASE VARCHAR2(5);
   V_NRAMOSTRACARDBASEORI NUMBER;
   V_NRCONFIGCARDBASEQ NUMBER;
   V_NRCONFIGCARDBASEF NUMBER;
   V_DE_PARA_CONFIG VARCHAR2(10);
BEGIN
--=========================================================
--=== Ajuste da quantidade de dias
--=========================================================
   -- Verifica necessidade de incrementar o número de dias      
   IF P_COMPOSICAO = 'S' THEN      
      SELECT COUNT(1)
        INTO V_QTDIASORI
        FROM DIACARDBASE
       WHERE NRCARDAPIOBASE = P_NRCARDAPIOBASEORI;

      SELECT COUNT(1), MAX(NRSEMANA)
        INTO V_QTDIASDEST, V_MAX_SEMANA
        FROM DIACARDBASE
       WHERE NRCARDAPIOBASE = P_NRCARDAPIOBASEDEST;         

      IF V_QTDIASDEST < V_QTDIASORI THEN
         SELECT MAX(NRDIASEMANA)
           INTO V_MAX_DIASEMANA
           FROM DIACARDBASE
          WHERE NRCARDAPIOBASE = P_NRCARDAPIOBASEDEST
            AND NRSEMANA = V_MAX_SEMANA;

         V_SEMANA := NVL(V_MAX_SEMANA, 1);
         V_DIA := NVL(V_MAX_DIASEMANA, 0) + 1;
         IF V_DIA > 7 THEN
            V_DIA := 1;
            V_SEMANA := V_SEMANA + 1;
         END IF;

         V_QTDE_A_INCLUIR := V_QTDIASORI - V_QTDIASDEST;

         V_I := 1;
         FOR V_I IN 1..V_QTDE_A_INCLUIR LOOP
            --Inclusão dos dias no cardápio
            V_NRDIACARDBASE := TO_NUMBER(RETORNA_NOVO_CODIGO('DIACARDBASE', 1));   

            INSERT INTO DIACARDBASE
            (NRDIACARDBASE, NRCARDAPIOBASE, NRSEMANA, NRDIASEMANA,
             NRORG, NRORGINCLUSAO, NRORGULTATU,
             CDOPERINCLUSAO, CDOPERULTATU,
             DTINCLUSAO, DTULTATU)
            VALUES
            (V_NRDIACARDBASE, P_NRCARDAPIOBASEDEST, V_SEMANA, V_DIA,
             P_NRORG, P_NRORG, P_NRORG,
             P_CDOPERADOR, P_CDOPERADOR,
             SYSDATE, SYSDATE);

            V_DIA := V_DIA + 1;
            IF V_DIA > 7 THEN
               V_DIA := 1;
               V_SEMANA := V_SEMANA + 1;
            END IF;
         END LOOP;
      END IF;
   END IF;
--=========================================================
--=== Inclusão da configuração
--=========================================================      
   SELECT MAX(NRORDEM)
     INTO V_NRORDEM
     FROM CONFIGCARDBASE
    WHERE NRCARDAPIOBASE = P_NRCARDAPIOBASEDEST;

   V_NRORDEM := NVL(V_NRORDEM, 0) + 1;

   V_DE_PARA_CONFIG := RETORNA_NOVO_CODIGO('LISTA', 1, 10);

   FOR C_CONF IN
   (
      SELECT C.NRCONFIGCARDBASE AS NRCONFIGCARDBASEORI, C.CDTIPOPRAT, C.DSCOMPLEMENTO,
             C.IDCLASSIFICACAO, C.NRORDEM, C.IDTEMPERATURA
      FROM CONFIGCARDBASE C
      WHERE C.NRCARDAPIOBASE = P_NRCARDAPIOBASEORI
        AND VALOR_NA_LISTA(C.NRCONFIGCARDBASE, NVL(P_COLUNAS, 'T')) > 0
      ORDER BY C.NRORDEM
   ) LOOP

      V_NRCONFIGCARDBASE := TO_NUMBER(RETORNA_NOVO_CODIGO('CONFIGCARDBASE', 1));

      INSERT INTO CONFIGCARDBASE
      (NRCONFIGCARDBASE, NRCARDAPIOBASE, CDTIPOPRAT,DSCOMPLEMENTO,
       IDCLASSIFICACAO, NRORDEM, IDTEMPERATURA,
       NRORG, NRORGINCLUSAO, NRORGULTATU,
       CDOPERINCLUSAO, CDOPERULTATU,
       DTINCLUSAO, DTULTATU)
      VALUES
      (V_NRCONFIGCARDBASE, P_NRCARDAPIOBASEDEST, C_CONF.CDTIPOPRAT, C_CONF.DSCOMPLEMENTO,
       C_CONF.IDCLASSIFICACAO, V_NRORDEM, C_CONF.IDTEMPERATURA,
       P_NRORG, P_NRORG, P_NRORG,
       P_CDOPERADOR, P_CDOPERADOR,
       SYSDATE, SYSDATE);


      
   --=========================================================
   --=== Inclusão da composição, se solicitada
   --=========================================================
      IF P_COMPOSICAO = 'S' THEN

         FOR C_DIA IN
         (
            SELECT D.NRDIACARDBASE, DO.NRDIACARDBASE AS NRDIACARDBASEORI
              FROM DIACARDBASE D
                   INNER JOIN DIACARDBASE DO ON DO.NRCARDAPIOBASE = P_NRCARDAPIOBASEORI AND
                                                DO.NRSEMANA = D.NRSEMANA AND
                                                DO.NRDIASEMANA = D.NRDIASEMANA
             WHERE D.NRCARDAPIOBASE = P_NRCARDAPIOBASEDEST
               AND DO.NRCARDAPIOBASE = P_NRCARDAPIOBASEORI                  
         ) LOOP
            SELECT MAX(NRCOMPCARDBASE)
              INTO V_NRCOMPCARDBASEORI
              FROM COMPCARDBASE
             WHERE NRCARDAPIOBASE = P_NRCARDAPIOBASEORI
               AND NRCONFIGCARDBASE = C_CONF.NRCONFIGCARDBASEORI
               AND NRDIACARDBASE = C_DIA.NRDIACARDBASEORI;
            IF V_NRCOMPCARDBASEORI IS NOT NULL THEN
               V_NRCOMPCARDBASE := TO_NUMBER(RETORNA_NOVO_CODIGO('COMPCARDBASE', 1));

               INSERT INTO COMPCARDBASE
               (NRCOMPCARDBASE, NRCARDAPIOBASE, NRDIACARDBASE, NRCONFIGCARDBASE,
                NRORG, NRORGINCLUSAO, NRORGULTATU,
                CDOPERINCLUSAO, CDOPERULTATU,
                DTINCLUSAO, DTULTATU)
               VALUES
               (V_NRCOMPCARDBASE, P_NRCARDAPIOBASEDEST, C_DIA.NRDIACARDBASE, V_NRCONFIGCARDBASE,
                P_NRORG, P_NRORG, P_NRORG,
                P_CDOPERADOR, P_CDOPERADOR,
                SYSDATE, SYSDATE);

               FOR C_PRATOS IN
               (
                  SELECT NRPRATCOMPCARDBASE AS NRPRATCOMPCARDBASEORI, 
                         CDFILAUXPRAT, CDPRATO, IDPRATOEXIBICAO
                    FROM PRATCOMPCARDBASE
                   WHERE NRCOMPCARDBASE = V_NRCOMPCARDBASEORI                        
               ) LOOP
                  V_NRPRATCOMPCARDBASE := TO_NUMBER(RETORNA_NOVO_CODIGO('PRATCOMPCARDBASE', 1));

                  INSERT INTO PRATCOMPCARDBASE
                  (NRPRATCOMPCARDBASE, NRCOMPCARDBASE, 
                   CDFILAUXPRAT, CDPRATO, IDPRATOEXIBICAO,
                   NRORG, NRORGINCLUSAO, NRORGULTATU,
                   CDOPERINCLUSAO, CDOPERULTATU,
                   DTINCLUSAO, DTULTATU)
                  VALUES
                  (V_NRPRATCOMPCARDBASE, V_NRCOMPCARDBASE,
                   C_PRATOS.CDFILAUXPRAT, C_PRATOS.CDPRATO, C_PRATOS.IDPRATOEXIBICAO,
                   P_NRORG, P_NRORG, P_NRORG,
                   P_CDOPERADOR, P_CDOPERADOR,
                   SYSDATE, SYSDATE);

                  FOR C_REGIAO IN
                  (
                     SELECT CDREGIAO
                       FROM REGIAOPRATCARDBASE
                      WHERE NRPRATCOMPCARDBASE = C_PRATOS.NRPRATCOMPCARDBASEORI
                  ) LOOP
                     V_NRREGIAOPRATCARDBASE := TO_NUMBER(RETORNA_NOVO_CODIGO('REGIAOPRATCARDBASE', 1));

                     INSERT INTO REGIAOPRATCARDBASE
                     (NRREGIAOPRATCARDBASE, NRPRATCOMPCARDBASE, CDREGIAO,
                      NRORG, NRORGINCLUSAO, NRORGULTATU,
                      CDOPERINCLUSAO, CDOPERULTATU,
                      DTINCLUSAO, DTULTATU)
                     VALUES
                     (V_NRREGIAOPRATCARDBASE, V_NRPRATCOMPCARDBASE, C_REGIAO.CDREGIAO,
                      P_NRORG, P_NRORG, P_NRORG,
                      P_CDOPERADOR, P_CDOPERADOR, 
                      SYSDATE, SYSDATE);
                  END LOOP;                     
               END LOOP;
            END IF;
         END LOOP;
      END IF;

      INSERT INTO LISTA
      (NRLISTA, CDLISTA,
       NRORG, NRORGINCLUSAO, NRORGULTATU,
       CDOPERINCLUSAO, CDOPERULTATU,
       DTINCLUSAO, DTULTATU)
      VALUES
      (V_DE_PARA_CONFIG, TO_CHAR(C_CONF.NRCONFIGCARDBASEORI) || '|' || TO_CHAR(V_NRCONFIGCARDBASE),
       P_NRORG, P_NRORG, P_NRORG,
       P_CDOPERADOR, P_CDOPERADOR,
       SYSDATE, SYSDATE);

      V_NRORDEM := V_NRORDEM + 1;
   END LOOP;
--=========================================================
--=== Inclusão das regras, se solicitado
--=========================================================
   IF P_REGRAS = 'S' THEN
   --=========================================================
   --=== Adesão
   --=========================================================
      SELECT MAX(CDADESAOCARDBASE)
        INTO V_CDADESAOCARDBASE
        FROM ADESAOCARDBASE
       WHERE NRCARDAPIOBASE = P_NRCARDAPIOBASEDEST;

      V_CDADESAOCARDBASE := NVL(V_CDADESAOCARDBASE, '00000');

      V_CDADESAOCARDBASE := LPAD(TO_CHAR(TO_NUMBER(V_CDADESAOCARDBASE) + 1), 5, '0');

      FOR C_ADESAO IN
      (
         SELECT A.NRADESAOCARDBASE, A.NMADESAOCARDBASE, 
                A.CDGRTIPOPR, DD.NRDIACARDBASE AS NRDIACARDBASEDEST
           FROM ADESAOCARDBASE A
                LEFT JOIN DIACARDBASE D ON D.NRDIACARDBASE = A.NRDIACARDBASE
                LEFT JOIN DIACARDBASE DD ON DD.NRCARDAPIOBASE = P_NRCARDAPIOBASEDEST AND
                                            D.NRSEMANA = DD.NRSEMANA AND
                                            D.NRDIASEMANA = DD.NRDIASEMANA 
          WHERE A.NRCARDAPIOBASE = P_NRCARDAPIOBASEORI         
      ) LOOP
         -- Verifica que a regra não possua itens que não foram escolhidos para importação
         SELECT COUNT(1)
           INTO V_QTDE
         FROM ITEMADESAOCBASE I           
         WHERE I.NRADESAOCARDBASE = C_ADESAO.NRADESAOCARDBASE
          AND VALOR_NA_LISTA(I.NRCONFIGCARDBASE, NVL(P_COLUNAS, 'T')) = 0;
         -- Se possuir itens que não fazem parte do cardápio, avança para próxima regra
         IF V_QTDE > 0 THEN
            CONTINUE;
         END IF;

         -- Verifica se a regra é específica por segmento, e se a regra possui segmento do cardapio base
         SELECT COUNT(1)
           INTO V_QTDE
           FROM SEGMERADESAOCBASE
          WHERE NRADESAOCARDBASE = C_ADESAO.NRADESAOCARDBASE;

         IF V_QTDE > 0 THEN
            SELECT COUNT(1)
              INTO V_QTDE
              FROM SEGMERADESAOCBASE S
                   INNER JOIN SEGMERCARDBASE SC ON SC.NRCARDAPIOBASE = P_NRCARDAPIOBASEDEST AND
                                                   SC.CDSEGMER = S.CDSEGMER
             WHERE NRADESAOCARDBASE = C_ADESAO.NRADESAOCARDBASE;

            -- Se não atende nenhum dos segmentos, avança para próxima regra
            IF V_QTDE = 0 THEN
               CONTINUE;
            END IF;
         END IF;

         --ADESÃO
         V_NRADESAOCARDBASE := TO_NUMBER(RETORNA_NOVO_CODIGO('ADESAOCARDBASE', 1));

         INSERT INTO ADESAOCARDBASE
         (NRADESAOCARDBASE, NRCARDAPIOBASE, CDADESAOCARDBASE, 
          NMADESAOCARDBASE, CDGRTIPOPR, NRDIACARDBASE,
          NRORG, NRORGINCLUSAO, NRORGULTATU,
          CDOPERINCLUSAO, CDOPERULTATU,
          DTINCLUSAO, DTULTATU)
         VALUES
         (V_NRADESAOCARDBASE, P_NRCARDAPIOBASEDEST, V_CDADESAOCARDBASE,
          SUBSTR(C_ADESAO.NMADESAOCARDBASE || '(*)', 50), C_ADESAO.CDGRTIPOPR, C_ADESAO.NRDIACARDBASEDEST,
          P_NRORG, P_NRORG, P_NRORG,
          P_CDOPERADOR, P_CDOPERADOR,
          SYSDATE, SYSDATE);

         -- SEGMENTO DE MERCADO
         FOR C_SEG IN
         (
            SELECT S.CDSEGMER
              INTO V_QTDE
              FROM SEGMERADESAOCBASE S
                   INNER JOIN SEGMERCARDBASE SC ON SC.NRCARDAPIOBASE = P_NRCARDAPIOBASEDEST AND
                                                   SC.CDSEGMER = S.CDSEGMER
             WHERE NRADESAOCARDBASE = C_ADESAO.NRADESAOCARDBASE
         ) LOOP
            V_NRSEGMERADESAOCBASE := TO_NUMBER(RETORNA_NOVO_CODIGO('SEGMERADESAOCBASE', 1));

            INSERT INTO SEGMERADESAOCBASE
            (NRSEGMERADESAOCBASE, NRADESAOCARDBASE, CDSEGMER,
             NRORG, NRORGINCLUSAO, NRORGULTATU,
             CDOPERINCLUSAO, CDOPERULTATU,
             DTINCLUSAO, DTULTATU)
            VALUES
            (V_NRSEGMERADESAOCBASE, V_NRADESAOCARDBASE, C_SEG.CDSEGMER,
             P_NRORG, P_NRORG, P_NRORG,
             P_CDOPERADOR, P_CDOPERADOR,
             SYSDATE, SYSDATE);
         END LOOP;

         -- RAMO DE ATIVIDADE
         FOR C_RAMO IN
         (
            SELECT A.NRATIVCLISEGMER
              INTO V_QTDE
              FROM ATIVCLIADESAOCBASE A
                   INNER JOIN ATIVCLISEGMER ATS ON ATS.NRATIVCLISEGMER = A.NRATIVCLISEGMER
                   INNER JOIN SEGMERADESAOCBASE S ON S.NRADESAOCARDBASE = V_NRADESAOCARDBASE AND
                                                     S.CDSEGMER = ATS.CDSEGMER
             WHERE A.NRADESAOCARDBASE = C_ADESAO.NRADESAOCARDBASE
         ) LOOP
            V_NRATIVCLIADESAOCBASE := TO_NUMBER(RETORNA_NOVO_CODIGO('ATIVCLIADESAOCBASE', 1));

            INSERT INTO ATIVCLIADESAOCBASE
            (NRATIVCLIADESAOCBASE, NRADESAOCARDBASE, NRATIVCLISEGMER,             
             NRORG, NRORGINCLUSAO, NRORGULTATU,
             CDOPERINCLUSAO, CDOPERULTATU,
             DTINCLUSAO, DTULTATU)
            VALUES
            (V_NRATIVCLIADESAOCBASE, V_NRADESAOCARDBASE, C_RAMO.NRATIVCLISEGMER,
             P_NRORG, P_NRORG, P_NRORG,
             P_CDOPERADOR, P_CDOPERADOR,
             SYSDATE, SYSDATE);
         END LOOP;
         
         --ITENS DA ADESÃO
         FOR C_ITEM IN
         (
            SELECT L.NRCONFIGCARDBASE, I.NRPORCIONAMENTO, I.VRPEADESAO
              FROM ITEMADESAOCBASE I
                   INNER JOIN (
                                 SELECT SUBSTR(CDLISTA, 1, INSTR(CDLISTA, '|') - 1) AS NRCONFIGCARDBASEORI,
                                        SUBSTR(CDLISTA, INSTR(CDLISTA, '|') + 1, 50) AS NRCONFIGCARDBASE
                                   FROM LISTA
                                  WHERE NRLISTA = V_DE_PARA_CONFIG
                              ) L ON L.NRCONFIGCARDBASEORI = I.NRCONFIGCARDBASE
             WHERE I.NRADESAOCARDBASE = C_ADESAO.NRADESAOCARDBASE
         ) LOOP
            V_NRITEMADESAOCBASE := TO_NUMBER(RETORNA_NOVO_CODIGO('ITEMADESAOCBASE', 1));

            INSERT INTO ITEMADESAOCBASE
            (NRITEMADESAOCBASE, NRADESAOCARDBASE, NRCONFIGCARDBASE, 
             NRPORCIONAMENTO, VRPEADESAO,
             NRORG, NRORGINCLUSAO, NRORGULTATU,
             CDOPERINCLUSAO, CDOPERULTATU,
             DTINCLUSAO, DTULTATU)
            VALUES         
            (V_NRITEMADESAOCBASE, V_NRADESAOCARDBASE, C_ITEM.NRCONFIGCARDBASE, 
             C_ITEM.NRPORCIONAMENTO, C_ITEM.VRPEADESAO,
             P_NRORG, P_NRORG, P_NRORG,
             P_CDOPERADOR, P_CDOPERADOR,
             SYSDATE, SYSDATE);
         END LOOP;

         V_CDADESAOCARDBASE := LPAD(TO_CHAR(TO_NUMBER(V_CDADESAOCARDBASE) + 1), 5, '0');
      END LOOP;

   --=========================================================
   --=== Gramatura
   --=========================================================
      FOR C_GRAMATURA IN
      (
         SELECT G.NRGRAMATURACARDBASE, G.CDGRTIPOPR, G.VRGRAMATURA, G.SGUNIDADE, 
                G.IDTIPOGRAMATURA, G.NRTIPOPUBLICO
           FROM GRAMATURACARDBASE G
          WHERE G.NRCARDAPIOBASE = P_NRCARDAPIOBASEORI
      ) LOOP
         -- Verifica se já existe a regra de gramatura solicitada no destino
         SELECT MAX(NRGRAMATURACARDBASE)
           INTO V_NRGRAMATURACARDBASE_EXISTE
           FROM GRAMATURACARDBASE
          WHERE NRCARDAPIOBASE = P_NRCARDAPIOBASEDEST
            AND CDGRTIPOPR = C_GRAMATURA.CDGRTIPOPR
            AND VRGRAMATURA = C_GRAMATURA.VRGRAMATURA
            AND SGUNIDADE = C_GRAMATURA.SGUNIDADE
            AND (NRTIPOPUBLICO = C_GRAMATURA.NRTIPOPUBLICO OR
                 (NRTIPOPUBLICO IS NULL AND C_GRAMATURA.NRTIPOPUBLICO IS NULL));
         IF V_NRGRAMATURACARDBASE_EXISTE IS NOT NULL THEN
            CONTINUE;
         END IF;

         -- Verifica se a regra se aplica a grupo de tipo de prato selecionado para importação
         SELECT COUNT(1)
           INTO V_QTDE
           FROM CONFIGCARDBASE C
                INNER JOIN TIPOPRAT T ON C.CDTIPOPRAT = T.CDTIPOPRAT
          WHERE C.NRCARDAPIOBASE = P_NRCARDAPIOBASEORI
            AND T.CDGRTIPOPR = C_GRAMATURA.CDGRTIPOPR
            AND VALOR_NA_LISTA(C.NRCONFIGCARDBASE, NVL(P_COLUNAS, 'T')) > 0;
         IF V_QTDE = 0 THEN
            CONTINUE;
         END IF;

         V_NRGRAMATURACARDBASE := TO_NUMBER(RETORNA_NOVO_CODIGO('GRAMATURACARDBASE', 1));

         INSERT INTO GRAMATURACARDBASE
         (NRGRAMATURACARDBASE, NRCARDAPIOBASE, CDGRTIPOPR,
          VRGRAMATURA, SGUNIDADE, 
          IDTIPOGRAMATURA, NRTIPOPUBLICO,
          NRORG, NRORGINCLUSAO, NRORGULTATU,
          CDOPERINCLUSAO, CDOPERULTATU,
          DTINCLUSAO, DTULTATU)
         VALUES
         (V_NRGRAMATURACARDBASE, P_NRCARDAPIOBASEDEST, C_GRAMATURA.CDGRTIPOPR,
          C_GRAMATURA.VRGRAMATURA, C_GRAMATURA.SGUNIDADE,
          C_GRAMATURA.IDTIPOGRAMATURA, C_GRAMATURA.NRTIPOPUBLICO,
          P_NRORG, P_NRORG, P_NRORG,
          P_CDOPERADOR, P_CDOPERADOR,
          SYSDATE, SYSDATE);

         --ITENS DA GRAMATURA
         FOR C_ITEM IN
         (
            SELECT I.CDGRUPPROD, I.CDSUBGRPROD, I.CDPRODUTO, 
                   I.NRPORCIONAMENTO, I.VRGRAMATURA
              FROM ITEMGRAMCARDBASE I
             WHERE I.NRGRAMATURACARDBASE = C_GRAMATURA.NRGRAMATURACARDBASE
         ) LOOP
            V_NRITEMGRAMCARDBASE := TO_NUMBER(RETORNA_NOVO_CODIGO('ITEMGRAMCARDBASE', 1));

            INSERT INTO ITEMGRAMCARDBASE
            (NRITEMGRAMCARDBASE, NRGRAMATURACARDBASE,               
             CDGRUPPROD, CDSUBGRPROD, CDPRODUTO, 
             NRPORCIONAMENTO, VRGRAMATURA,
             NRORG, NRORGINCLUSAO, NRORGULTATU,
             CDOPERINCLUSAO, CDOPERULTATU,
             DTINCLUSAO, DTULTATU)
            VALUES
            (V_NRITEMGRAMCARDBASE, V_NRGRAMATURACARDBASE,
             C_ITEM.CDGRUPPROD, C_ITEM.CDSUBGRPROD, C_ITEM.CDPRODUTO,
             C_ITEM.NRPORCIONAMENTO, C_ITEM.VRGRAMATURA,
             P_NRORG, P_NRORG, P_NRORG,
             P_CDOPERADOR, P_CDOPERADOR,
             SYSDATE, SYSDATE);
         END LOOP;
      END LOOP;
   --=========================================================
   --=== Particularidade por segmento
   --=========================================================
      SELECT MAX(CDPARTSEGCARDBASE)
        INTO V_CDPARTSEGCARDBASE
        FROM PARTSEGCARDBASE
       WHERE NRCARDAPIOBASE = P_NRCARDAPIOBASEORI;

      V_CDPARTSEGCARDBASE := NVL(V_CDPARTSEGCARDBASE, '00000');
      V_CDPARTSEGCARDBASE := LPAD(TO_CHAR(TO_NUMBER(V_CDPARTSEGCARDBASE) + 1), 5, '0');

      FOR C_PARTSEG IN
      (
         SELECT P.NRPARTSEGCARDBASE, P.NRATIVCLISEGMER
           FROM PARTSEGCARDBASE P
          WHERE P.NRCARDAPIOBASE = P_NRCARDAPIOBASEORI
      ) LOOP
         -- Verifica se a particularidade já existe no destino
         SELECT MAX(NRPARTSEGCARDBASE)
           INTO V_NRPARTSEG_EXISTE
           FROM PARTSEGCARDBASE
          WHERE NRCARDAPIOBASE = P_NRCARDAPIOBASEDEST
            AND NRATIVCLISEGMER = C_PARTSEG.NRATIVCLISEGMER;

         IF V_NRPARTSEG_EXISTE IS NOT NULL THEN
            CONTINUE;
         END IF;
         -- Verifica que a regra não possua itens que não foram escolhidos para importação
         SELECT COUNT(1)
           INTO V_QTDE
         FROM ITPARTSEGCARDBASE I           
         WHERE I.NRPARTSEGCARDBASE = C_PARTSEG.NRPARTSEGCARDBASE
          AND VALOR_NA_LISTA(I.NRCONFIGCARDBASE, NVL(P_COLUNAS, 'T')) = 0;
         -- Se possuir itens que não fazem parte do cardápio, avança para próxima regra
         IF V_QTDE > 0 THEN
            CONTINUE;
         END IF;

         -- Verifica se a regra possui segmento do cardapio base
         SELECT COUNT(1)
           INTO V_QTDE
           FROM ATIVCLISEGMER A
                INNER JOIN SEGMERCARDBASE S ON S.NRCARDAPIOBASE = P_NRCARDAPIOBASEDEST AND 
                                               S.CDSEGMER = A.CDSEGMER
          WHERE NRATIVCLISEGMER = C_PARTSEG.NRATIVCLISEGMER;
         -- Se não possuir segmentos 
         IF V_QTDE = 0 THEN
            CONTINUE;
         END IF;

         -- Verifica se a regra 

         V_NRPARTSEGCARDBASE := TO_NUMBER(RETORNA_NOVO_CODIGO('PARTSEGCARDBASE', 1));

         INSERT INTO PARTSEGCARDBASE
         (NRPARTSEGCARDBASE, NRCARDAPIOBASE, 
          CDPARTSEGCARDBASE, NRATIVCLISEGMER,
          NRORG, NRORGINCLUSAO, NRORGULTATU,
          CDOPERINCLUSAO, CDOPERULTATU,
          DTINCLUSAO, DTULTATU)
         VALUES
         (V_NRPARTSEGCARDBASE, P_NRCARDAPIOBASEDEST,
          V_CDPARTSEGCARDBASE, C_PARTSEG.NRATIVCLISEGMER,
          P_NRORG, P_NRORG, P_NRORG,
          P_CDOPERADOR, P_CDOPERADOR,
          SYSDATE, SYSDATE);

         -- ITENS DA PARTICULARIDADE
         FOR C_ITEM IN
         (
            SELECT L.NRCONFIGCARDBASE, I.VRPERCENTUAL
              FROM ITPARTSEGCARDBASE I
                   INNER JOIN (
                                 SELECT SUBSTR(CDLISTA, 1, INSTR(CDLISTA, '|') - 1) AS NRCONFIGCARDBASEORI,
                                        SUBSTR(CDLISTA, INSTR(CDLISTA, '|') + 1, 50) AS NRCONFIGCARDBASE
                                   FROM LISTA
                                  WHERE NRLISTA = V_DE_PARA_CONFIG
                              ) L ON L.NRCONFIGCARDBASEORI = I.NRCONFIGCARDBASE
             WHERE NRPARTSEGCARDBASE = C_PARTSEG.NRPARTSEGCARDBASE
         ) LOOP
            V_NRITPARTSEGCARDBASE := TO_NUMBER(RETORNA_NOVO_CODIGO('ITPARTSEGCARDBASE', 1));
            INSERT INTO ITPARTSEGCARDBASE
            (NRITPARTSEGCARDBASE, NRPARTSEGCARDBASE,               
             NRCONFIGCARDBASE,VRPERCENTUAL,
             NRORG, NRORGINCLUSAO, NRORGULTATU,
             CDOPERINCLUSAO, CDOPERULTATU,
             DTINCLUSAO, DTULTATU)
            VALUES
            (V_NRITPARTSEGCARDBASE, V_NRPARTSEGCARDBASE,
             C_ITEM.NRCONFIGCARDBASE, C_ITEM.VRPERCENTUAL,
             P_NRORG, P_NRORG, P_NRORG,
             P_CDOPERADOR, P_CDOPERADOR,
             SYSDATE, SYSDATE);
         END LOOP;

         V_CDPARTSEGCARDBASE := LPAD(TO_CHAR(TO_NUMBER(V_CDPARTSEGCARDBASE) + 1), 5, '0');
      END LOOP;
   --=========================================================
   --=== Amostra
   --=========================================================   
      SELECT MAX(A.NRAMOSTRACARDBASE), MAX(LQ.NRCONFIGCARDBASE), MAX(LF.NRCONFIGCARDBASE)
        INTO V_NRAMOSTRACARDBASEORI, V_NRCONFIGCARDBASEQ, V_NRCONFIGCARDBASEF
        FROM AMOSTRACARDBASE A
             LEFT JOIN (
                           SELECT SUBSTR(CDLISTA, 1, INSTR(CDLISTA, '|') - 1) AS NRCONFIGCARDBASEORI,
                                  SUBSTR(CDLISTA, INSTR(CDLISTA, '|') + 1, 50) AS NRCONFIGCARDBASE
                             FROM LISTA
                            WHERE NRLISTA = V_DE_PARA_CONFIG
                        ) LQ ON LQ.NRCONFIGCARDBASEORI = A.NRCONFIGCARDBASEQ
             LEFT JOIN (
                           SELECT SUBSTR(CDLISTA, 1, INSTR(CDLISTA, '|') - 1) AS NRCONFIGCARDBASEORI,
                                  SUBSTR(CDLISTA, INSTR(CDLISTA, '|') + 1, 50) AS NRCONFIGCARDBASE
                             FROM LISTA
                            WHERE NRLISTA = V_DE_PARA_CONFIG
                        ) LF ON LQ.NRCONFIGCARDBASEORI = A.NRCONFIGCARDBASEF
       WHERE NRCARDAPIOBASE = P_NRCARDAPIOBASEORI;

      IF V_NRAMOSTRACARDBASEORI IS NOT NULL THEN
         SELECT COUNT(1)
           INTO V_QTDE
           FROM AMOSTRACARDBASE
          WHERE NRCARDAPIOBASE = P_NRCARDAPIOBASEDEST;
         -- Não insere amostra se já estiver configurado no destino
         IF V_QTDE = 0 THEN
            V_NRAMOSTRACARDBASE := TO_NUMBER(RETORNA_NOVO_CODIGO('AMOSTRACARDBASE', 1));

            INSERT INTO AMOSTRACARDBASE
            (NRAMOSTRACARDBASE, NRCARDAPIOBASE, 
             NRCONFIGCARDBASEQ, NRCONFIGCARDBASEF,
             NRORG, NRORGINCLUSAO, NRORGULTATU,
             CDOPERINCLUSAO, CDOPERULTATU,
             DTINCLUSAO, DTULTATU)
            VALUES
            (V_NRAMOSTRACARDBASE, P_NRCARDAPIOBASEDEST,
             V_NRCONFIGCARDBASEQ, V_NRCONFIGCARDBASEF,
             P_NRORG, P_NRORG, P_NRORG,
             P_CDOPERADOR, P_CDOPERADOR,
             SYSDATE, SYSDATE);
         END IF;
      END IF;
   --=========================================================
   --=== Descartaveis
   --=========================================================
      FOR C_DESCART IN
      (
         SELECT L.NRCONFIGCARDBASE, D.IDFORMACALCULO
           FROM DESCARTCARDBASE D
                INNER JOIN (
                           SELECT SUBSTR(CDLISTA, 1, INSTR(CDLISTA, '|') - 1) AS NRCONFIGCARDBASEORI,
                                  SUBSTR(CDLISTA, INSTR(CDLISTA, '|') + 1, 50) AS NRCONFIGCARDBASE
                             FROM LISTA
                            WHERE NRLISTA = V_DE_PARA_CONFIG
                        ) L ON L.NRCONFIGCARDBASEORI = D.NRCONFIGCARDBASE
          WHERE D.NRCARDAPIOBASE = P_NRCARDAPIOBASEORI
      ) LOOP
         V_NRDESCARTCARDBASE := TO_NUMBER(RETORNA_NOVO_CODIGO('DESCARTCARDBASE', 1));

         INSERT INTO DESCARTCARDBASE
         (NRDESCARTCARDBASE, NRCARDAPIOBASE, 
          NRCONFIGCARDBASE, IDFORMACALCULO,
          NRORG, NRORGINCLUSAO, NRORGULTATU,
          CDOPERINCLUSAO, CDOPERULTATU,
          DTINCLUSAO, DTULTATU)
         VALUES
         (V_NRDESCARTCARDBASE, P_NRCARDAPIOBASEDEST,
          C_DESCART.NRCONFIGCARDBASE, C_DESCART.IDFORMACALCULO,
          P_NRORG, P_NRORG, P_NRORG,
          P_CDOPERADOR, P_CDOPERADOR,
          SYSDATE, SYSDATE);
      END LOOP;
   --=========================================================
   --=== Limpeza
   --=========================================================
      FOR C_LIMPEZA IN
      (
         SELECT LC.NRCONFIGCARDBASE, L.QTINICIAL, L.QTFINAL
           FROM LIMPEZACARDBASE L
                INNER JOIN (
                           SELECT SUBSTR(CDLISTA, 1, INSTR(CDLISTA, '|') - 1) AS NRCONFIGCARDBASEORI,
                                  SUBSTR(CDLISTA, INSTR(CDLISTA, '|') + 1, 50) AS NRCONFIGCARDBASE
                             FROM LISTA
                            WHERE NRLISTA = V_DE_PARA_CONFIG
                        ) LC ON LC.NRCONFIGCARDBASEORI = L.NRCONFIGCARDBASE
          WHERE L.NRCARDAPIOBASE = P_NRCARDAPIOBASEORI
      ) LOOP
         V_NRLIMPEZACARDBASE := TO_NUMBER(RETORNA_NOVO_CODIGO('LIMPEZACARDBASE', 1));

         INSERT INTO LIMPEZACARDBASE
         (NRLIMPEZACARDBASE, NRCARDAPIOBASE, 
          NRCONFIGCARDBASE, QTINICIAL, QTFINAL,
          NRORG, NRORGINCLUSAO, NRORGULTATU,
          CDOPERINCLUSAO, CDOPERULTATU,
          DTINCLUSAO, DTULTATU)   
         VALUES
         (V_NRLIMPEZACARDBASE, P_NRCARDAPIOBASEDEST,
          C_LIMPEZA.NRCONFIGCARDBASE, C_LIMPEZA.QTINICIAL, C_LIMPEZA.QTFINAL,
          P_NRORG, P_NRORG,P_NRORG,
          P_CDOPERADOR, P_CDOPERADOR,
          SYSDATE, SYSDATE);
      END LOOP;

   END IF;   
END;
/


CREATE OR REPLACE PROCEDURE INSERE_LISTA_ERROS(P_CDFILIAL IN VARCHAR2,                             
                                               P_MENSAGEM IN VARCHAR2,
                                               P_CDOPERADOR IN VARCHAR2,
                                               P_NRORG IN NUMBER,
                                               P_NRLISTAERROS IN OUT NUMBER,
                                               P_NRORDEM IN NUMBER DEFAULT NULL,
                                               P_CDCHAVE IN VARCHAR2 DEFAULT NULL,
                                               P_NMCHAVE IN VARCHAR2 DEFAULT NULL)
AS
  PRAGMA AUTONOMOUS_TRANSACTION;
  V_SEQ VARCHAR2(20);
BEGIN
  IF P_MENSAGEM IS NOT NULL THEN
     IF P_NRLISTAERROS IS NULL THEN
        NOVO_CODIGO_NT('LISTAERROS'|| P_CDFILIAL, V_SEQ);
        P_NRLISTAERROS := TO_NUMBER(V_SEQ);
     END IF;
     INSERT INTO LISTAERROS
     (CDFILIAL, NRLISTA, DSERRO, NRORDEM,
      CDCHAVE, NMCHAVE,
      NRORG, NRORGINCLUSAO, NRORGULTATU,
      CDOPERINCLUSAO, CDOPERULTATU,
      DTINCLUSAO, DTULTATU)
     VALUES
     (P_CDFILIAL, P_NRLISTAERROS, P_MENSAGEM, P_NRORDEM,
      P_CDCHAVE, P_NMCHAVE,
      P_NRORG, P_NRORG, P_NRORG,
      P_CDOPERADOR, P_CDOPERADOR,
      SYSDATE, SYSDATE);
  END IF;

  COMMIT;
END;
/


CREATE OR REPLACE PROCEDURE DELETA_PRATOS_CARDBASE
(
P_DIAS IN VARCHAR2,
P_CONFIGURACAO IN VARCHAR2
)
AS
BEGIN   
   FOR C_DIA IN
   (
      SELECT NRCARDAPIOBASE, NRDIACARDBASE
        FROM DIACARDBASE
       WHERE VALOR_NA_LISTA(TO_CHAR(NRDIACARDBASE),P_DIAS) > 0
   ) LOOP       
      --Inativa regras de adesão específicas do dia
      UPDATE ADESAOCARDBASE
         SET IDATIVO = 'N'
       WHERE NRCARDAPIOBASE = C_DIA.NRCARDAPIOBASE
         AND NRDIACARDBASE = C_DIA.NRDIACARDBASE;

      FOR C_CONFIG IN
      (
         SELECT NRCONFIGCARDBASE
           FROM CONFIGCARDBASE
          WHERE VALOR_NA_LISTA(TO_CHAR(NRCONFIGCARDBASE), P_CONFIGURACAO) > 0
      ) LOOP
         FOR C_COMP IN
         (
            SELECT NRCOMPCARDBASE
              FROM COMPCARDBASE
             WHERE NRCARDAPIOBASE = C_DIA.NRCARDAPIOBASE
               AND NRDIACARDBASE = C_DIA.NRDIACARDBASE
               AND NRCONFIGCARDBASE = C_CONFIG.NRCONFIGCARDBASE
         ) LOOP
            DELETE FROM REGIAOPRATCARDBASE
             WHERE NRPRATCOMPCARDBASE IN (SELECT NRPRATCOMPCARDBASE FROM PRATCOMPCARDBASE 
                                           WHERE NRCOMPCARDBASE = C_COMP.NRCOMPCARDBASE);

            DELETE FROM PRATCOMPCARDBASE
             WHERE NRCOMPCARDBASE = C_COMP.NRCOMPCARDBASE;


            DELETE FROM COMPCARDBASE
             WHERE NRCOMPCARDBASE = C_COMP.NRCOMPCARDBASE;
         END LOOP;
      END LOOP;
   END LOOP;
END;
/


CREATE OR REPLACE PROCEDURE GRAVA_LISTAPRECOTCO 
(
   P_DTREFERENCIA IN DATE,
   P_CDREGIAO IN VARCHAR2,
   P_NRORG IN NUMBER,
   P_CDOPERADOR IN VARCHAR2,
   P_NRLISTAPRECOTCO OUT NUMBER
)
AS
   V_CDFILIAL VARCHAR2(4);
   V_CDFILCENTCMP VARCHAR2(4);
   V_IDTIPOAPUR VARCHAR2(1);

   V_CDPRODESTO VARCHAR2(10);
   V_VRFATOCONV FLOAT;
   V_VRCUSTO FLOAT;
   V_FORNECEDOR_OL VARCHAR2(1);

   V_NRLISTAPRECOTCO NUMBER;
   V_NRPRODLISTAPRECOTCO NUMBER;
   V_QTDE NUMBER;

   V_CDARVPROD VARCHAR2(20);
   V_FORNEPRIO VARCHAR2(1);
   V_CUSTOPELAMEDIA VARCHAR2(1);
   V_CDFORNECED VARCHAR2(21);
   V_CDMARCA VARCHAR2(5);

   V_VRTOTCUSTO FLOAT;
BEGIN
  -- Busca filial parametrizada no TCO
   SELECT MAX(CDFILIAL)
     INTO V_CDFILIAL
     FROM PARAMTCO;
  -- Busca a central de compras
   SELECT MAX(NVL(FILIAL.CDFILCENTCMP, FILIAL.CDFILIAL))
     INTO V_CDFILCENTCMP
     FROM FILIAL
    WHERE CDFILIAL = V_CDFILIAL;
   -- Busca informações da PARASUPRI
   SELECT MAX(IDTIPOAPUR)
     INTO V_IDTIPOAPUR
     FROM PARASUPRI
    WHERE CDFILIAL = V_CDFILCENTCMP;   

   IF V_CDFILCENTCMP IS NOT NULL THEN
--=========================================================
--=== Acesso a lista de preços e gravação na lista do TCO
--=========================================================      
      V_NRLISTAPRECOTCO := TO_NUMBER(RETORNA_NOVO_CODIGO('LISTAPRECOTCO', 1));

      INSERT INTO LISTAPRECOTCO
      (NRLISTAPRECOTCO, DTREFERENCIA, CDREGIAO, CDFILIAL, IDTIPOAPUR,
       NRORG, NRORGINCLUSAO, NRORGULTATU,
       CDOPERINCLUSAO, CDOPERULTATU,
       DTINCLUSAO, DTULTATU)
      VALUES
      (V_NRLISTAPRECOTCO, P_DTREFERENCIA, P_CDREGIAO, V_CDFILCENTCMP, V_IDTIPOAPUR,
      P_NRORG, P_NRORG, P_NRORG,
      P_CDOPERADOR, P_CDOPERADOR,
      SYSDATE, SYSDATE);

      V_QTDE := 0;
      -- Percorre os itens da lista de preços segundo o filtro informado
      FOR C_ITEMCOLE IN
      (
      SELECT I.CDFILIAL,
             I.NRCOLEPRECO,
             I.CDMARCA,
             I.CDREGIAO,
             I.CDFORNECED,
             I.CDPRODUTO,                
             I.DTINIVALITM,
             I.DTFINVALITM,
             I.VRPRECUNIITM,                    
             I.VRPRECOITMPI,
             I.VRPRECECOITM                   
         FROM ITEMCOLE I INNER JOIN COLETAPR C ON C.CDFILIAL = I.CDFILIAL AND
                                                       C.NRCOLEPRECO = I.NRCOLEPRECO
         WHERE I.CDFILIAL = V_CDFILCENTCMP
           AND P_DTREFERENCIA BETWEEN I.DTINIVALITM AND I.DTFINVALITM
           AND I.VRPRECUNIITM > 0
           AND I.CDREGIAO = P_CDREGIAO
           AND I.IDITMLISPREC = 'S'
      ) LOOP
         -- Busca produto de estoque e fator de conversão
         SELECT MAX(CDPRODESTO), MAX(VRFATOCONV)
              INTO V_CDPRODESTO, V_VRFATOCONV
              FROM PRODUTO
             WHERE CDPRODUTO = C_ITEMCOLE.CDPRODUTO;
         IF NVL(V_VRFATOCONV, 0) <= 0 THEN
            V_VRFATOCONV := 1;
         END IF;

         /*Busca o código de árvore do produto de estoque*/
         SELECT MAX(CDARVPROD)
           INTO V_CDARVPROD
           FROM PRODUTO
          WHERE CDPRODUTO = V_CDPRODESTO;

         -- Calcula preço do produto de estoque para essa linha
         V_VRCUSTO := CASE NVL(V_IDTIPOAPUR, '0') WHEN '0' THEN C_ITEMCOLE.VRPRECUNIITM
                                                 WHEN '1' THEN C_ITEMCOLE.VRPRECOITMPI
                                                 WHEN '2' THEN C_ITEMCOLE.VRPRECECOITM
                      END / V_VRFATOCONV;

         -- Insere item na lista de preços do TCO
         IF V_VRCUSTO > 0 THEN
            -- Verifica se fornecedor é prioritário para o produto na região
            SELECT MAX('S')
              INTO V_FORNEPRIO
              FROM FORNEPRIOTCO F
                   INNER JOIN PRODUTO P ON P.CDPRODUTO = F.CDPRODUTO
             WHERE F.CDREGIAO = P_CDREGIAO
               AND F.CDFORNECED = C_ITEMCOLE.CDFORNECED
               AND V_CDARVPROD LIKE P.CDARVPROD|| '%'
               /*Adicionado para que o fornecedor prioritário seja o mais próximo no cadastro do produto em questão*/
               AND NOT EXISTS (SELECT 1
                                 FROM FORNEPRIOTCO FP
                                      INNER JOIN PRODUTO PT ON PT.CDPRODUTO = FP.CDPRODUTO
                                WHERE FP.CDREGIAO = P_CDREGIAO
                                  AND FP.CDFORNECED <> F.CDFORNECED
                                  AND V_CDARVPROD LIKE PT.CDARVPROD|| '%'
                                  AND LENGTH(PT.CDARVPROD) > LENGTH(P.CDARVPROD) );

            V_FORNEPRIO := NVL(V_FORNEPRIO, 'N');

            -- Verifica se produto possui custo pela média
            SELECT MAX('S')
              INTO V_CUSTOPELAMEDIA
              FROM PRODCUSMEDIATCO PC
                   INNER JOIN PRODUTO P ON P.CDPRODUTO = PC.CDPRODUTO
             WHERE V_CDARVPROD LIKE P.CDARVPROD|| '%';

            V_CUSTOPELAMEDIA := NVL(V_CUSTOPELAMEDIA, 'N');

            V_NRPRODLISTAPRECOTCO := TO_NUMBER(RETORNA_NOVO_CODIGO('PRODLISTAPRECOTCO', 1));
            
            INSERT INTO PRODLISTAPRECOTCO
            (NRPRODLISTAPRECOTCO, NRLISTAPRECOTCO, IDESCOLHIDO, 
            CDPRODESTO, VRCUSTO, CDFILIAL, 
            NRCOLEPRECO, CDMARCA, CDREGIAO, 
            CDFORNECED, CDPRODUTO, 
            DTINIVALITM, DTFINVALITM, 
            VRPRECUNIITM, VRPRECOITMPI, VRPRECECOITM, 
            VRFATOCONV, IDFORNECEDOROL, IDCUSTOPELAMEDIA, IDFORNEPRIOTCO,
            NRORG, NRORGINCLUSAO, NRORGULTATU,
            CDOPERINCLUSAO, CDOPERULTATU,
            DTINCLUSAO, DTULTATU)
            VALUES
            (V_NRPRODLISTAPRECOTCO, V_NRLISTAPRECOTCO, 'N',
            V_CDPRODESTO, V_VRCUSTO, C_ITEMCOLE.CDFILIAL,
            C_ITEMCOLE.NRCOLEPRECO, C_ITEMCOLE.CDMARCA, C_ITEMCOLE.CDREGIAO,
            C_ITEMCOLE.CDFORNECED, C_ITEMCOLE.CDPRODUTO,
            C_ITEMCOLE.DTINIVALITM, C_ITEMCOLE.DTFINVALITM, 
            C_ITEMCOLE.VRPRECUNIITM, C_ITEMCOLE.VRPRECOITMPI, C_ITEMCOLE.VRPRECECOITM,
            V_VRFATOCONV, 'N', V_CUSTOPELAMEDIA, V_FORNEPRIO, 
            P_NRORG, P_NRORG, P_NRORG, 
            P_CDOPERADOR, P_CDOPERADOR, 
            SYSDATE, SYSDATE);
            V_QTDE := V_QTDE + 1;
         END IF;

      END LOOP;
         
--=========================================================
--=== Tratativas antes da escolha de preços
--=========================================================
      -- Apaga as linhas de fornecedores que não atendem a região
      FOR C_FORN_N_ATENDE_REG IN
      (
        SELECT CDFORNECED
         FROM REFOREG
           WHERE REFOREG.CDREGIAO = P_CDREGIAO
      ) LOOP
         DELETE FROM PRODLISTAPRECOTCO
          WHERE NRLISTAPRECOTCO = V_NRLISTAPRECOTCO
            AND CDFORNECED = C_FORN_N_ATENDE_REG.CDFORNECED;
      END LOOP;

      -- Indica se fornecedor é um Operador Logístico (OL)
      FOR C_FORNOL IN
      (
         SELECT DISTINCT CDFORNOPELOG           
           FROM FILIAL
             WHERE NVL(FILIAL.IDFUNCAOFILI, 'F') = 'O'
      ) LOOP
         UPDATE PRODLISTAPRECOTCO
            SET IDFORNECEDOROL = 'S'
          WHERE NRLISTAPRECOTCO = V_NRLISTAPRECOTCO
            AND CDFORNECED = C_FORNOL.CDFORNOPELOG;
      END LOOP;

      -- Insere a linha dos itens com custo pela média     

      SELECT MAX(CDFORNECED), MAX(CDMARCA)
        INTO V_CDFORNECED, V_CDMARCA
        FROM PARAMTCO;

      FOR C_PRODCUSMEDIA IN
      (
         SELECT DISTINCT CDPRODESTO
           FROM PRODLISTAPRECOTCO
          WHERE NRLISTAPRECOTCO = V_NRLISTAPRECOTCO
            AND IDCUSTOPELAMEDIA = 'S'
      ) LOOP
         -- Se fornecedor e marca não forem informados, não é possível efetuar o custo pela média, 
         -- por isso a rotina assume que é para escolher o preço no mecanismo tradicional
         IF V_CDFORNECED IS NULL OR V_CDMARCA IS NULL THEN
            UPDATE PRODLISTAPRECOTCO
               SET IDCUSTOPELAMEDIA = 'N'
             WHERE NRLISTAPRECOTCO = V_NRLISTAPRECOTCO
               AND CDPRODESTO = C_PRODCUSMEDIA.CDPRODESTO;
         ELSE
            V_VRTOTCUSTO := 0;
            V_QTDE := 0;
            -- Soma o custo unitário dos produtos a considerar a média
            FOR C_PROD IN
            (
               SELECT VRCUSTO
                 FROM PRODLISTAPRECOTCO
                WHERE NRLISTAPRECOTCO = V_NRLISTAPRECOTCO
                  AND CDPRODESTO = C_PRODCUSMEDIA.CDPRODESTO
            ) LOOP      
               V_VRTOTCUSTO := V_VRTOTCUSTO + C_PROD.VRCUSTO;
               V_QTDE := V_QTDE + 1;
            END LOOP;

            IF (V_VRTOTCUSTO > 0) THEN
               V_NRPRODLISTAPRECOTCO := TO_NUMBER(RETORNA_NOVO_CODIGO('PRODLISTAPRECOTCO', 1));
               INSERT INTO PRODLISTAPRECOTCO
               (NRPRODLISTAPRECOTCO, NRLISTAPRECOTCO, IDESCOLHIDO, 
                CDPRODESTO, VRCUSTO, CDFILIAL, 
                NRCOLEPRECO, CDMARCA, CDREGIAO, 
                CDFORNECED, CDPRODUTO, 
                DTINIVALITM, DTFINVALITM, 
                VRPRECUNIITM, VRPRECOITMPI, VRPRECECOITM, 
                VRFATOCONV, IDFORNECEDOROL, IDFORNEPRIOTCO, IDCUSTOPELAMEDIA,
                NRORG, NRORGINCLUSAO, NRORGULTATU,
                CDOPERINCLUSAO, CDOPERULTATU,
                DTINCLUSAO, DTULTATU)
               VALUES
               (V_NRPRODLISTAPRECOTCO, V_NRLISTAPRECOTCO, 'S',
                C_PRODCUSMEDIA.CDPRODESTO, V_VRTOTCUSTO/V_QTDE, V_CDFILCENTCMP,
                NULL, V_CDMARCA, P_CDREGIAO,
                V_CDFORNECED, C_PRODCUSMEDIA.CDPRODESTO,
                P_DTREFERENCIA, P_DTREFERENCIA, 
                V_VRTOTCUSTO/V_QTDE, V_VRTOTCUSTO/V_QTDE, V_VRTOTCUSTO/V_QTDE,
                1, 'N', 'N', 'S',
                P_NRORG, P_NRORG, P_NRORG, 
                P_CDOPERADOR, P_CDOPERADOR, 
                SYSDATE, SYSDATE);
            END IF;
         END IF;
      END LOOP;

--=========================================================
--=== Escolha do melhor preço segundo os critérios do TCO
--=========================================================    
      V_CDPRODESTO := NULL;
      V_NRPRODLISTAPRECOTCO := NULL;      
      FOR C_PRODLISTA IN
      (
      SELECT CDPRODESTO, NRPRODLISTAPRECOTCO, VRCUSTO, IDFORNECEDOROL, IDFORNEPRIOTCO
        FROM PRODLISTAPRECOTCO
       WHERE NRLISTAPRECOTCO = V_NRLISTAPRECOTCO
            AND IDCUSTOPELAMEDIA = 'N' -- desconsidera os custos pela média que já foram incluídos
       /*ORDER BY OBRIGATÓRIO para que a lógica por produto de estoque funcionar*/
       ORDER BY CDPRODESTO
      ) LOOP
         IF (V_CDPRODESTO IS NULL) OR (V_CDPRODESTO <> C_PRODLISTA.CDPRODESTO) THEN
            -- Se trocou o produto e se já processou algum, inica o escolhido na tabela
            IF V_NRPRODLISTAPRECOTCO IS NOT NULL THEN
               UPDATE PRODLISTAPRECOTCO
                  SET IDESCOLHIDO = 'S'
                WHERE NRPRODLISTAPRECOTCO = V_NRPRODLISTAPRECOTCO; 
            END IF;
            V_CDPRODESTO := C_PRODLISTA.CDPRODESTO;
            V_NRPRODLISTAPRECOTCO := C_PRODLISTA.NRPRODLISTAPRECOTCO;
            V_VRCUSTO := C_PRODLISTA.VRCUSTO;
            V_FORNECEDOR_OL := C_PRODLISTA.IDFORNECEDOROL;
            V_FORNEPRIO := C_PRODLISTA.IDFORNEPRIOTCO;
         END IF;
         
         -- Se o escolhido ainda não é operador OL, passa a ser o operador OL (independente do preço)
            -- Se OL é o mesmo do anteriormente escolhido e ainda não é preferencial, passa a ser o preferencial (independente do preço)
         -- Se OL e preferencial não mudaram, verifica se o preço é menor
         IF ((V_FORNECEDOR_OL = 'N') AND (C_PRODLISTA.IDFORNECEDOROL = 'S')) OR -- mudando para fornecedor OL
            (
               (V_FORNECEDOR_OL = C_PRODLISTA.IDFORNECEDOROL) AND 
               (
                  (V_FORNEPRIO = 'N' AND (C_PRODLISTA.IDFORNEPRIOTCO = 'S')) OR -- mudando para fornecedor prioritário
                  ((V_FORNECEDOR_OL = C_PRODLISTA.IDFORNECEDOROL) AND (V_FORNEPRIO = C_PRODLISTA.IDFORNEPRIOTCO ) AND (C_PRODLISTA.VRCUSTO < V_VRCUSTO)) -- Mudando para um preço melhor
               )
            ) THEN
            V_NRPRODLISTAPRECOTCO := C_PRODLISTA.NRPRODLISTAPRECOTCO;
            V_VRCUSTO := C_PRODLISTA.VRCUSTO;
            V_FORNECEDOR_OL := C_PRODLISTA.IDFORNECEDOROL;
            V_FORNEPRIO := C_PRODLISTA.IDFORNEPRIOTCO;
         END IF;
      END LOOP;
      IF (V_NRPRODLISTAPRECOTCO IS NOT NULL) THEN
         UPDATE PRODLISTAPRECOTCO
            SET IDESCOLHIDO = 'S'
          WHERE NRPRODLISTAPRECOTCO = V_NRPRODLISTAPRECOTCO;
      END IF;
   END IF;

   SELECT COUNT(1)
     INTO V_QTDE
     FROM PRODLISTAPRECOTCO
    WHERE NRLISTAPRECOTCO = V_NRLISTAPRECOTCO;

   -- Se não há itens, apaga a lista de preços gerada e sai do procedimento
   IF V_QTDE = 0 THEN
      DELETE FROM LISTAPRECOTCO
       WHERE NRLISTAPRECOTCO = V_NRLISTAPRECOTCO;

      RETURN;
   END IF;

   P_NRLISTAPRECOTCO := V_NRLISTAPRECOTCO;
END;
/


CREATE OR REPLACE PROCEDURE IMPORTA_CARDBASE_NO_CARDTRAB
(
   P_NRCARDAPIOBASE IN NUMBER,
   P_IDORIGEM IN VARCHAR2,
   P_NRATIVCLISEGMER IN NUMBER,
   P_CDREGIAO IN VARCHAR2,
   P_VRPEACRESCUSTO IN FLOAT,
   P_NRTIPOPUBLICO IN NUMBER,
   P_QTSEGSEX IN FLOAT,
   P_QTSABADO IN FLOAT,
   P_QTDOMFERI IN FLOAT,
   P_QTTURNOS IN FLOAT,
   P_CONFIGURACOES IN VARCHAR2,
   P_GRUPOS IN VARCHAR2,
   P_DTCUSTO IN DATE,
   P_NRCARDTRABCOMPLEMENTADO IN NUMBER,
   P_NRORG IN NUMBER,
   P_CDOPERADOR IN VARCHAR2,
   P_CDFILIALLOGADA IN VARCHAR2,
   P_NRCARDAPIOTRAB OUT NUMBER,
   P_LISTAERROS OUT VARCHAR2,
   P_IDIOMA IN VARCHAR2 DEFAULT 'PT_BR'
)
AS
   V_QTDE NUMBER;
   V_NRCARDAPIOTRAB NUMBER;
   V_CDCARDAPIOBASE VARCHAR2(10);
   V_DTINIVIGENCIA DATE;
   V_DTFIMVIGENCIA DATE;
   V_IDATIVO VARCHAR2(1);
   V_NRPADRAOQUALIDADE NUMBER;
   V_NRSERVICOPROPOSTA NUMBER;
   V_CDFILIAL VARCHAR2(4);
   V_CDTIPOCUSTO VARCHAR2(2);
   V_NRDIACARDTRAB NUMBER;
   V_NRCONFIGCARDTRAB NUMBER;
   V_NRCOMPCARDTRAB NUMBER;
   V_NRPRODUTOCARDTRAB NUMBER;
   V_NRRECEPRATCARDTRAB NUMBER;
   V_NRCOMPCARDBASE NUMBER;
   V_NRPRATCOMPCARDBASE NUMBER;
   V_CDFILAUXPRAT VARCHAR2(4);
   V_CDPRATO VARCHAR2(10);
   V_NMPRATO VARCHAR2(100);
   V_NRADESAOCARDBASE NUMBER;
   V_CDADESAOCARDBASE VARCHAR2(5);   
   V_ATENDE_PORCIONAMENTO VARCHAR2(1);
   V_ATENDE_SEGMENTO VARCHAR2(1);
   V_ATENDE_RAMO VARCHAR2(1);
   V_SERVICOPROPOSTA VARCHAR2(100);
   V_CDFILIALSERV VARCHAR2(4);   
   V_CDSERVFILI VARCHAR2(5);
   V_QTDE2 NUMBER;
   V_CDPRODUTO_BASE VARCHAR2(10);   
   V_NRRECEPRAT_ESCOLHIDA NUMBER;   
   V_VRGRAMATURA FLOAT; 
   V_SGUNIDADE VARCHAR2(10);
   V_SGUNIDADE_RECEITA VARCHAR2(10);
   V_IDTIPOGRAMATURA VARCHAR2(30);
   V_CDPRODUTO VARCHAR2(10);
   V_NMPRODUTO VARCHAR2(100);
   V_QTPRONTA FLOAT;
   V_VRPEFATCOR FLOAT;
   V_VRPEFATCOC FLOAT;
   V_QTINNATURA FLOAT;
   V_QTLIMPA  FLOAT;
   V_VRFATOR FLOAT;
   V_NRPARTSEGCARDBASE NUMBER; 
   V_CDPARTSEGCARDBASE VARCHAR2(5);
   V_NRCONFIGCARDBASEQ NUMBER;
   V_NRCONFIGCARDBASEF NUMBER;
   V_QTUNIDADES FLOAT;
   V_NRORDEM NUMBER;
   V_COMENSAIS FLOAT;
   V_CDTIPOPRATLIMPEZA VARCHAR2(2);
   V_NRCONFIGCARDBASE NUMBER;
   V_IDCOMPLEMENTAR VARCHAR2(1);
   V_NRCARDAPIOBASECOMPL NUMBER;
   V_NRCARDCOMPLCARDBASE NUMBER;
   V_NRCOMPCARDTRABCOMPL NUMBER;
   V_NMREGIAO VARCHAR2(100);
   V_DESCRICAO VARCHAR2(100);
   V_CDSEGMER VARCHAR2(5);
   V_IDRECEITA VARCHAR2(1);
   V_NMSERVICO VARCHAR2(200);
   V_DSCOMPLEMENTO VARCHAR2(50);
   V_VRFTCONVER FLOAT; 
   V_IDTIPOOPE VARCHAR2(1);
   V_VRGRAMATURA_REGRA FLOAT;
   V_CDFILCENTCMP VARCHAR2(4);

   V_CDPRODESTO VARCHAR2(10);
   V_VRPRECO FLOAT;
   V_VRPRECO_PROD FLOAT;
   V_FORNECEDOR_OL VARCHAR2(1);
   V_FORNECEDOR_OL_PROD VARCHAR2(1);
   V_CDMARCA VARCHAR2(5);
   V_IDTIPOAPUR VARCHAR2(1);
   V_VRFATOCONV FLOAT;

   V_NRLISTAPRECOTCO NUMBER;   

   -- Procedure auxiliar para agilizar inclusão na lista de erros
   PROCEDURE I_L(MENSAGEM IN VARCHAR2)
   AS
   BEGIN
      INSERE_LISTA_ERROS(P_CDFILIALLOGADA, MENSAGEM,
                         P_CDOPERADOR, P_NRORG, P_LISTAERROS);
   END;

   FUNCTION NOME_DIA(NRSEMANA IN NUMBER, NRDIASEMANA IN NUMBER) RETURN VARCHAR2
   AS
   BEGIN
   	  IF UPPER(P_IDIOMA) = 'PT_BR' THEN
   	  	 IF NRDIASEMANA = 1 THEN
   	  	 	RETURN TO_CHAR(NRSEMANA) || 'º DOM';
   	  	 ELSIF NRDIASEMANA = 2 THEN
   	  	 	RETURN TO_CHAR(NRSEMANA) || 'ª SEG';
   	  	 ELSIF NRDIASEMANA = 3 THEN
   	  	 	RETURN TO_CHAR(NRSEMANA) || 'ª TER';
   	  	 ELSIF NRDIASEMANA = 4 THEN
   	  	 	RETURN TO_CHAR(NRSEMANA) || 'ª QUA';
   	  	 ELSIF NRDIASEMANA = 5 THEN
   	  	 	RETURN TO_CHAR(NRSEMANA) || 'ª QUI';
   	  	 ELSIF NRDIASEMANA = 6 THEN   	  	 	
   	  	 	RETURN TO_CHAR(NRSEMANA) || 'ª SEX';
   	  	 ELSIF NRDIASEMANA = 7 THEN
   	  	 	RETURN TO_CHAR(NRSEMANA) || 'º SAB';
   	  	 END IF;
   	  END IF;
   	  RETURN NULL;
   END;
   
BEGIN
--=========================================================
--=== Validação inicial
--=========================================================
   SELECT MAX(CDCARDAPIOBASE), MAX(NRPADRAOQUALIDADE), 
          MAX(IDATIVO), MAX(DTINIVIGENCIA), 
          MAX(DTFIMVIGENCIA), COUNT(1),
          MAX(NRSERVICOPROPOSTA),
          MAX(IDCOMPLEMENTAR)
     INTO V_CDCARDAPIOBASE, V_NRPADRAOQUALIDADE, V_IDATIVO, V_DTINIVIGENCIA, V_DTFIMVIGENCIA, 
          V_QTDE, V_NRSERVICOPROPOSTA, V_IDCOMPLEMENTAR
     FROM CARDAPIOBASE
    WHERE NRCARDAPIOBASE = P_NRCARDAPIOBASE;

   SELECT MAX(CDSEGMER)
     INTO V_CDSEGMER   
     FROM ATIVCLISEGMER
    WHERE NRATIVCLISEGMER = P_NRATIVCLISEGMER;   

   IF V_QTDE = 0 THEN
      -- Cardápio base informado não encontrado
      I_L(MSG('TCOPROC_CARDBASE_N_CAD'));
   ELSE
      IF P_IDORIGEM IS NULL THEN
         -- Origem não informada
         I_L(MSG('TCOPROC_ORIGEM_N_INF'));
      END IF;

      IF V_IDATIVO = 'N' THEN
         -- Cardápio base informado encontra-se inativo
         I_L(MSG('TCOPROC_CARDBASE_INATIVO'));
      END IF;
      
      IF NOT (TRUNC(SYSDATE) BETWEEN V_DTINIVIGENCIA AND V_DTFIMVIGENCIA) THEN
         -- Cardápio base informado não está vigente
         I_L(MSG('TCOPROC_CARDBASE_N_VIGENTE'));
      END IF;
      
      SELECT COUNT(1)
        INTO V_QTDE
        FROM SEGMERCARDBASE
       WHERE NRCARDAPIOBASE = P_NRCARDAPIOBASE
         AND CDSEGMER = V_CDSEGMER;

      IF V_QTDE = 0 THEN
         -- Segmento de mercado não é contemplado pelo cardápio base informado
         I_L(MSG('TCOPROC_SEGMER_N_CONTEMP_CARDBASE'));
      END IF;

      SELECT COUNT(1), MAX(CDREGIAO || ' - ' || NMREGIAO)
        INTO V_QTDE, V_NMREGIAO
        FROM REGIAO
       WHERE CDREGIAO = P_CDREGIAO;

      IF V_QTDE = 0 THEN
         -- Região não informada
         I_L(MSG('TCOPROC_REGIAO_N_INF'));
      END IF;

      IF (P_QTSEGSEX IS NULL AND P_QTSABADO IS NULL AND P_QTDOMFERI IS NULL) OR
         (P_QTSEGSEX + P_QTSABADO + P_QTDOMFERI = 0) THEN
         -- Não foram informados comensais estimados
         I_L(MSG('TCOPROC_COMENSAIS_N_INF'));
      END IF;    
      
      SELECT COUNT(1)
        INTO V_QTDE
        FROM LISTA
       WHERE NRLISTA = P_CONFIGURACOES;
      IF P_CONFIGURACOES IS NULL OR V_QTDE = 0 THEN
         -- Não foi informada a configuração de colunas do cardápio
         I_L(MSG('TCOPROC_CONFIG_N_INF'));
      ELSE
         SELECT COUNT(1)
           INTO V_QTDE
           FROM CONFIGCARDBASE C
                INNER JOIN LISTA L ON C.NRCONFIGCARDBASE = TO_NUMBER(L.CDLISTA)
          WHERE L.NRLISTA = P_CONFIGURACOES
            AND C.NRCARDAPIOBASE = P_NRCARDAPIOBASE;
         IF V_QTDE = 0 THEN
            -- Configuração informada não encontrada no cardápio base
            I_L(MSG('TCOPROC_CONFIG_NEXIST_CARDBASE'));
         END IF;
      END IF;

      SELECT COUNT(1)
        INTO V_QTDE
        FROM LISTA
       WHERE NRLISTA = P_GRUPOS;
      IF P_GRUPOS IS NULL OR V_QTDE = 0 THEN         
         -- Grupos de tipos de prato não informados
         I_L(MSG('TCOPROC_GRTIPOPRAT_N_INF'));
      ELSE
         --Verifica se as configurações e os grupos informados estão corretos
         FOR C_CNF IN 
         (
         SELECT C.IDCLASSIFICACAO,
                G.CDGRTIPOPR, 
                T.NMTIPOPRAT || ' (' || NVL(C.DSCOMPLEMENTO, ' ') || ')' AS DESCRICAO,
                G.NMGRTIPOPR,
                CASE WHEN
                NOT EXISTS (
                  SELECT 1
                    FROM LISTA
                   WHERE NRLISTA = P_GRUPOS
                     AND SUBSTR(CDLISTA, 1, INSTR(CDLISTA, '|') - 1) = G.CDGRTIPOPR
                ) THEN 'S' ELSE 'N' END AS GRUPO_INFORMADO
           FROM CONFIGCARDBASE C
                INNER JOIN LISTA L ON C.NRCONFIGCARDBASE = TO_NUMBER(L.CDLISTA)
                INNER JOIN TIPOPRAT T ON T.CDTIPOPRAT = C.CDTIPOPRAT
                LEFT JOIN GRTIPOPR G ON G.CDGRTIPOPR = T.CDGRTIPOPR
          WHERE L.NRLISTA = P_CONFIGURACOES
            AND C.NRCARDAPIOBASE = P_NRCARDAPIOBASE
            AND C.IDCLASSIFICACAO = 'ALIMENTAR'
            AND (G.CDGRTIPOPR IS NULL OR
            NOT EXISTS (
               SELECT 1
                 FROM LISTA
                WHERE NRLISTA = P_GRUPOS
                  AND SUBSTR(CDLISTA, 1, INSTR(CDLISTA, '|') - 1) = G.CDGRTIPOPR
            ))
         ) LOOP
            IF C_CNF.CDGRTIPOPR IS NULL THEN
               -- Grupo de tipo de prato da coluna __PARAM0__ não cadastrado no tipo de prato
               I_L(MSG('TCOPROC_GRTIPOPRAT_N_CAD', C_CNF.DESCRICAO));
            END IF;
            IF C_CNF.GRUPO_INFORMADO = 'N' THEN
               -- Grupo de tipo de prato __PARAM0__ da coluna __PARAM1__ não informado
               I_L(MSG('TCOPROC_GRTIPOPRAT_COLUNA_N_INF', C_CNF.NMGRTIPOPR, C_CNF.DESCRICAO));
            END IF;
            -- IF C_CNF.IDCLASSIFICACAO <> 'ALIMENTAR' THEN
            --    -- Classificação da coluna informada __PARAM0__ não é "Alimentar"
            --    I_L(MSG('TCOPROC_CLASS_COLUNA_N_E_ALIMENTAR', C_CNF.DESCRICAO));
            -- END IF;
         END LOOP;

         FOR C_GRUPOS IN
         (SELECT G.CDGRTIPOPR || ' - ' || G.NMGRTIPOPR AS GRUPO
            FROM GRTIPOPR G
                 INNER JOIN LISTA LI ON SUBSTR(LI.CDLISTA, 1, INSTR(LI.CDLISTA, '|') - 1) = G.CDGRTIPOPR
           WHERE NRLISTA = P_GRUPOS
             AND NOT EXISTS (SELECT 1
                               FROM CONFIGCARDBASE C
                                    INNER JOIN LISTA L ON C.NRCONFIGCARDBASE = TO_NUMBER(L.CDLISTA)
                                    INNER JOIN TIPOPRAT T ON T.CDTIPOPRAT = C.CDTIPOPRAT
                              WHERE L.NRLISTA = P_CONFIGURACOES
                                AND C.IDCLASSIFICACAO = 'ALIMENTAR'
                                AND T.CDGRTIPOPR = G.CDGRTIPOPR)
         ) LOOP
            -- Grupo de tipo de prato __PARAM0__ não possui colunas selecionadas
            I_L(MSG('TCOPROC_GRTIPOPRAT_SEM_COLUNAS', C_GRUPOS.GRUPO));
         END LOOP;

         SELECT MAX(CDFILIAL), MAX(CDTIPOCUSTO), MAX(CDTIPOPRATLIMPEZA)
           INTO V_CDFILIAL, V_CDTIPOCUSTO, V_CDTIPOPRATLIMPEZA
           FROM PARAMTCO;         
         -- IF V_CDTIPOCUSTO IS NULL THEN            
         --    -- Tipo de custo não informado nos parâmetros comerciais
         --    I_L(MSG('TCOPROC_TIPOCUSTO_N_INF_PARAMTCO'));
         -- END IF;
         IF V_CDFILIAL IS NULL THEN
            -- Unidade base para elaboração do cardápio não informada nos parâmetros comerciais
            I_L(MSG('TCOPROC_FILIAL_N_INF_PARAMTCO'));
         END IF;

      END IF;

      SELECT MAX(S.CDSERVICOPROPOSTA || ' - ' || S.NMSERVICOPROPOSTA), MAX(S.CDFILIAL), 
             MAX(S.CDSERVFILI), MAX(SE.CDSERVFILI || ' - ' || SE.NMSERVICO)
        INTO V_SERVICOPROPOSTA, V_CDFILIALSERV, 
             V_CDSERVFILI, V_NMSERVICO
        FROM SERVICOPROPOSTA S
             LEFT JOIN SERVICO SE ON SE.CDFILIAL = S.CDFILIAL AND
                                     SE.CDSERVFILI = S.CDSERVFILI
       WHERE S.NRSERVICOPROPOSTA = V_NRSERVICOPROPOSTA;

      IF V_CDFILIAL <> V_CDFILIALSERV THEN
         -- Unidade do serviço de planejamento do serviço para proposta difere da unidade base para elaboração do cardápio
         I_L(MSG('TCOPROC_FILIAL<>FILIAL_SERVPROPOSTA'));
      END IF;

      IF V_CDSERVFILI IS NULL THEN
         -- Serviço de planejamento não indicado no serviço para proposta
         I_L(MSG('TCOPROC_SERVPLAN_N_CAD_SERVPROPOSTA'));
      END IF;
--=========================================================
--=== Procedimento
--=========================================================   
      IF P_LISTAERROS IS NULL THEN   
      --=========================================================
      --=== Cabeçalho, configuração selecionada e dias
      --=========================================================   
         
         --Insere cardápio
         V_NRCARDAPIOTRAB := TO_NUMBER(RETORNA_NOVO_CODIGO('CARDAPIOTRAB', 1));
         INSERT INTO CARDAPIOTRAB
         (NRCARDAPIOTRAB, CDREGIAO, VRPEACRESCUSTO,
          DTCUSTO, CDTIPOCUSTO, IDORIGEM,
          NRCARDAPIOBASE,
          NRORG, NRORGINCLUSAO, NRORGULTATU,
          CDOPERINCLUSAO, CDOPERULTATU,
          DTINCLUSAO, DTULTATU)
         VALUES
         (V_NRCARDAPIOTRAB, P_CDREGIAO, P_VRPEACRESCUSTO,
          TRUNC(P_DTCUSTO), V_CDTIPOCUSTO, P_IDORIGEM, P_NRCARDAPIOBASE,
          P_NRORG, P_NRORG, P_NRORG,
          P_CDOPERADOR, P_CDOPERADOR,
          SYSDATE, SYSDATE);

         --Inclusão dos dias
         SELECT COUNT(1)
           INTO V_QTDE
           FROM DIACARDBASE
          WHERE NRCARDAPIOBASE = P_NRCARDAPIOBASE;
         IF V_QTDE = 0 THEN
            -- Cardápio base não possui dias cadastrados
            I_L(MSG('TCOPROC_CARDBASE_N_POSSUI_DIAS'));
         ELSE
            V_NRDIACARDTRAB := TO_NUMBER(RETORNA_NOVO_CODIGO('DIACARDTRAB', V_QTDE));

            INSERT INTO DIACARDTRAB
            (NRDIACARDTRAB, NRCARDAPIOTRAB,
             NRSEMANA, NRDIASEMANA, QTCOMENSAIS, 
             NRORG, NRORGINCLUSAO, NRORGULTATU,
             CDOPERINCLUSAO, CDOPERULTATU,
             DTINCLUSAO, DTULTATU)
            SELECT V_NRDIACARDTRAB + (ROW_NUMBER() OVER (ORDER BY D.NRDIACARDBASE) - 1) AS NRDIACARDTRAB,
                   V_NRCARDAPIOTRAB,
                   D.NRSEMANA, D.NRDIASEMANA, 
                   CASE WHEN D.NRDIASEMANA = 1 THEN NVL(P_QTDOMFERI, 0)
                        WHEN D.NRDIASEMANA BETWEEN 2 AND 6 THEN NVL(P_QTSEGSEX, 0)
                        WHEN D.NRDIASEMANA = 7 THEN NVL(P_QTSABADO, 0)
                   END AS QTCOMENSAIS,
                   P_NRORG, P_NRORG, P_NRORG,
                   P_CDOPERADOR, P_CDOPERADOR,
                   SYSDATE, SYSDATE
              FROM DIACARDBASE D
             WHERE NRCARDAPIOBASE = P_NRCARDAPIOBASE
             ORDER BY D.NRDIACARDBASE;
         END IF;
         SELECT COUNT(1)
           INTO V_QTDE
           FROM CONFIGCARDBASE C
                INNER JOIN LISTA L ON C.NRCONFIGCARDBASE = TO_NUMBER(L.CDLISTA)
          WHERE L.NRLISTA = P_CONFIGURACOES
            AND C.NRCARDAPIOBASE = P_NRCARDAPIOBASE
            AND C.IDCLASSIFICACAO = 'ALIMENTAR';
         
         -- Inclusão da Configuração
         V_NRCONFIGCARDTRAB := TO_NUMBER(RETORNA_NOVO_CODIGO('CONFIGCARDTRAB', V_QTDE));
         INSERT INTO CONFIGCARDTRAB
         (NRCONFIGCARDTRAB, NRCARDAPIOTRAB,
          CDTIPOPRAT, DSCOMPLEMENTO, IDCLASSIFICACAO, 
          NRORDEM,IDTEMPERATURA, NRCONFIGCARDBASE,
          NRORG, NRORGINCLUSAO, NRORGULTATU,
          CDOPERINCLUSAO, CDOPERULTATU,
          DTINCLUSAO, DTULTATU)
         SELECT V_NRCONFIGCARDTRAB + (ROW_NUMBER() OVER (ORDER BY C.NRCONFIGCARDBASE) - 1) AS NRCONFIGCARDTRAB,
                V_NRCARDAPIOTRAB,
                C.CDTIPOPRAT, C.DSCOMPLEMENTO, C.IDCLASSIFICACAO, 
                C.NRORDEM, C.IDTEMPERATURA, C.NRCONFIGCARDBASE,
                P_NRORG, P_NRORG, P_NRORG,
                P_CDOPERADOR, P_CDOPERADOR,
                SYSDATE, SYSDATE
           FROM CONFIGCARDBASE C
                INNER JOIN LISTA L ON C.NRCONFIGCARDBASE = TO_NUMBER(L.CDLISTA)
          WHERE L.NRLISTA = P_CONFIGURACOES
            AND C.NRCARDAPIOBASE = P_NRCARDAPIOBASE
            AND C.IDCLASSIFICACAO = 'ALIMENTAR'           
          ORDER BY C.NRCONFIGCARDBASE;
      --=========================================================
      --=== Composição a partir do cardápio base
      --=========================================================   
         FOR C_CNFTRAB IN
         (
            SELECT C.NRCONFIGCARDTRAB,
                   T.NMTIPOPRAT || ' (' || NVL(C.DSCOMPLEMENTO, ' ') || ')' AS DESCRICAO,
                   C.NRCONFIGCARDBASE
              FROM CONFIGCARDTRAB C
                   INNER JOIN TIPOPRAT T ON T.CDTIPOPRAT = C.CDTIPOPRAT
             WHERE C.NRCARDAPIOTRAB = V_NRCARDAPIOTRAB         
         ) LOOP
            FOR C_DIATRAB IN
            (
               SELECT D.NRDIACARDTRAB, LPAD(TO_CHAR((D.NRSEMANA - 1) * 7 + D.NRDIASEMANA),2, '0') AS DIA, DB.NRDIACARDBASE, D.QTCOMENSAIS,
               		  D.NRSEMANA, D.NRDIASEMANA
                 FROM DIACARDTRAB D
                      INNER JOIN DIACARDBASE DB ON DB.NRSEMANA = D.NRSEMANA AND
                                                   DB.NRDIASEMANA = D.NRDIASEMANA 
                WHERE D.NRCARDAPIOTRAB = V_NRCARDAPIOTRAB
                  AND DB.NRCARDAPIOBASE = P_NRCARDAPIOBASE
                  AND D.QTCOMENSAIS > 0
            ) LOOP               
               V_NRPRATCOMPCARDBASE := NULL;
               
               SELECT MAX(NRCOMPCARDBASE)
                 INTO V_NRCOMPCARDBASE
                 FROM COMPCARDBASE
                WHERE NRCARDAPIOBASE = P_NRCARDAPIOBASE
                  AND NRDIACARDBASE = C_DIATRAB.NRDIACARDBASE
                  AND NRCONFIGCARDBASE = C_CNFTRAB.NRCONFIGCARDBASE;
               IF V_NRCOMPCARDBASE IS NULL THEN
                  -- Não há pratos no cardápio base para o dia __PARAM0__ e coluna __PARAM1__
                  I_L(MSG('TCOPROC_CARDBASE_N_POSSUI_PRATOS_DIA', NOME_DIA(C_DIATRAB.NRSEMANA, C_DIATRAB.NRDIASEMANA), C_CNFTRAB.DESCRICAO));
               ELSE
                  SELECT COUNT(1), MAX(P.NRPRATCOMPCARDBASE)
                    INTO V_QTDE, V_NRPRATCOMPCARDBASE
                    FROM PRATCOMPCARDBASE P
                         INNER JOIN REGIAOPRATCARDBASE R ON R.NRPRATCOMPCARDBASE = P.NRPRATCOMPCARDBASE
                   WHERE P.NRCOMPCARDBASE = V_NRCOMPCARDBASE
                     AND R.CDREGIAO = P_CDREGIAO;

                  IF V_QTDE = 0 THEN
                     -- Não há pratos no cardápio base que atendam a região __PARAM0__ no dia __PARAM1__ e coluna __PARAM2__
                     I_L(MSG('TCOPROC_CARDBASE_N_POSSUI_PRATOS_DIA_PARA_REGIAO', V_NMREGIAO, NOME_DIA(C_DIATRAB.NRSEMANA, C_DIATRAB.NRDIASEMANA), C_CNFTRAB.DESCRICAO));
                  ELSIF V_QTDE > 1 THEN
                     -- Há dois ou mais pratos no cardápio base que atendem a região __PARAM0__ no dia __PARAM1__ e coluna __PARAM2__
                     I_L(MSG('TCOPROC_CARDBASE_MAISDE1_PRATO_DIA_PARA_REGIAO', V_NMREGIAO, NOME_DIA(C_DIATRAB.NRSEMANA, C_DIATRAB.NRDIASEMANA), C_CNFTRAB.DESCRICAO));
                  ELSE
                     SELECT MAX(P.CDFILAUXPRAT), MAX(P.CDPRATO), MAX(PT.CDPRATO || ' - ' || PT.NMPRATO), MAX(PT.IDATIVO)
                       INTO V_CDFILAUXPRAT, V_CDPRATO, V_NMPRATO, V_IDATIVO
                       FROM PRATCOMPCARDBASE P
                            INNER JOIN PRATO PT ON PT.CDFILAUXPRAT = P.CDFILAUXPRAT AND
                                                   PT.CDPRATO = P.CDPRATO
                      WHERE P.NRPRATCOMPCARDBASE = V_NRPRATCOMPCARDBASE;
                     
                     IF V_IDATIVO = 'N' THEN
                        -- O prato __PARAM0__ está inativo
                        I_L(MSG('TCOPROC_PRATO_INATIVO', V_NMPRATO));
                     END IF;

                     SELECT COUNT(1)
                       INTO V_QTDE
                       FROM GRUPOPRATO G INNER JOIN GRUPOPRATOSERV GS ON G.NRGRUPOPRATO = GS.NRGRUPOPRATO
                                          INNER JOIN ITGRUPOPRATOSERV IT ON IT.NRGRUPOPRATOSERV = GS.NRGRUPOPRATOSERV
                       WHERE G.CDFILIAL = V_CDFILIAL AND
                             GS.CDSERVFILI = V_CDSERVFILI AND
                             IT.CDPRATO = V_CDPRATO AND
                             IT.CDFILAUXPRAT = V_CDFILAUXPRAT AND
                             G.IDTIPORESTRICAO = 'CONTRATO';

                     IF V_QTDE = 0 THEN
                        -- O prato __PARAM0__ não está cadastrado a grupo de prato para o serviço __PARAM1__ na unidade __PARAM2__
                        I_L(MSG('TCOPROC_PRATO_N_CAD_GRUPOPRAT', V_NMPRATO, V_NMSERVICO, V_CDFILIAL));
                     ELSIF V_QTDE > 1 THEN
                        -- O prato __PARAM0__ está cadastrado a dois ou mais grupos de prato para o serviço __PARAM1__ na unidade __PARAM2__
                        I_L(MSG('TCOPROC_PRATO_MAISDE1_GRUPOPRAT', V_NMPRATO, V_NMSERVICO, V_CDFILIAL));
                     END IF;

                     V_NRCOMPCARDTRAB := TO_NUMBER(RETORNA_NOVO_CODIGO('COMPCARDTRAB', 1));

                     INSERT INTO COMPCARDTRAB
                     (NRCOMPCARDTRAB, NRCARDAPIOTRAB, 
                      NRDIACARDTRAB, NRCONFIGCARDTRAB,
                      CDFILAUXPRAT, CDPRATO, VRPECONSCARDTRAB,
                      NRORG, NRORGINCLUSAO, NRORGULTATU,
                      CDOPERINCLUSAO, CDOPERULTATU,
                      DTINCLUSAO, DTULTATU)
                     VALUES
                     (V_NRCOMPCARDTRAB, V_NRCARDAPIOTRAB,
                      C_DIATRAB.NRDIACARDTRAB, C_CNFTRAB.NRCONFIGCARDTRAB,
                      V_CDFILAUXPRAT, V_CDPRATO, 100,
                      P_NRORG, P_NRORG, P_NRORG,
                      P_CDOPERADOR, P_CDOPERADOR,
                      SYSDATE, SYSDATE);

                     SELECT COUNT(1)
                       INTO V_QTDE
                       FROM RECEPRATCARDTRAB
                      WHERE NRCARDAPIOTRAB = V_NRCARDAPIOTRAB
                        AND CDFILAUXPRAT = V_CDFILAUXPRAT
                        AND CDPRATO = V_CDPRATO;

                     IF V_QTDE = 0 THEN
                        V_IDRECEITA := RECE_UTIL_TCO(V_CDFILAUXPRAT,
                                                      V_CDPRATO,
                                                      V_CDFILIAL,
                                                      V_NRSERVICOPROPOSTA,
                                                      V_NRPADRAOQUALIDADE,
                                                      P_CDREGIAO,
                                                      NULL);

                        IF V_IDRECEITA IS NULL THEN
                           -- O prato __PARAM0__ não possui receita cadastrada
                           I_L(MSG('TCOPROC_PRATO_SEM_RECEITA', V_NMPRATO));
                        ELSE                              
                           IF V_IDRECEITA = 'R' THEN
                              SELECT COUNT(1)
                                INTO V_QTDE
                                FROM RECEREGIAO
                               WHERE CDFILAUXPRAT = V_CDFILAUXPRAT
                                 AND CDPRATO = V_CDPRATO
                                 AND CDREGIAO = P_CDREGIAO
                                 AND NRPADRAOQUALIDADE = V_NRPADRAOQUALIDADE;

                              V_NRRECEPRATCARDTRAB := TO_NUMBER(RETORNA_NOVO_CODIGO('RECEPRATCARDTRAB', V_QTDE));

                              INSERT INTO RECEPRATCARDTRAB
                              (NRRECEPRATCARDTRAB, NRCARDAPIOTRAB,
                               CDFILAUXPRAT, CDPRATO,
                               CDPRODUTO, QTPRODRECCARDTRAB,
                               VRPEFATCOCCARDTRAB, VRPEFATCORCARDTRAB,
                               SGUNIDADE, QTBRUTACARDTRABUNR,
                               IDPRODBASECARDTRAB, IDQTDEFIXCARDTRAB,
                               NRORG, NRORGINCLUSAO, NRORGULTATU,
                               CDOPERINCLUSAO, CDOPERULTATU,
                               DTINCLUSAO, DTULTATU)                                 
                              SELECT V_NRRECEPRATCARDTRAB + (ROW_NUMBER() OVER (ORDER BY R.NRRECEREGIAO) - 1) AS NRRECEPRATCARDTRAB,
                                     V_NRCARDAPIOTRAB, R.CDFILAUXPRAT, R.CDPRATO,
                                     R.CDPRODUTO, R.QTPRODRECREGIAO,
                                     NVL(R.VRPEFATCOCREGIAO, 0), NVL(R.VRPEFATCORREGIAO, 0),
                                     NVL(R.SGUNIDADE, P.SGUNIDADE), R.QTBRUTAREGIAOUNR,
                                     NVL(R.IDPRODBASEREGIAO, 'N'), NVL(R.IDQTDEFIXREGIAO, 'N'),
                                     P_NRORG, P_NRORG, P_NRORG,
                                     P_CDOPERADOR, P_CDOPERADOR,
                                     SYSDATE, SYSDATE
                                FROM RECEREGIAO R INNER JOIN PRODUTO P ON P.CDPRODUTO = R.CDPRODUTO
                               WHERE R.CDFILAUXPRAT = V_CDFILAUXPRAT
                                 AND R.CDPRATO = V_CDPRATO
                                 AND R.CDREGIAO = P_CDREGIAO
                                 AND R.NRPADRAOQUALIDADE = V_NRPADRAOQUALIDADE
                               ORDER BY R.NRRECEREGIAO;

                           ELSIF V_IDRECEITA = 'Q' THEN
                              SELECT COUNT(1)
                                INTO V_QTDE
                                FROM RECEPADQUALI
                               WHERE CDFILAUXPRAT = V_CDFILAUXPRAT
                                 AND CDPRATO = V_CDPRATO
                                 AND NRPADRAOQUALIDADE = V_NRPADRAOQUALIDADE;

                              V_NRRECEPRATCARDTRAB := TO_NUMBER(RETORNA_NOVO_CODIGO('RECEPRATCARDTRAB', V_QTDE));

                              INSERT INTO RECEPRATCARDTRAB
                              (NRRECEPRATCARDTRAB, NRCARDAPIOTRAB, 
                               CDFILAUXPRAT, CDPRATO,
                               CDPRODUTO, QTPRODRECCARDTRAB,
                               VRPEFATCOCCARDTRAB, VRPEFATCORCARDTRAB,
                               SGUNIDADE, QTBRUTACARDTRABUNR,
                               IDPRODBASECARDTRAB, IDQTDEFIXCARDTRAB,
                               NRORG, NRORGINCLUSAO, NRORGULTATU,
                               CDOPERINCLUSAO, CDOPERULTATU,
                               DTINCLUSAO, DTULTATU)                                 
                              SELECT V_NRRECEPRATCARDTRAB + (ROW_NUMBER() OVER (ORDER BY R.NRRECEPADQUALI) - 1) AS NRRECEPRATCARDTRAB,
                                     V_NRCARDAPIOTRAB, R.CDFILAUXPRAT, R.CDPRATO,
                                     R.CDPRODUTO, R.QTPRODRECPADQ,
                                     NVL(R.VRPEFATCOCPADQ, 0), NVL(R.VRPEFATCORPADQ, 0),
                                     NVL(R.SGUNIDADE, P.SGUNIDADE), R.QTBRUTAPADQUNR,
                                     NVL(R.IDPRODBASEPADQ,'N'), NVL(R.IDQTDEFIXPADQ, 'N'),
                                     P_NRORG, P_NRORG, P_NRORG,
                                     P_CDOPERADOR, P_CDOPERADOR,
                                     SYSDATE, SYSDATE
                                FROM RECEPADQUALI R INNER JOIN PRODUTO P ON P.CDPRODUTO = R.CDPRODUTO
                               WHERE R.CDFILAUXPRAT = V_CDFILAUXPRAT
                                 AND R.CDPRATO = V_CDPRATO
                                 AND R.NRPADRAOQUALIDADE = V_NRPADRAOQUALIDADE
                               ORDER BY R.NRRECEPADQUALI;

                           ELSIF V_IDRECEITA = 'S' THEN                           

                              SELECT COUNT(1)
                                INTO V_QTDE
                                FROM RECESERV
                               WHERE CDFILAUXPRAT = V_CDFILAUXPRAT
                                 AND CDPRATO = V_CDPRATO
                                 AND CDFILIAL = V_CDFILIAL
                                 AND CDSERVFILI = V_CDSERVFILI;

                              SELECT MAX(IDATIVO)
                                INTO V_IDATIVO
                                FROM PRATSERV
                               WHERE CDFILAUXPRAT = V_CDFILAUXPRAT
                                 AND CDPRATO = V_CDPRATO
                                 AND CDFILIAL = V_CDFILIAL
                                 AND CDSERVFILI = V_CDSERVFILI;

                              IF V_IDATIVO = 'N' THEN
                                 -- Receita por servico do prato __PARAM0__ está inativa para unidade __PARAM1__ e servico __PARAM2__
                                 I_L(MSG('TCOPROC_RECESERV_INATIVA', V_NMPRATO, V_CDFILIAL, V_NMSERVICO));
                              END IF;

                              V_NRRECEPRATCARDTRAB := TO_NUMBER(RETORNA_NOVO_CODIGO('RECEPRATCARDTRAB', V_QTDE));

                              INSERT INTO RECEPRATCARDTRAB
                              (NRRECEPRATCARDTRAB, NRCARDAPIOTRAB, 
                               CDFILAUXPRAT, CDPRATO,
                               CDPRODUTO, QTPRODRECCARDTRAB,
                               VRPEFATCOCCARDTRAB, VRPEFATCORCARDTRAB,
                               SGUNIDADE, QTBRUTACARDTRABUNR,
                               IDPRODBASECARDTRAB, IDQTDEFIXCARDTRAB,
                               NRORG, NRORGINCLUSAO, NRORGULTATU,
                               CDOPERINCLUSAO, CDOPERULTATU,
                               DTINCLUSAO, DTULTATU)                                 
                              SELECT V_NRRECEPRATCARDTRAB + (ROW_NUMBER() OVER (ORDER BY R.CDPRODUTO) - 1) AS NRRECEPRATCARDTRAB,
                                     V_NRCARDAPIOTRAB, R.CDFILAUXPRAT, R.CDPRATO,
                                     R.CDPRODUTO, R.QTPRODRECSER,
                                     NVL(R.VRPEFATCOCSE, 0), NVL(R.VRPEFATCORSE, 0),
                                     NVL(R.SGUNIDADE, P.SGUNIDADE), R.QTBRUTASEUNR,
                                     NVL(R.IDPRODBASESE, 'N'), NVL(R.IDQTDEFIXSE, 'N'),
                                     P_NRORG, P_NRORG, P_NRORG,
                                     P_CDOPERADOR, P_CDOPERADOR,
                                     SYSDATE, SYSDATE
                                FROM RECESERV R INNER JOIN PRODUTO P ON P.CDPRODUTO = R.CDPRODUTO
                               WHERE R.CDFILAUXPRAT = V_CDFILAUXPRAT
                                 AND R.CDPRATO = V_CDPRATO
                                 AND R.CDFILIAL = V_CDFILIAL
                                 AND R.CDSERVFILI = V_CDSERVFILI
                               ORDER BY R.CDPRODUTO;

                           ELSIF V_IDRECEITA = 'F' THEN
                              SELECT COUNT(1)
                                INTO V_QTDE
                                FROM RECEFILI
                               WHERE CDFILAUXPRAT = V_CDFILAUXPRAT
                                 AND CDPRATO = V_CDPRATO
                                 AND CDFILIAL = V_CDFILIAL;

                              SELECT MAX(IDATIVO)
                                INTO V_IDATIVO
                                FROM PRATFILI
                               WHERE CDFILAUXPRAT = V_CDFILAUXPRAT
                                 AND CDPRATO = V_CDPRATO
                                 AND CDFILIAL = V_CDFILIAL;

                              IF V_IDATIVO = 'N' THEN
                                 -- Receita por unidade do prato __PARAM0__ está inativa para unidade __PARAM1__
                                 I_L(MSG('TCOPROC_RECEFILI_INATIVA', V_NMPRATO, V_CDFILIAL));
                              END IF;

                              V_NRRECEPRATCARDTRAB := TO_NUMBER(RETORNA_NOVO_CODIGO('RECEPRATCARDTRAB', V_QTDE));

                              INSERT INTO RECEPRATCARDTRAB
                              (NRRECEPRATCARDTRAB, NRCARDAPIOTRAB, 
                               CDFILAUXPRAT, CDPRATO,
                               CDPRODUTO, QTPRODRECCARDTRAB,
                               VRPEFATCOCCARDTRAB, VRPEFATCORCARDTRAB,
                               SGUNIDADE, QTBRUTACARDTRABUNR,
                               IDPRODBASECARDTRAB, IDQTDEFIXCARDTRAB,
                               NRORG, NRORGINCLUSAO, NRORGULTATU,
                               CDOPERINCLUSAO, CDOPERULTATU,
                               DTINCLUSAO, DTULTATU)                                 
                              SELECT V_NRRECEPRATCARDTRAB + (ROW_NUMBER() OVER (ORDER BY R.CDPRODUTO) - 1) AS NRRECEPRATCARDTRAB,
                                     V_NRCARDAPIOTRAB, R.CDFILAUXPRAT, R.CDPRATO,
                                     R.CDPRODUTO, R.QTPRODRECLOC,
                                     NVL(R.VRPEFATCOCLO, 0), NVL(R.VRPEFATCORLO, 0),
                                     NVL(R.SGUNIDADE, P.SGUNIDADE), R.QTBRUTALOUNR,
                                     NVL(R.IDPRODBASELO, 'N'), NVL(R.IDQTDEFIXLO, 'N'),
                                     P_NRORG, P_NRORG, P_NRORG,
                                     P_CDOPERADOR, P_CDOPERADOR,
                                     SYSDATE, SYSDATE
                                FROM RECEFILI R INNER JOIN PRODUTO P ON P.CDPRODUTO = R.CDPRODUTO
                               WHERE R.CDFILAUXPRAT = V_CDFILAUXPRAT
                                 AND R.CDPRATO = V_CDPRATO
                                 AND R.CDFILIAL = V_CDFILIAL
                               ORDER BY R.CDPRODUTO;

                           ELSIF V_IDRECEITA = 'P' THEN                           
                              SELECT COUNT(1)
                                INTO V_QTDE
                                FROM RECEPADR
                               WHERE CDFILAUXPRAT = V_CDFILAUXPRAT
                                 AND CDPRATO = V_CDPRATO;

                              SELECT MAX(IDATIVO)
                                INTO V_IDATIVO
                                FROM PRATPADR
                               WHERE CDFILAUXPRAT = V_CDFILAUXPRAT
                                 AND CDPRATO = V_CDPRATO;

                              IF V_IDATIVO = 'N' THEN
                                 -- Receita padrão do prato __PARAM0__ está inativa
                                 I_L(MSG('TCOPROC_RECEPADR_INATIVA', V_NMPRATO));
                              END IF;

                              V_NRRECEPRATCARDTRAB := TO_NUMBER(RETORNA_NOVO_CODIGO('RECEPRATCARDTRAB', V_QTDE));

                              INSERT INTO RECEPRATCARDTRAB
                              (NRRECEPRATCARDTRAB, NRCARDAPIOTRAB, 
                               CDFILAUXPRAT, CDPRATO,
                               CDPRODUTO, QTPRODRECCARDTRAB,
                               VRPEFATCOCCARDTRAB, VRPEFATCORCARDTRAB,
                               SGUNIDADE, QTBRUTACARDTRABUNR,
                               IDPRODBASECARDTRAB, IDQTDEFIXCARDTRAB,
                               NRORG, NRORGINCLUSAO, NRORGULTATU,
                               CDOPERINCLUSAO, CDOPERULTATU,
                               DTINCLUSAO, DTULTATU)                                 
                              SELECT V_NRRECEPRATCARDTRAB + (ROW_NUMBER() OVER (ORDER BY R.CDPRODUTO) - 1) AS NRRECEPRATCARDTRAB,
                                     V_NRCARDAPIOTRAB, R.CDFILAUXPRAT, R.CDPRATO,
                                     R.CDPRODUTO, R.QTPRODPRAT,
                                     NVL(R.VRPEFATCOCPR, 0), NVL(R.VRPEFATCORPR, 0),
                                     NVL(R.SGUNIDADE, P.SGUNIDADE), R.QTBRUTAPRUNR,
                                     NVL(R.IDPRODBASEPR, 'N'), NVL(R.IDQTDEFIXPR, 'N'),
                                     P_NRORG, P_NRORG, P_NRORG,
                                     P_CDOPERADOR, P_CDOPERADOR,
                                     SYSDATE, SYSDATE
                                FROM RECEPADR R INNER JOIN PRODUTO P ON P.CDPRODUTO = R.CDPRODUTO
                               WHERE R.CDFILAUXPRAT = V_CDFILAUXPRAT
                                 AND R.CDPRATO = V_CDPRATO
                              ORDER BY R.CDPRODUTO;
                           END IF;
                        END IF;

                     END IF;                           
                  END IF;
               END IF;               
            END LOOP; 
         END LOOP;
      --=========================================================
      --=== Regras de adesão e gramatura (1ª e 2ª etapas)
      --=========================================================
         FOR C_GRUPOS IN 
         (
            SELECT G.CDGRTIPOPR, 
                   G.CDGRTIPOPR || ' - ' || G.NMGRTIPOPR AS NMGRTIPOPR,
                   P.NRPORCIONAMENTO,
                   P.NMPORCIONAMENTO,                   
                   TO_NUMBER( SUBSTR( LI.CDLISTA, INSTR(LI.CDLISTA, '|', 1, 2) + 1, 50 ) ) AS NRGRAMATURACARDBASE
              FROM GRTIPOPR G                    
                   INNER JOIN LISTA LI ON SUBSTR(LI.CDLISTA, 1, INSTR(LI.CDLISTA, '|') - 1) = G.CDGRTIPOPR
                   LEFT JOIN PORCIONAMENTO P ON P.NRPORCIONAMENTO = TO_NUMBER( SUBSTR( LI.CDLISTA, INSTR(LI.CDLISTA, '|') + 1, INSTR(LI.CDLISTA, '|', 1, 2) - INSTR(LI.CDLISTA, '|') -1 ) )
             WHERE NRLISTA = P_GRUPOS
         ) LOOP
         --=========================================================
         --=== 1ª etapa: Regra de adesão
         --=========================================================
            /*Busca regra de adesão do grupo que corresponda a configuração de serviços no cardápio*/
            V_QTDE := 0;
            V_NRADESAOCARDBASE := NULL;
            V_CDADESAOCARDBASE := NULL;
            FOR C_ADESAO IN
            (
               SELECT A.NRADESAOCARDBASE, A.CDADESAOCARDBASE
                 FROM ADESAOCARDBASE A
                WHERE A.NRCARDAPIOBASE = P_NRCARDAPIOBASE
                  AND A.CDGRTIPOPR = C_GRUPOS.CDGRTIPOPR
                  AND A.IDATIVO = 'S'
            ) LOOP
               -- Verifica se os itens da regra correspondem a seleção de tipos de prato
               SELECT COUNT(1)
                 INTO V_QTDE2
                 FROM (
                          SELECT C.NRCONFIGCARDBASE
                            FROM CONFIGCARDTRAB C
                                 INNER JOIN TIPOPRAT T ON T.CDTIPOPRAT = C.CDTIPOPRAT
                           WHERE C.NRCARDAPIOTRAB = V_NRCARDAPIOTRAB
                             AND T.CDGRTIPOPR = C_GRUPOS.CDGRTIPOPR
                      ) CNF FULL OUTER JOIN
                      (
                          SELECT DISTINCT I.NRCONFIGCARDBASE
                            FROM ITEMADESAOCBASE I
                           WHERE I.NRADESAOCARDBASE = C_ADESAO.NRADESAOCARDBASE
                      ) I ON I.NRCONFIGCARDBASE = CNF.NRCONFIGCARDBASE
                WHERE I.NRCONFIGCARDBASE IS NULL OR
                      CNF.NRCONFIGCARDBASE IS NULL;

               -- Se itens não correspondem à seleção, passa para a próxima regra
               IF V_QTDE2 > 0 THEN
                  CONTINUE;
               END IF;
                           
               V_ATENDE_SEGMENTO := 'N';
               SELECT COUNT(1)
                 INTO V_QTDE2
                 FROM SEGMERADESAOCBASE
                WHERE NRADESAOCARDBASE = C_ADESAO.NRADESAOCARDBASE;
               -- Se vazio atende a todos os segmentos
               IF V_QTDE2 = 0 THEN
                  V_ATENDE_SEGMENTO := 'S';
               ELSE
                  SELECT COUNT(1)
                    INTO V_QTDE2
                    FROM SEGMERADESAOCBASE
                   WHERE NRADESAOCARDBASE = C_ADESAO.NRADESAOCARDBASE
                     AND CDSEGMER = V_CDSEGMER;
                  IF V_QTDE2 > 0 THEN
                     V_ATENDE_SEGMENTO := 'S';
                  END IF;
               END IF;

               -- verifica se atende ao ramo de atividade
               V_ATENDE_RAMO := 'N';
               SELECT COUNT(1)
                 INTO V_QTDE2
                 FROM ATIVCLIADESAOCBASE
                WHERE NRADESAOCARDBASE = C_ADESAO.NRADESAOCARDBASE;
               -- Se vazio atende a todos os ramos
               IF V_QTDE2 = 0 THEN
                  V_ATENDE_RAMO := 'S';
               ELSE
                  SELECT COUNT(1)
                    INTO V_QTDE2
                    FROM ATIVCLIADESAOCBASE
                   WHERE NRADESAOCARDBASE = C_ADESAO.NRADESAOCARDBASE
                     AND NRATIVCLISEGMER = P_NRATIVCLISEGMER;
                  IF V_QTDE2 > 0 THEN
                     V_ATENDE_RAMO := 'S';
                  END IF;
               END IF;

               IF V_ATENDE_SEGMENTO = 'S' AND V_ATENDE_RAMO = 'S' THEN
                  V_QTDE := V_QTDE + 1;
                  V_NRADESAOCARDBASE := C_ADESAO.NRADESAOCARDBASE;
                  V_CDADESAOCARDBASE := C_ADESAO.CDADESAOCARDBASE;
               END IF;
            END LOOP;

            IF V_QTDE = 0 THEN
               -- Não há regra de adesão que atenda a seleção de tipos de prato, segmento e ramo de atividade informados para o grupo de tipo de prato __PARAM0__
               I_L(MSG('TCOPROC_ADESAO_N_CAD', C_GRUPOS.NMGRTIPOPR));
            ELSIF V_QTDE > 1 THEN
               -- Há mais de uma regra de adesão que atenda a seleção de tipos de prato, segmento e ramo de atividade informados para o grupo de tipo de prato __PARAM0__
               I_L(MSG('TCOPROC_ADESAO_MAISDE1', C_GRUPOS.NMGRTIPOPR));
            ELSE
               SELECT COUNT(1)
                 INTO V_QTDE
                 FROM ITEMADESAOCBASE
                WHERE NRADESAOCARDBASE = V_NRADESAOCARDBASE
                  AND NRPORCIONAMENTO = C_GRUPOS.NRPORCIONAMENTO;

               IF V_QTDE = 0 THEN
                  -- A regra de adesão __PARAM0__ não atende o porcionamento __PARAM1__ do grupo de tipo de prato __PARAM2__ 
                  I_L(MSG('TCOPROC_ADESAO_N_ATENDE_PORCIONAMENTO', V_CDADESAOCARDBASE, C_GRUPOS.NMPORCIONAMENTO,  C_GRUPOS.NMGRTIPOPR));
               ELSE
                  FOR C_ITEMADESAO IN
                  (
                     SELECT NRCONFIGCARDBASE, VRPEADESAO
                       FROM ITEMADESAOCBASE
                      WHERE NRADESAOCARDBASE = V_NRADESAOCARDBASE
                        AND NRPORCIONAMENTO = C_GRUPOS.NRPORCIONAMENTO
                  ) LOOP
                     FOR C_COMPOSICAO IN
                     (
                        SELECT C.NRCOMPCARDTRAB
                          FROM COMPCARDTRAB C
                               INNER JOIN CONFIGCARDTRAB CNF ON CNF.NRCONFIGCARDTRAB = C.NRCONFIGCARDTRAB
                         WHERE C.NRCARDAPIOTRAB = V_NRCARDAPIOTRAB
                           AND CNF.NRCARDAPIOTRAB = V_NRCARDAPIOTRAB
                           AND CNF.NRCONFIGCARDBASE = C_ITEMADESAO.NRCONFIGCARDBASE
                     ) LOOP
                        UPDATE COMPCARDTRAB
                           SET VRPECONSCARDTRAB = NVL(C_ITEMADESAO.VRPEADESAO, 100),
                               NRORGULTATU = P_NRORG,
                               CDOPERULTATU = P_CDOPERADOR,
                               DTULTATU = SYSDATE
                         WHERE NRCOMPCARDTRAB = C_COMPOSICAO.NRCOMPCARDTRAB;
                     END LOOP;
                  END LOOP;
               END IF;
            END IF;
         --=========================================================
         --=== 2ª etapa: Regra de gramatura
         --=========================================================
            IF C_GRUPOS.NRGRAMATURACARDBASE IS NOT NULL THEN
               SELECT MAX(VRGRAMATURA), MAX(SGUNIDADE), MAX(IDTIPOGRAMATURA)
                 INTO V_VRGRAMATURA, V_SGUNIDADE, V_IDTIPOGRAMATURA
                 FROM GRAMATURACARDBASE
                WHERE NRGRAMATURACARDBASE = C_GRUPOS.NRGRAMATURACARDBASE;
               FOR C_COMPOSICAO IN
               (
                  SELECT DISTINCT C.CDFILAUXPRAT, C.CDPRATO, P.CDPRATO || ' - ' || P.NMPRATO AS NMPRATO
                    FROM COMPCARDTRAB C
                         INNER JOIN CONFIGCARDTRAB CNF ON CNF.NRCONFIGCARDTRAB = C.NRCONFIGCARDTRAB
                         INNER JOIN TIPOPRAT T ON T.CDTIPOPRAT = CNF.CDTIPOPRAT
                         INNER JOIN PRATO P ON P.CDFILAUXPRAT = C.CDFILAUXPRAT AND
                                               P.CDPRATO = C.CDPRATO
                   WHERE C.NRCARDAPIOTRAB = V_NRCARDAPIOTRAB
                     AND CNF.NRCARDAPIOTRAB = V_NRCARDAPIOTRAB            
                     AND T.CDGRTIPOPR = C_GRUPOS.CDGRTIPOPR
               ) LOOP
                  V_CDPRODUTO_BASE := NULL;
                  SELECT MAX(CDPRODUTO), COUNT(1)
                    INTO V_CDPRODUTO_BASE, V_QTDE
                    FROM RECEPRATCARDTRAB
                   WHERE NRCARDAPIOTRAB = V_NRCARDAPIOTRAB
                     AND CDFILAUXPRAT = C_COMPOSICAO.CDFILAUXPRAT
                     AND CDPRATO = C_COMPOSICAO.CDPRATO
                     AND IDPRODBASECARDTRAB = 'S';

                  IF V_QTDE > 1 THEN
                     -- Prato __PARAM0__ possui mais de um produto base em sua receita
                     I_L(MSG('TCOPROC_PRATO_MAISDE1_PRODBASE_RECEITA', C_COMPOSICAO.NMPRATO));
                  END IF;
                  FOR C_REGRAGRAM IN
                  (  
                     SELECT CDPRODUTO, CDGRUPPROD, CDSUBGRPROD, VRGRAMATURA
                       FROM ITEMGRAMCARDBASE
                      WHERE NRGRAMATURACARDBASE = C_GRUPOS.NRGRAMATURACARDBASE
                        AND NRPORCIONAMENTO = C_GRUPOS.NRPORCIONAMENTO                        
                  ) LOOP
                     IF C_REGRAGRAM.CDPRODUTO IS NOT NULL THEN                        
                        SELECT MAX(NRRECEPRATCARDTRAB)
                          INTO V_NRRECEPRAT_ESCOLHIDA
                          FROM RECEPRATCARDTRAB
                         WHERE NRCARDAPIOTRAB = V_NRCARDAPIOTRAB
                           AND CDFILAUXPRAT = C_COMPOSICAO.CDFILAUXPRAT
                           AND CDPRATO = C_COMPOSICAO.CDPRATO
                           AND CDPRODUTO = C_REGRAGRAM.CDPRODUTO                           
                           AND (CDPRODUTO = V_CDPRODUTO_BASE OR V_CDPRODUTO_BASE IS NULL);
                     ELSE
                        SELECT MAX(NRRECEPRATCARDTRAB)
                          INTO V_NRRECEPRAT_ESCOLHIDA
                          FROM RECEPRATCARDTRAB R
                               INNER JOIN PRSUBGRPROD PR ON PR.CDPRODUTO = R.CDPRODUTO
                         WHERE R.NRCARDAPIOTRAB = V_NRCARDAPIOTRAB
                           AND R.CDFILAUXPRAT = C_COMPOSICAO.CDFILAUXPRAT
                           AND R.CDPRATO = C_COMPOSICAO.CDPRATO                           
                           AND (R.CDPRODUTO = V_CDPRODUTO_BASE OR V_CDPRODUTO_BASE IS NULL)
                           AND PR.CDGRUPPROD = C_REGRAGRAM.CDGRUPPROD
                           AND PR.CDSUBGRPROD = C_REGRAGRAM.CDSUBGRPROD
                           AND NOT EXISTS (SELECT CDPRODUTO
                                             FROM ITEMGRAMCARDBASE
                                            WHERE NRGRAMATURACARDBASE = C_GRUPOS.NRGRAMATURACARDBASE
                                              AND NRPORCIONAMENTO = C_GRUPOS.NRPORCIONAMENTO
                                              AND CDPRODUTO = PR.CDPRODUTO
                                          );
                     END IF;
                     IF V_NRRECEPRAT_ESCOLHIDA IS NOT NULL THEN
                        V_VRGRAMATURA_REGRA := C_REGRAGRAM.VRGRAMATURA;

                        SELECT MAX(R.CDPRODUTO), MAX(R.QTPRODRECCARDTRAB), MAX(R.VRPEFATCORCARDTRAB), 
                               MAX(R.VRPEFATCOCCARDTRAB), MAX(R.QTBRUTACARDTRABUNR), MAX(CDARVPROD || ' - ' || NMPRODUTO),
                               MAX(R.SGUNIDADE)
                          INTO V_CDPRODUTO, V_QTPRONTA, V_VRPEFATCOR, V_VRPEFATCOC, V_QTINNATURA, V_NMPRODUTO, V_SGUNIDADE_RECEITA
                          FROM RECEPRATCARDTRAB R
                               INNER JOIN PRODUTO P ON P.CDPRODUTO = R.CDPRODUTO
                         WHERE R.NRRECEPRATCARDTRAB = V_NRRECEPRAT_ESCOLHIDA;

                        IF V_SGUNIDADE <> V_SGUNIDADE_RECEITA THEN
                           -- Busca fator para conversão da quantidade da regra para a unidade utilizada na receita
                           SELECT MAX(VRFTCONVER), MAX(IDTIPOPE)
                             INTO V_VRFTCONVER, V_IDTIPOOPE
                             FROM (
                                     SELECT TO_NUMBER(C.VRFATOCONVES) AS VRFTCONVER,
                                            RPAD('/', 1, ' ') AS IDTIPOPE
                                       FROM CONVPRODUTO C
                                            INNER JOIN PRODUTO P ON P.CDPRODUTO = C.CDPRODUTO
                                      WHERE C.CDPRODUTO = V_CDPRODUTO AND
                                            P.SGUNIDADE = V_SGUNIDADE AND
                                            C.SGUNIDADE = V_SGUNIDADE_RECEITA

                                      UNION ALL


                                     SELECT TO_NUMBER(C.VRFATOCONVES) AS VRFTCONVER,
                                            RPAD('*', 1, ' ')       AS IDTIPOPE
                                       FROM CONVPRODUTO C
                                            INNER JOIN PRODUTO P ON P.CDPRODUTO = C.CDPRODUTO
                                      WHERE C.CDPRODUTO = V_CDPRODUTO AND
                                            P.SGUNIDADE = V_SGUNIDADE_RECEITA AND
                                            C.SGUNIDADE = V_SGUNIDADE AND
                                            NOT EXISTS (
                                               SELECT 1
                                                 FROM CONVPRODUTO C
                                                      INNER JOIN PRODUTO P ON P.CDPRODUTO = C.CDPRODUTO
                                                WHERE C.CDPRODUTO = V_CDPRODUTO AND
                                                      P.SGUNIDADE = V_SGUNIDADE AND
                                                      C.SGUNIDADE = V_SGUNIDADE_RECEITA 
                                            )

                                      UNION ALL

                                     SELECT TO_NUMBER(VRFTCONVER)  AS VRFTCONVER,
                                            RPAD(IDTIPOPE, 1, ' ') AS IDTIPOPE
                                       FROM CONVUNID
                                      WHERE SGUNIDPARA = V_SGUNIDADE_RECEITA AND
                                            SGUNIDDE = V_SGUNIDADE AND
                                            NOT EXISTS (
                                               SELECT 1
                                                 FROM CONVPRODUTO C
                                                      INNER JOIN PRODUTO P ON P.CDPRODUTO = C.CDPRODUTO
                                                WHERE C.CDPRODUTO = V_CDPRODUTO AND
                                                      P.SGUNIDADE = V_SGUNIDADE AND
                                                      C.SGUNIDADE = V_SGUNIDADE_RECEITA 
                                            ) AND
                                            NOT EXISTS (
                                               SELECT 1
                                                 FROM CONVPRODUTO C
                                                      INNER JOIN PRODUTO P ON P.CDPRODUTO = C.CDPRODUTO
                                                WHERE C.CDPRODUTO = V_CDPRODUTO AND
                                                      P.SGUNIDADE = V_SGUNIDADE_RECEITA AND
                                                      C.SGUNIDADE = V_SGUNIDADE
                                            )

                                     UNION ALL

                                     SELECT TO_NUMBER(VRFTCONVER)  AS VRFTCONVER,
                                            CASE WHEN IDTIPOPE = '*' THEN '/' ELSE '*' END AS IDTIPOPE
                                       FROM CONVUNID
                                      WHERE SGUNIDPARA = V_SGUNIDADE AND
                                            SGUNIDDE = V_SGUNIDADE_RECEITA AND
                                            NOT EXISTS (
                                               SELECT 1
                                                 FROM CONVPRODUTO C
                                                      INNER JOIN PRODUTO P ON P.CDPRODUTO = C.CDPRODUTO
                                                WHERE C.CDPRODUTO = V_CDPRODUTO AND
                                                      P.SGUNIDADE = V_SGUNIDADE AND
                                                      C.SGUNIDADE = V_SGUNIDADE_RECEITA 
                                            ) AND
                                            NOT EXISTS (
                                               SELECT 1
                                                 FROM CONVPRODUTO C
                                                      INNER JOIN PRODUTO P ON P.CDPRODUTO = C.CDPRODUTO
                                                WHERE C.CDPRODUTO = V_CDPRODUTO AND
                                                      P.SGUNIDADE = V_SGUNIDADE_RECEITA AND
                                                      C.SGUNIDADE = V_SGUNIDADE
                                            ) AND
                                            NOT EXISTS (
                                               SELECT 1
                                                 FROM CONVUNID
                                                WHERE SGUNIDPARA = V_SGUNIDADE_RECEITA AND
                                                      SGUNIDDE = V_SGUNIDADE
                                            )                              
                                  );
                           -- Se encontrado fator de conversão, aplica a operação sobre a quantidade da regra
                           IF V_VRFTCONVER IS NOT NULL AND V_VRFTCONVER > 0 THEN
                              IF V_IDTIPOOPE = '*' THEN
                                 V_VRGRAMATURA_REGRA := V_VRGRAMATURA_REGRA * V_VRFTCONVER;
                              ELSE
                                 V_VRGRAMATURA_REGRA := V_VRGRAMATURA_REGRA / V_VRFTCONVER;
                              END IF;
                           ELSE
                              -- Se não é possível fazer a conversão, essa regra não é válida, passa para a próxima
                              CONTINUE;
                           END IF;
                        END IF;

                        IF V_IDTIPOGRAMATURA = 'INNATURA' THEN
                           V_VRFATOR := V_VRGRAMATURA_REGRA / V_QTINNATURA;
                           V_QTINNATURA := ROUND(V_VRGRAMATURA_REGRA, 5);
                           V_QTLIMPA := ROUND(V_QTINNATURA * (1 - (V_VRPEFATCOR/100) ) , 5);
                           V_QTPRONTA := ROUND(V_QTLIMPA * (1 + (V_VRPEFATCOC/100)), 5);
                        ELSIF V_IDTIPOGRAMATURA = 'PRONTA' THEN
                           V_VRFATOR := V_VRGRAMATURA_REGRA / V_QTPRONTA;
                           V_QTPRONTA := ROUND(V_VRGRAMATURA_REGRA, 5);
                           V_QTLIMPA := ROUND(V_QTPRONTA/(1 + (V_VRPEFATCOC/100)), 5);
                           V_QTINNATURA := ROUND(V_QTLIMPA/(1 - (V_VRPEFATCOR/100)), 5);
                        ELSE
                           V_QTLIMPA := ROUND(V_QTINNATURA * (1 - (V_VRPEFATCOR/100) ) , 5);
                           V_VRFATOR := V_VRGRAMATURA_REGRA / V_QTLIMPA;
                           V_QTLIMPA := ROUND(V_VRGRAMATURA_REGRA, 5);
                           V_QTINNATURA := ROUND(V_QTLIMPA/(1 - (V_VRPEFATCOR/100)), 5);
                           V_QTPRONTA := ROUND(V_QTLIMPA * (1 + (V_VRPEFATCOC/100)), 5);
                        END IF;

                        IF V_QTINNATURA = 0 THEN                           
                           -- Quantidade bruta do produto __PARAM0__ do Prato __PARAM1__ será zero após aplicação da regra de gramatura
                           I_L(MSG('TCOPROC_QTBRUTA_ZERO_APOS_GRAMATURA', V_NMPRODUTO, C_COMPOSICAO.NMPRATO));
                        ELSIF V_QTPRONTA = 0 THEN
                           -- Quantidade pronta do produto __PARAM0__ do Prato __PARAM1__ será zero após aplicação da regra de gramatura
                           I_L(MSG('TCOPROC_QTPRONTA_ZERO_APOS_GRAMATURA', V_NMPRODUTO, C_COMPOSICAO.NMPRATO));
                        END IF;

                        IF V_QTPRONTA > 0 AND V_QTLIMPA > 0 AND V_QTINNATURA > 0 THEN
                           UPDATE RECEPRATCARDTRAB
                              SET QTPRODRECCARDTRAB = V_QTPRONTA,
                                  QTBRUTACARDTRABUNR = V_QTINNATURA,
                                  NRORGULTATU = P_NRORG,
                                  CDOPERULTATU = P_CDOPERADOR,
                                  DTULTATU = SYSDATE
                            WHERE NRRECEPRATCARDTRAB = V_NRRECEPRAT_ESCOLHIDA;

                           FOR C_PRODUTOS IN
                           (
                              SELECT R.NRRECEPRATCARDTRAB, R.CDPRODUTO, R.QTPRODRECCARDTRAB, R.VRPEFATCORCARDTRAB, 
                                     R.VRPEFATCOCCARDTRAB, R.QTBRUTACARDTRABUNR, 
                                     P.CDARVPROD || ' - ' || P.NMPRODUTO AS NMPRODUTO
                                FROM RECEPRATCARDTRAB R
                                     INNER JOIN PRODUTO P ON P.CDPRODUTO = R.CDPRODUTO
                               WHERE R.NRCARDAPIOTRAB = V_NRCARDAPIOTRAB
                                 AND R.CDFILAUXPRAT = C_COMPOSICAO.CDFILAUXPRAT
                                 AND R.CDPRATO = C_COMPOSICAO.CDPRATO
                                 AND R.NRRECEPRATCARDTRAB <> V_NRRECEPRAT_ESCOLHIDA
                                 AND R.IDQTDEFIXCARDTRAB <> 'S'
                           ) LOOP
                              IF V_IDTIPOGRAMATURA = 'INNATURA' THEN
                                 IF V_QTINNATURA = 0 THEN
                                    -- Quantidade bruta do produto __PARAM0__ do Prato __PARAM1__ é zero
                                    I_L(MSG('TCOPROC_QTBRUTA_ZERO', C_PRODUTOS.NMPRODUTO, C_COMPOSICAO.NMPRATO));
                                 ELSE                                    
                                    V_QTINNATURA := ROUND(C_PRODUTOS.QTBRUTACARDTRABUNR * V_VRFATOR, 5);
                                    V_QTLIMPA := ROUND(V_QTINNATURA * (1 - (C_PRODUTOS.VRPEFATCORCARDTRAB/100)), 5);
                                    V_QTPRONTA := ROUND(V_QTLIMPA * (1 + (C_PRODUTOS.VRPEFATCOCCARDTRAB/100)), 5);
                                 END IF;
                              ELSIF V_IDTIPOGRAMATURA = 'PRONTA' THEN
                                 IF V_QTPRONTA = 0 THEN
                                    -- Quantidade pronta do produto __PARAM0__ do Prato __PARAM1__ é zero
                                    I_L(MSG('TCOPROC_QTPRONTA_ZERO', C_PRODUTOS.NMPRODUTO, C_COMPOSICAO.NMPRATO));
                                 ELSE                                    
                                    V_QTPRONTA := ROUND(C_PRODUTOS.QTPRODRECCARDTRAB * V_VRFATOR, 5);
                                    V_QTLIMPA := ROUND(V_QTPRONTA/(1 + (C_PRODUTOS.VRPEFATCOCCARDTRAB/100)), 5);
                                    V_QTINNATURA := ROUND(V_QTLIMPA/(1 - (C_PRODUTOS.VRPEFATCORCARDTRAB/100)), 5);
                                    
                                 END IF;
                              ELSE                                 
                                 IF V_QTINNATURA = 0 THEN
                                    -- Quantidade bruta do produto __PARAM0__ do Prato __PARAM1__ é zero
                                    I_L(MSG('TCOPROC_QTBRUTA_ZERO', C_PRODUTOS.NMPRODUTO, C_COMPOSICAO.NMPRATO));
                                 ELSE                                    
                                    V_QTLIMPA := ROUND(C_PRODUTOS.QTBRUTACARDTRABUNR * (1 - (C_PRODUTOS.VRPEFATCORCARDTRAB/100) ) , 5);
                                    V_QTLIMPA := ROUND(V_QTLIMPA * V_VRFATOR, 5);
                                    V_QTINNATURA := ROUND(V_QTLIMPA/(1 - (C_PRODUTOS.VRPEFATCORCARDTRAB/100)), 5);
                                    V_QTPRONTA := ROUND(V_QTLIMPA * (1 + (C_PRODUTOS.VRPEFATCOCCARDTRAB/100)), 5);
                                 END IF;
                              END IF;
                              IF V_QTINNATURA = 0 THEN
                                 -- Quantidade bruta do produto __PARAM0__ do Prato __PARAM1__ será zero após aplicação da regra de gramatura
                                 I_L(MSG('TCOPROC_QTBRUTA_ZERO_APOS_GRAMATURA', C_PRODUTOS.NMPRODUTO, C_COMPOSICAO.NMPRATO));
                              ELSIF V_QTPRONTA = 0 THEN
                                 -- Quantidade pronta do produto __PARAM0__ do Prato __PARAM1__ será zero após aplicação da regra de gramatura
                                 I_L(MSG('TCOPROC_QTPRONTA_ZERO_APOS_GRAMATURA', C_PRODUTOS.NMPRODUTO, C_COMPOSICAO.NMPRATO));
                              END IF;
                              IF V_QTPRONTA > 0 AND V_QTLIMPA > 0 AND V_QTINNATURA > 0 THEN
                                 UPDATE RECEPRATCARDTRAB
                                    SET QTPRODRECCARDTRAB = V_QTPRONTA,
                                        QTBRUTACARDTRABUNR = V_QTINNATURA,
                                        NRORGULTATU = P_NRORG,
                                        CDOPERULTATU = P_CDOPERADOR,
                                        DTULTATU = SYSDATE
                                  WHERE NRRECEPRATCARDTRAB = C_PRODUTOS.NRRECEPRATCARDTRAB;
                              END IF;
                           END LOOP;
                        END IF;
                     END IF;
                  END LOOP;
               END LOOP;
            END IF;
         END LOOP;
      --=========================================================
      --=== 3ª etapa: Particularidade do Segmento
      --=========================================================
         SELECT MAX(NRPARTSEGCARDBASE), MAX(CDPARTSEGCARDBASE)
           INTO V_NRPARTSEGCARDBASE, V_CDPARTSEGCARDBASE
           FROM PARTSEGCARDBASE
          WHERE NRCARDAPIOBASE = P_NRCARDAPIOBASE
            AND NRATIVCLISEGMER = P_NRATIVCLISEGMER;

         IF V_NRPARTSEGCARDBASE IS NOT NULL THEN
            FOR C_ITPARTSEG IN
            (
               SELECT C.NRCONFIGCARDTRAB, I.VRPERCENTUAL
                 FROM ITPARTSEGCARDBASE I
                      INNER JOIN CONFIGCARDTRAB C ON C.NRCONFIGCARDBASE = I.NRCONFIGCARDBASE
                WHERE NRPARTSEGCARDBASE = V_NRPARTSEGCARDBASE
            ) LOOP
               IF C_ITPARTSEG.VRPERCENTUAL IS NOT NULL THEN
                  FOR C_PRATOS IN
                  (
                     SELECT DISTINCT CDFILAUXPRAT, CDPRATO
                       FROM COMPCARDTRAB
                      WHERE NRCARDAPIOTRAB = V_NRCARDAPIOTRAB
                        AND NRCONFIGCARDTRAB = C_ITPARTSEG.NRCONFIGCARDTRAB
                  ) LOOP                  
                     UPDATE RECEPRATCARDTRAB
                        SET QTBRUTACARDTRABUNR = ROUND(QTBRUTACARDTRABUNR + QTBRUTACARDTRABUNR * C_ITPARTSEG.VRPERCENTUAL/100, 5),
                            QTPRODRECCARDTRAB = ROUND(QTPRODRECCARDTRAB + QTPRODRECCARDTRAB * C_ITPARTSEG.VRPERCENTUAL/100, 5),
                            NRORGULTATU = P_NRORG,
                            CDOPERULTATU = P_CDOPERADOR,
                            DTULTATU = SYSDATE
                      WHERE NRCARDAPIOTRAB = V_NRCARDAPIOTRAB
                        AND CDFILAUXPRAT = C_PRATOS.CDFILAUXPRAT
                        AND CDPRATO = C_PRATOS.CDPRATO
                        AND IDQTDEFIXCARDTRAB <> 'S';
                  END LOOP;
               END IF;
            END LOOP;
         END IF;
      --=========================================================
      --=== Se Cardápio for Complementar a Outro
      --=========================================================
         IF V_IDCOMPLEMENTAR = 'S' THEN
            SELECT COUNT(1), MAX(NRCARDAPIOBASE)
              INTO V_QTDE, V_NRCARDAPIOBASECOMPL
              FROM CARDAPIOTRAB
             WHERE NRCARDAPIOTRAB = P_NRCARDTRABCOMPLEMENTADO;
            IF V_QTDE = 0 THEN
               -- Serviço da proposta é complementar mas não foi informado o cardápio complementado pelo mesmo
               I_L(MSG('TCOPROC_SERVCOMPLEMENTAR_SEM_CARDCOMPLEMENTADO'));
            ELSE
               SELECT COUNT(1), MAX(NRCARDCOMPLCARDBASE)
                 INTO V_QTDE, V_NRCARDCOMPLCARDBASE
                 FROM CARDCOMPLCARDBASE
                WHERE NRCARDAPIOBASE = P_NRCARDAPIOBASE
                  AND NRCARDAPIOBASECOMPL = V_NRCARDAPIOBASECOMPL;

               IF V_QTDE = 0 THEN
                  -- Serviço da proposta complementar não complementa o cardápio complementado informado
                  I_L(MSG('TCOPROC_SERVCOMPLEMENTAR_N_LINK_CARDCOMPLEMENTADO'));
               END IF;
            END IF;
            -- Busca a última ordem cadastrada
            SELECT MAX(NRORDEM)
              INTO V_NRORDEM
              FROM CONFIGCARDTRAB
             WHERE NRCARDAPIOTRAB = V_NRCARDAPIOTRAB;

            -- Valida se os pratos do cardápio complementado não são iguais aos do cardápio complementar
            FOR C_PRATOS_INCORRETOS IN
            (
               SELECT DISTINCT PT.CDPRATO, PT.CDPRATO || ' - ' || PT.NMPRATO AS NMPRATO
                 FROM CONFIGCARDTRAB C
                      INNER JOIN CNFCCOMPLCARDBASE CNF ON CNF.NRCONFIGCARDBASE = C.NRCONFIGCARDBASE
                      INNER JOIN COMPCARDTRAB CO ON CO.NRCARDAPIOTRAB = C.NRCARDAPIOTRAB AND
                                                    CO.NRCONFIGCARDTRAB = C.NRCONFIGCARDTRAB
                      INNER JOIN PRATO PT ON PT.CDFILAUXPRAT = CO.CDFILAUXPRAT AND
                                             PT.CDPRATO = CO.CDPRATO
                WHERE C.NRCARDAPIOTRAB = P_NRCARDTRABCOMPLEMENTADO
                  AND CNF.NRCARDCOMPLCARDBASE = V_NRCARDCOMPLCARDBASE
                  AND EXISTS
                      (
                         SELECT 1
                           FROM COMPCARDTRAB
                          WHERE NRCARDAPIOTRAB = V_NRCARDAPIOTRAB
                            AND CDFILAUXPRAT = CO.CDFILAUXPRAT
                            AND CDPRATO = CO.CDPRATO
                      )
            ) LOOP
               -- Prato __PARAM0__ do cardápio complementado já existe no cardápio
               I_L(MSG('TCOPROC_PRATO_CARDCOMPLEMENTADO_EXISTE', C_PRATOS_INCORRETOS.NMPRATO));
            END LOOP;
            
            -- Percorre as colunas do cardápio complementado
            FOR C_CNFCOMPL IN
            (
               SELECT C.NRCONFIGCARDTRAB, C.CDTIPOPRAT, T.NMTIPOPRAT || ' ('|| NVL(C.DSCOMPLEMENTO, ' ') || ')' AS DESCRICAO, C.IDCLASSIFICACAO,
                      C.NRORDEM, C.IDTEMPERATURA, C.NRCONFIGCARDBASE
                 FROM CONFIGCARDTRAB C
                      INNER JOIN TIPOPRAT T ON T.CDTIPOPRAT = C.CDTIPOPRAT
                      INNER JOIN CNFCCOMPLCARDBASE CNF ON CNF.NRCONFIGCARDBASE = C.NRCONFIGCARDBASE
                WHERE C.NRCARDAPIOTRAB = P_NRCARDTRABCOMPLEMENTADO
                  AND CNF.NRCARDCOMPLCARDBASE = V_NRCARDCOMPLCARDBASE
            ) LOOP

               V_NRORDEM := NVL(V_NRORDEM + 1, 1);
               
               -- Insere configuração
               V_NRCONFIGCARDTRAB := TO_NUMBER(RETORNA_NOVO_CODIGO('CONFIGCARDTRAB', 1));

               INSERT INTO CONFIGCARDTRAB
               (NRCONFIGCARDTRAB, NRCARDAPIOTRAB,
                CDTIPOPRAT, DSCOMPLEMENTO, IDCLASSIFICACAO, 
                NRORDEM,IDTEMPERATURA, NRCONFIGCARDBASE,
                NRORG, NRORGINCLUSAO, NRORGULTATU,
                CDOPERINCLUSAO, CDOPERULTATU,
                DTINCLUSAO, DTULTATU)
               VALUES
               (V_NRCONFIGCARDTRAB, V_NRCARDAPIOTRAB,
                C_CNFCOMPL.CDTIPOPRAT, C_CNFCOMPL.DESCRICAO, C_CNFCOMPL.IDCLASSIFICACAO,
                V_NRORDEM, C_CNFCOMPL.IDTEMPERATURA, NULL,
                P_NRORG, P_NRORG, P_NRORG,
                P_CDOPERADOR, P_CDOPERADOR,
                SYSDATE, SYSDATE);

               -- percorre os dias do cardápio complementado
               FOR C_DIATRAB IN
               (
                  SELECT D.NRDIACARDTRAB, TO_CHAR( (D.NRSEMANA - 1) * 7 + D.NRDIASEMANA) AS DIA, DB.NRDIACARDTRAB AS NRDIACARDTRABORI, D.QTCOMENSAIS,
                         D.NRSEMANA, D.NRDIASEMANA
                    FROM DIACARDTRAB D
                         INNER JOIN DIACARDTRAB DB ON DB.NRSEMANA = D.NRSEMANA AND
                                                      DB.NRDIASEMANA = D.NRDIASEMANA
                   WHERE D.NRCARDAPIOTRAB = V_NRCARDAPIOTRAB
                     AND DB.NRCARDAPIOTRAB = P_NRCARDTRABCOMPLEMENTADO
                     AND D.QTCOMENSAIS > 0
               ) LOOP
                  SELECT MAX(NRCOMPCARDTRAB), MAX(CDFILAUXPRAT), MAX(CDPRATO)                    
                    INTO V_NRCOMPCARDTRABCOMPL, V_CDFILAUXPRAT, V_CDPRATO
                    FROM COMPCARDTRAB
                   WHERE NRCARDAPIOTRAB = P_NRCARDTRABCOMPLEMENTADO
                     AND NRDIACARDTRAB = C_DIATRAB.NRDIACARDTRABORI
                     AND NRCONFIGCARDTRAB = C_CNFCOMPL.NRCONFIGCARDTRAB;
                  IF V_NRCOMPCARDTRABCOMPL IS NULL THEN
                     -- Não há pratos no dia __PARAM0__ para a coluna __PARAM1__ no cardápio complementado
                     I_L(MSG('TCOPROC_PRATO_N_EXIT_CARDCOMPLEMENTADO', NOME_DIA(C_DIATRAB.NRSEMANA, C_DIATRAB.NRDIASEMANA), C_CNFCOMPL.DESCRICAO));
                  ELSE
                     V_NRCOMPCARDTRAB := TO_NUMBER(RETORNA_NOVO_CODIGO('COMPCARDTRAB', 1));
                     INSERT INTO COMPCARDTRAB
                     (NRCOMPCARDTRAB, NRCARDAPIOTRAB, 
                      NRDIACARDTRAB, NRCONFIGCARDTRAB,
                      CDFILAUXPRAT, CDPRATO, VRPECONSCARDTRAB,
                      NRORG, NRORGINCLUSAO, NRORGULTATU,
                      CDOPERINCLUSAO, CDOPERULTATU,
                      DTINCLUSAO, DTULTATU)
                     SELECT V_NRCOMPCARDTRAB, V_NRCARDAPIOTRAB,
                            C_DIATRAB.NRDIACARDTRAB, V_NRCONFIGCARDTRAB,
                            C.CDFILAUXPRAT, C.CDPRATO, NVL(C.VRPECONSCARDTRAB, 0.00),
                            P_NRORG, P_NRORG, P_NRORG,
                            P_CDOPERADOR, P_CDOPERADOR,
                            SYSDATE, SYSDATE
                       FROM COMPCARDTRAB C
                      WHERE C.NRCOMPCARDTRAB = V_NRCOMPCARDTRABCOMPL;

                     SELECT MAX(C.CDFILAUXPRAT), MAX(C.CDPRATO), MAX(PT.CDPRATO || ' - ' || PT.NMPRATO)
                       INTO V_CDFILAUXPRAT, V_CDPRATO, V_NMPRATO
                       FROM COMPCARDTRAB C
                            INNER JOIN PRATO PT ON PT.CDFILAUXPRAT = C.CDFILAUXPRAT AND
                                                   PT.CDPRATO = C.CDPRATO
                      WHERE NRCOMPCARDTRAB = V_NRCOMPCARDTRAB;

                     SELECT COUNT(1)
                       INTO V_QTDE
                       FROM GRUPOPRATO G INNER JOIN GRUPOPRATOSERV GS ON G.NRGRUPOPRATO = GS.NRGRUPOPRATO
                                          INNER JOIN ITGRUPOPRATOSERV IT ON IT.NRGRUPOPRATOSERV = GS.NRGRUPOPRATOSERV
                       WHERE G.CDFILIAL = V_CDFILIAL AND
                             GS.CDSERVFILI = V_CDSERVFILI AND
                             IT.CDPRATO = V_CDPRATO AND
                             IT.CDFILAUXPRAT = V_CDFILAUXPRAT AND
                             G.IDTIPORESTRICAO = 'CONTRATO';

                     IF V_QTDE = 0 THEN
                        -- O prato __PARAM0__ não está cadastrado a grupo de prato para o serviço __PARAM1__ na unidade __PARAM2__
                        I_L(MSG('TCOPROC_PRATO_N_CAD_GRUPOPRAT', V_NMPRATO, V_NMSERVICO, V_CDFILIAL));
                     ELSIF V_QTDE > 1 THEN
                        -- O prato __PARAM0__ está cadastrado a dois ou mais grupos de prato para o serviço __PARAM1__ na unidade __PARAM2__
                        I_L(MSG('TCOPROC_PRATO_MAISDE1_GRUPOPRAT', V_NMPRATO, V_NMSERVICO, V_CDFILIAL));
                     END IF;

                     SELECT COUNT(1)
                       INTO V_QTDE
                       FROM RECEPRATCARDTRAB
                      WHERE NRCARDAPIOTRAB = V_NRCARDAPIOTRAB
                        AND CDFILAUXPRAT = V_CDFILAUXPRAT
                        AND CDPRATO = V_CDPRATO;
                     IF V_QTDE = 0 THEN
                        SELECT COUNT(1)
                          INTO V_QTDE
                          FROM RECEPRATCARDTRAB
                         WHERE NRCARDAPIOTRAB = P_NRCARDTRABCOMPLEMENTADO
                           AND CDFILAUXPRAT = V_CDFILAUXPRAT
                           AND CDPRATO = V_CDPRATO;

                        V_NRRECEPRATCARDTRAB := TO_NUMBER(RETORNA_NOVO_CODIGO('RECEPRATCARDTRAB', V_QTDE));

                        INSERT INTO RECEPRATCARDTRAB
                        (NRRECEPRATCARDTRAB, NRCARDAPIOTRAB,
                         CDFILAUXPRAT, CDPRATO,
                         CDPRODUTO, QTPRODRECCARDTRAB,
                         VRPEFATCOCCARDTRAB, VRPEFATCORCARDTRAB,
                         SGUNIDADE, QTBRUTACARDTRABUNR,
                         IDPRODBASECARDTRAB, IDQTDEFIXCARDTRAB,
                         NRORG, NRORGINCLUSAO, NRORGULTATU,
                         CDOPERINCLUSAO, CDOPERULTATU,
                         DTINCLUSAO, DTULTATU) 
                        SELECT V_NRRECEPRATCARDTRAB + (ROW_NUMBER() OVER (ORDER BY R.CDPRODUTO) - 1), V_NRCARDAPIOTRAB,
                               R.CDFILAUXPRAT, R.CDPRATO,
                               R.CDPRODUTO, R.QTPRODRECCARDTRAB,
                               R.VRPEFATCOCCARDTRAB, R.VRPEFATCORCARDTRAB,
                               NVL(R.SGUNIDADE, P.SGUNIDADE), R.QTBRUTACARDTRABUNR,
                               NVL(R.IDPRODBASECARDTRAB, 'N'), NVL(R.IDQTDEFIXCARDTRAB, 'N'),
                               P_NRORG, P_NRORG, P_NRORG,
                               P_CDOPERADOR, P_CDOPERADOR,
                               SYSDATE, SYSDATE
                          FROM RECEPRATCARDTRAB R INNER JOIN PRODUTO P ON P.CDPRODUTO = R.CDPRODUTO
                         WHERE R.NRCARDAPIOTRAB = P_NRCARDTRABCOMPLEMENTADO
                           AND R.CDFILAUXPRAT = V_CDFILAUXPRAT
                           AND R.CDPRATO = V_CDPRATO
                         ORDER BY R.CDPRODUTO;
                     END IF;
                  END IF;   
               END LOOP;               
            END LOOP;
         END IF;
      --=========================================================
      --=== 4ª etapa: Descartáveis
      --=========================================================
         --Amostra
         SELECT MAX(NRCONFIGCARDBASEQ), MAX(NRCONFIGCARDBASEF)
           INTO V_NRCONFIGCARDBASEQ, V_NRCONFIGCARDBASEF
           FROM AMOSTRACARDBASE
          WHERE NRCARDAPIOBASE = P_NRCARDAPIOBASE;

         --Descartáveis
         FOR C_DESCART IN
         (
            SELECT V_NRCONFIGCARDBASEQ AS NRCONFIGCARDBASE, 'QUENTE' AS IDFORMACALCULO            
              FROM DUAL             
             WHERE V_NRCONFIGCARDBASEQ IS NOT NULL 

            UNION ALL 

            SELECT V_NRCONFIGCARDBASEF AS NRCONFIGCARDBASE, 'FRIO' AS IDFORMACALCULO
              FROM DUAL
             WHERE V_NRCONFIGCARDBASEF IS NOT NULL

            UNION ALL

            SELECT D.NRCONFIGCARDBASE, D.IDFORMACALCULO
              FROM DESCARTCARDBASE D
                   INNER JOIN LISTA L ON L.NRLISTA = P_CONFIGURACOES AND
                                         D.NRCONFIGCARDBASE = TO_NUMBER(L.CDLISTA)
             WHERE D.NRCARDAPIOBASE = P_NRCARDAPIOBASE
               AND (V_NRCONFIGCARDBASEQ IS NULL OR D.NRCONFIGCARDBASE <> V_NRCONFIGCARDBASEQ)
               AND (V_NRCONFIGCARDBASEF IS NULL OR D.NRCONFIGCARDBASE <> V_NRCONFIGCARDBASEF)
         ) LOOP
            V_QTDE := 0;
            IF C_DESCART.IDFORMACALCULO IN ('QUENTE', 'FRIO') THEN
               SELECT COUNT(1)
                 INTO V_QTDE
                 FROM CONFIGCARDTRAB
                WHERE NRCARDAPIOTRAB = V_NRCARDAPIOTRAB
                  AND IDCLASSIFICACAO = 'ALIMENTAR'
                  AND IDTEMPERATURA = C_DESCART.IDFORMACALCULO;
               V_QTUNIDADES := V_QTDE * NVL(CASE WHEN P_QTTURNOS = 0 THEN 1 ELSE P_QTTURNOS END, 1);
            END IF;

            IF V_QTDE > 0 OR NOT (C_DESCART.IDFORMACALCULO IN ('QUENTE', 'FRIO')) THEN

               V_NRCONFIGCARDTRAB := TO_NUMBER(RETORNA_NOVO_CODIGO('CONFIGCARDTRAB', 1));
               
               SELECT MAX(NRORDEM)
                 INTO V_NRORDEM
                 FROM CONFIGCARDTRAB
                WHERE NRCARDAPIOTRAB = V_NRCARDAPIOTRAB;
               V_NRORDEM := NVL(V_NRORDEM + 1, 1);

               INSERT INTO CONFIGCARDTRAB
               (NRCONFIGCARDTRAB, NRCARDAPIOTRAB,
                CDTIPOPRAT, DSCOMPLEMENTO, IDCLASSIFICACAO, 
                NRORDEM,IDTEMPERATURA, NRCONFIGCARDBASE,
                NRORG, NRORGINCLUSAO, NRORGULTATU,
                CDOPERINCLUSAO, CDOPERULTATU,
                DTINCLUSAO, DTULTATU)
               SELECT V_NRCONFIGCARDTRAB,
                      V_NRCARDAPIOTRAB,
                      C.CDTIPOPRAT, C.DSCOMPLEMENTO, C.IDCLASSIFICACAO, 
                      V_NRORDEM, C.IDTEMPERATURA, C.NRCONFIGCARDBASE,
                      P_NRORG, P_NRORG, P_NRORG,
                      P_CDOPERADOR, P_CDOPERADOR,
                      SYSDATE, SYSDATE
                 FROM CONFIGCARDBASE C                   
                WHERE C.NRCONFIGCARDBASE = C_DESCART.NRCONFIGCARDBASE
                ORDER BY C.NRCONFIGCARDBASE;


               SELECT T.NMTIPOPRAT || ' (' || NVL(C.DSCOMPLEMENTO, ' ') || ')' AS DESCRICAO
                 INTO V_DESCRICAO
                 FROM CONFIGCARDBASE C
                      INNER JOIN TIPOPRAT T ON T.CDTIPOPRAT = C.CDTIPOPRAT
                WHERE C.NRCONFIGCARDBASE = C_DESCART.NRCONFIGCARDBASE;

               FOR C_DIATRAB IN
               (
                  SELECT D.NRDIACARDTRAB, LPAD(TO_CHAR( (D.NRSEMANA - 1) * 7 + D.NRDIASEMANA), 2, '0') AS DIA, DB.NRDIACARDBASE, D.QTCOMENSAIS,
                         D.NRSEMANA, D.NRDIASEMANA
                    FROM DIACARDTRAB D
                         INNER JOIN DIACARDBASE DB ON DB.NRSEMANA = D.NRSEMANA AND
                                                      DB.NRDIASEMANA = D.NRDIASEMANA 
                   WHERE D.NRCARDAPIOTRAB = V_NRCARDAPIOTRAB
                     AND DB.NRCARDAPIOBASE = P_NRCARDAPIOBASE
                     AND D.QTCOMENSAIS > 0
               ) LOOP               
                  /*Se não tiver comensais não insere o prato pois não foi solicitado para o dia*/
                  
                  SELECT MAX(NRCOMPCARDBASE)
                    INTO V_NRCOMPCARDBASE
                    FROM COMPCARDBASE
                   WHERE NRCARDAPIOBASE = P_NRCARDAPIOBASE
                     AND NRDIACARDBASE = C_DIATRAB.NRDIACARDBASE
                     AND NRCONFIGCARDBASE = C_DESCART.NRCONFIGCARDBASE;
                  IF V_NRCOMPCARDBASE IS NULL THEN
                     -- Não há pratos no cardápio base para o dia __PARAM0__ e coluna __PARAM1__
                     I_L(MSG('TCOPROC_CARDBASE_N_POSSUI_PRATOS_DIA', NOME_DIA(C_DIATRAB.NRSEMANA, C_DIATRAB.NRDIASEMANA), V_DESCRICAO));
                  ELSE
                     SELECT COUNT(1), MAX(P.NRPRATCOMPCARDBASE)
                       INTO V_QTDE, V_NRPRATCOMPCARDBASE
                       FROM PRATCOMPCARDBASE P
                            INNER JOIN REGIAOPRATCARDBASE R ON R.NRPRATCOMPCARDBASE = P.NRPRATCOMPCARDBASE
                      WHERE P.NRCOMPCARDBASE = V_NRCOMPCARDBASE
                        AND R.CDREGIAO = P_CDREGIAO;

                     IF V_QTDE = 0 THEN
                        -- Não há pratos no cardápio base que atendam a região __PARAM0__ no dia __PARAM1__ e coluna __PARAM2__
                        I_L(MSG('TCOPROC_CARDBASE_N_POSSUI_PRATOS_DIA_PARA_REGIAO', V_NMREGIAO, NOME_DIA(C_DIATRAB.NRSEMANA, C_DIATRAB.NRDIASEMANA), V_DESCRICAO));
                     ELSIF V_QTDE > 1 THEN
                        -- Há dois ou mais pratos no cardápio base que atendem a região __PARAM0__ no dia __PARAM1__ e coluna __PARAM2__
                        I_L(MSG('TCOPROC_CARDBASE_MAISDE1_PRATO_DIA_PARA_REGIAO', V_NMREGIAO, NOME_DIA(C_DIATRAB.NRSEMANA, C_DIATRAB.NRDIASEMANA), V_DESCRICAO));
                     ELSE
                        SELECT MAX(P.CDFILAUXPRAT), MAX(P.CDPRATO), MAX(PT.CDPRATO || ' - ' || PT.NMPRATO), MAX(PT.IDATIVO)
                          INTO V_CDFILAUXPRAT, V_CDPRATO, V_NMPRATO, V_IDATIVO
                          FROM PRATCOMPCARDBASE P
                               INNER JOIN PRATO PT ON PT.CDFILAUXPRAT = P.CDFILAUXPRAT AND
                                                      PT.CDPRATO = P.CDPRATO
                         WHERE P.NRPRATCOMPCARDBASE = V_NRPRATCOMPCARDBASE;
                        
                        IF V_IDATIVO = 'N' THEN
                           -- O prato __PARAM0__ está inativo
                           I_L(MSG('TCOPROC_PRATO_INATIVO', V_NMPRATO));
                        END IF;

                        V_NRCOMPCARDTRAB := TO_NUMBER(RETORNA_NOVO_CODIGO('COMPCARDTRAB', 1));

                        INSERT INTO COMPCARDTRAB
                        (NRCOMPCARDTRAB, NRCARDAPIOTRAB, 
                         NRDIACARDTRAB, NRCONFIGCARDTRAB,
                         CDFILAUXPRAT, CDPRATO, VRPECONSCARDTRAB,
                         NRORG, NRORGINCLUSAO, NRORGULTATU,
                         CDOPERINCLUSAO, CDOPERULTATU,
                         DTINCLUSAO, DTULTATU)
                        VALUES
                        (V_NRCOMPCARDTRAB, V_NRCARDAPIOTRAB,
                         C_DIATRAB.NRDIACARDTRAB, V_NRCONFIGCARDTRAB,
                         V_CDFILAUXPRAT, V_CDPRATO, 100,
                         P_NRORG, P_NRORG, P_NRORG,
                         P_CDOPERADOR, P_CDOPERADOR,
                         SYSDATE, SYSDATE);

                        SELECT COUNT(1)
                          INTO V_QTDE
                          FROM RECEPRATCARDTRAB
                         WHERE NRCARDAPIOTRAB = V_NRCARDAPIOTRAB
                           AND CDFILAUXPRAT = V_CDFILAUXPRAT
                           AND CDPRATO = V_CDPRATO;

                        IF V_QTDE = 0 THEN
                           V_IDRECEITA := RECE_UTIL_TCO(V_CDFILAUXPRAT,
                                                      V_CDPRATO,
                                                      V_CDFILIAL,
                                                      V_NRSERVICOPROPOSTA,
                                                      V_NRPADRAOQUALIDADE,
                                                      P_CDREGIAO,
                                                      NULL);

                           IF V_IDRECEITA IS NULL THEN
                              -- O prato __PARAM0__ não possui receita cadastrada
                              I_L(MSG('TCOPROC_PRATO_SEM_RECEITA', V_NMPRATO));
                           ELSE                              
                              IF V_IDRECEITA = 'R' THEN
                                 SELECT COUNT(1)
                                   INTO V_QTDE
                                   FROM RECEREGIAO
                                  WHERE CDFILAUXPRAT = V_CDFILAUXPRAT
                                    AND CDPRATO = V_CDPRATO
                                    AND CDREGIAO = P_CDREGIAO
                                    AND NRPADRAOQUALIDADE = V_NRPADRAOQUALIDADE;

                                 V_NRRECEPRATCARDTRAB := TO_NUMBER(RETORNA_NOVO_CODIGO('RECEPRATCARDTRAB', V_QTDE));

                                 INSERT INTO RECEPRATCARDTRAB
                                 (NRRECEPRATCARDTRAB, NRCARDAPIOTRAB, 
                                  CDFILAUXPRAT, CDPRATO,
                                  CDPRODUTO, QTPRODRECCARDTRAB,
                                  VRPEFATCOCCARDTRAB, VRPEFATCORCARDTRAB,
                                  SGUNIDADE, QTBRUTACARDTRABUNR,
                                  IDPRODBASECARDTRAB, IDQTDEFIXCARDTRAB,
                                  NRORG, NRORGINCLUSAO, NRORGULTATU,
                                  CDOPERINCLUSAO, CDOPERULTATU,
                                  DTINCLUSAO, DTULTATU)                                 
                                 SELECT V_NRRECEPRATCARDTRAB + (ROW_NUMBER() OVER (ORDER BY R.NRRECEREGIAO) - 1) AS NRRECEPRATCARDTRAB,
                                        V_NRCARDAPIOTRAB, R.CDFILAUXPRAT, R.CDPRATO,
                                        R.CDPRODUTO, R.QTPRODRECREGIAO,
                                        NVL(R.VRPEFATCOCREGIAO, 0), NVL(R.VRPEFATCORREGIAO, 0),
                                        NVL(R.SGUNIDADE, P.SGUNIDADE), R.QTBRUTAREGIAOUNR,
                                        NVL(R.IDPRODBASEREGIAO, 'N'), NVL(R.IDQTDEFIXREGIAO, 'N'),
                                        P_NRORG, P_NRORG, P_NRORG,
                                        P_CDOPERADOR, P_CDOPERADOR,
                                        SYSDATE, SYSDATE
                                   FROM RECEREGIAO R INNER JOIN PRODUTO P ON P.CDPRODUTO = R.CDPRODUTO
                                  WHERE R.CDFILAUXPRAT = V_CDFILAUXPRAT
                                    AND R.CDPRATO = V_CDPRATO
                                    AND R.CDREGIAO = P_CDREGIAO
                                    AND R.NRPADRAOQUALIDADE = V_NRPADRAOQUALIDADE
                                  ORDER BY R.NRRECEREGIAO;

                              ELSIF V_IDRECEITA = 'Q' THEN
                                 SELECT COUNT(1)
                                   INTO V_QTDE
                                   FROM RECEPADQUALI
                                  WHERE CDFILAUXPRAT = V_CDFILAUXPRAT
                                    AND CDPRATO = V_CDPRATO
                                    AND NRPADRAOQUALIDADE = V_NRPADRAOQUALIDADE;

                                 V_NRRECEPRATCARDTRAB := TO_NUMBER(RETORNA_NOVO_CODIGO('RECEPRATCARDTRAB', V_QTDE));

                                 INSERT INTO RECEPRATCARDTRAB
                                 (NRRECEPRATCARDTRAB, NRCARDAPIOTRAB,
                                  CDFILAUXPRAT, CDPRATO,
                                  CDPRODUTO, QTPRODRECCARDTRAB,
                                  VRPEFATCOCCARDTRAB, VRPEFATCORCARDTRAB,
                                  SGUNIDADE, QTBRUTACARDTRABUNR,
                                  IDPRODBASECARDTRAB, IDQTDEFIXCARDTRAB,
                                  NRORG, NRORGINCLUSAO, NRORGULTATU,
                                  CDOPERINCLUSAO, CDOPERULTATU,
                                  DTINCLUSAO, DTULTATU)                                 
                                 SELECT V_NRRECEPRATCARDTRAB + (ROW_NUMBER() OVER (ORDER BY R.NRRECEPADQUALI) - 1) AS NRRECEPRATCARDTRAB,
                                        V_NRCARDAPIOTRAB, R.CDFILAUXPRAT, R.CDPRATO,
                                        R.CDPRODUTO, R.QTPRODRECPADQ,
                                        NVL(R.VRPEFATCOCPADQ, 0), NVL(R.VRPEFATCORPADQ, 0),
                                        NVL(R.SGUNIDADE, P.SGUNIDADE), R.QTBRUTAPADQUNR,
                                        NVL(R.IDPRODBASEPADQ, 'N'), NVL(R.IDQTDEFIXPADQ, 'N'),
                                        P_NRORG, P_NRORG, P_NRORG,
                                        P_CDOPERADOR, P_CDOPERADOR,
                                        SYSDATE, SYSDATE
                                   FROM RECEPADQUALI R INNER JOIN PRODUTO P ON P.CDPRODUTO = R.CDPRODUTO
                                  WHERE R.CDFILAUXPRAT = V_CDFILAUXPRAT
                                    AND R.CDPRATO = V_CDPRATO
                                    AND R.NRPADRAOQUALIDADE = V_NRPADRAOQUALIDADE
                                  ORDER BY R.NRRECEPADQUALI;

                              ELSIF V_IDRECEITA = 'S' THEN                           

                                 SELECT COUNT(1)
                                   INTO V_QTDE
                                   FROM RECESERV
                                  WHERE CDFILAUXPRAT = V_CDFILAUXPRAT
                                    AND CDPRATO = V_CDPRATO
                                    AND CDFILIAL = V_CDFILIAL
                                    AND CDSERVFILI = V_CDSERVFILI;

                                 SELECT MAX(IDATIVO)
                                   INTO V_IDATIVO
                                   FROM PRATSERV
                                  WHERE CDFILAUXPRAT = V_CDFILAUXPRAT
                                    AND CDPRATO = V_CDPRATO
                                    AND CDFILIAL = V_CDFILIAL
                                    AND CDSERVFILI = V_CDSERVFILI;

                                 IF V_IDATIVO = 'N' THEN
                                    -- Receita por servico do prato __PARAM0__ está inativa para unidade __PARAM1__ e servico __PARAM2__
                                    I_L(MSG('TCOPROC_RECESERV_INATIVA', V_NMPRATO, V_CDFILIAL, V_NMSERVICO));
                                 END IF;

                                 V_NRRECEPRATCARDTRAB := TO_NUMBER(RETORNA_NOVO_CODIGO('RECEPRATCARDTRAB', V_QTDE));

                                 INSERT INTO RECEPRATCARDTRAB
                                 (NRRECEPRATCARDTRAB, NRCARDAPIOTRAB, 
                                  CDFILAUXPRAT, CDPRATO,
                                  CDPRODUTO, QTPRODRECCARDTRAB,
                                  VRPEFATCOCCARDTRAB, VRPEFATCORCARDTRAB,
                                  SGUNIDADE, QTBRUTACARDTRABUNR,
                                  IDPRODBASECARDTRAB, IDQTDEFIXCARDTRAB,
                                  NRORG, NRORGINCLUSAO, NRORGULTATU,
                                  CDOPERINCLUSAO, CDOPERULTATU,
                                  DTINCLUSAO, DTULTATU)                                 
                                 SELECT V_NRRECEPRATCARDTRAB + (ROW_NUMBER() OVER (ORDER BY R.CDPRODUTO) - 1) AS NRRECEPRATCARDTRAB,
                                        V_NRCARDAPIOTRAB, R.CDFILAUXPRAT, R.CDPRATO,
                                        R.CDPRODUTO, R.QTPRODRECSER,
                                        NVL(R.VRPEFATCOCSE, 0), NVL(R.VRPEFATCORSE, 0),
                                        NVL(R.SGUNIDADE, P.SGUNIDADE), R.QTBRUTASEUNR,
                                        NVL(R.IDPRODBASESE, 'N'), NVL(R.IDQTDEFIXSE, 'N'),
                                        P_NRORG, P_NRORG, P_NRORG,
                                        P_CDOPERADOR, P_CDOPERADOR,
                                        SYSDATE, SYSDATE
                                   FROM RECESERV R INNER JOIN PRODUTO P ON P.CDPRODUTO = R.CDPRODUTO
                                  WHERE R.CDFILAUXPRAT = V_CDFILAUXPRAT
                                    AND R.CDPRATO = V_CDPRATO
                                    AND R.CDFILIAL = V_CDFILIAL
                                    AND R.CDSERVFILI = V_CDSERVFILI
                                  ORDER BY R.CDPRODUTO;

                                 ELSIF V_IDRECEITA = 'F' THEN
                                    SELECT COUNT(1)
                                      INTO V_QTDE
                                      FROM RECEFILI
                                     WHERE CDFILAUXPRAT = V_CDFILAUXPRAT
                                       AND CDPRATO = V_CDPRATO
                                       AND CDFILIAL = V_CDFILIAL;

                                    SELECT MAX(IDATIVO)
                                      INTO V_IDATIVO
                                      FROM PRATFILI
                                     WHERE CDFILAUXPRAT = V_CDFILAUXPRAT
                                       AND CDPRATO = V_CDPRATO
                                       AND CDFILIAL = V_CDFILIAL;

                                    IF V_IDATIVO = 'N' THEN
                                       -- Receita por unidade do prato __PARAM0__ está inativa para unidade __PARAM1__
                                       I_L(MSG('TCOPROC_RECEFILI_INATIVA', V_NMPRATO, V_CDFILIAL));
                                    END IF;

                                    V_NRRECEPRATCARDTRAB := TO_NUMBER(RETORNA_NOVO_CODIGO('RECEPRATCARDTRAB', V_QTDE));

                                    INSERT INTO RECEPRATCARDTRAB
                                    (NRRECEPRATCARDTRAB, NRCARDAPIOTRAB, 
                                     CDFILAUXPRAT, CDPRATO,
                                     CDPRODUTO, QTPRODRECCARDTRAB,
                                     VRPEFATCOCCARDTRAB, VRPEFATCORCARDTRAB,
                                     SGUNIDADE, QTBRUTACARDTRABUNR,
                                     IDPRODBASECARDTRAB, IDQTDEFIXCARDTRAB,
                                     NRORG, NRORGINCLUSAO, NRORGULTATU,
                                     CDOPERINCLUSAO, CDOPERULTATU,
                                     DTINCLUSAO, DTULTATU)                                 
                                    SELECT V_NRRECEPRATCARDTRAB + (ROW_NUMBER() OVER (ORDER BY R.CDPRODUTO) - 1) AS NRRECEPRATCARDTRAB,
                                           V_NRCARDAPIOTRAB, R.CDFILAUXPRAT, R.CDPRATO,
                                           R.CDPRODUTO, R.QTPRODRECLOC,
                                           NVL(R.VRPEFATCOCLO, 0), NVL(R.VRPEFATCORLO, 0),
                                           NVL(R.SGUNIDADE, P.SGUNIDADE), R.QTBRUTALOUNR,
                                           NVL(R.IDPRODBASELO, 'N'), NVL(R.IDQTDEFIXLO, 'N'),
                                           P_NRORG, P_NRORG, P_NRORG,
                                           P_CDOPERADOR, P_CDOPERADOR,
                                           SYSDATE, SYSDATE
                                      FROM RECEFILI R INNER JOIN PRODUTO P ON P.CDPRODUTO = R.CDPRODUTO
                                     WHERE R.CDFILAUXPRAT = V_CDFILAUXPRAT
                                       AND R.CDPRATO = V_CDPRATO
                                       AND R.CDFILIAL = V_CDFILIAL
                                     ORDER BY R.CDPRODUTO;
                                     
                              ELSIF V_IDRECEITA = 'P' THEN                           
                                 SELECT COUNT(1)
                                   INTO V_QTDE
                                   FROM RECEPADR
                                  WHERE CDFILAUXPRAT = V_CDFILAUXPRAT
                                    AND CDPRATO = V_CDPRATO;

                                 SELECT MAX(IDATIVO)
                                   INTO V_IDATIVO
                                   FROM PRATPADR
                                  WHERE CDFILAUXPRAT = V_CDFILAUXPRAT
                                    AND CDPRATO = V_CDPRATO;

                                 IF V_IDATIVO = 'N' THEN
                                    -- Receita padrão do prato __PARAM0__ está inativa
                                    I_L(MSG('TCOPROC_RECEPADR_INATIVA', V_NMPRATO));
                                 END IF;

                                 V_NRRECEPRATCARDTRAB := TO_NUMBER(RETORNA_NOVO_CODIGO('RECEPRATCARDTRAB', V_QTDE));

                                 INSERT INTO RECEPRATCARDTRAB
                                 (NRRECEPRATCARDTRAB, NRCARDAPIOTRAB, 
                                  CDFILAUXPRAT, CDPRATO,
                                  CDPRODUTO, QTPRODRECCARDTRAB,
                                  VRPEFATCOCCARDTRAB, VRPEFATCORCARDTRAB,
                                  SGUNIDADE, QTBRUTACARDTRABUNR,
                                  IDPRODBASECARDTRAB, IDQTDEFIXCARDTRAB,
                                  NRORG, NRORGINCLUSAO, NRORGULTATU,
                                  CDOPERINCLUSAO, CDOPERULTATU,
                                  DTINCLUSAO, DTULTATU)                                 
                                 SELECT V_NRRECEPRATCARDTRAB + (ROW_NUMBER() OVER (ORDER BY R.CDPRODUTO) - 1) AS NRRECEPRATCARDTRAB,
                                        V_NRCARDAPIOTRAB, R.CDFILAUXPRAT, R.CDPRATO,
                                        R.CDPRODUTO, R.QTPRODPRAT,
                                        NVL(R.VRPEFATCOCPR, 0), NVL(R.VRPEFATCORPR, 0),
                                        NVL(R.SGUNIDADE, P.SGUNIDADE), R.QTBRUTAPRUNR,
                                        NVL(R.IDPRODBASEPR, 'N'), NVL(R.IDQTDEFIXPR, 'N'),
                                        P_NRORG, P_NRORG, P_NRORG,
                                        P_CDOPERADOR, P_CDOPERADOR,
                                        SYSDATE, SYSDATE
                                   FROM RECEPADR R INNER JOIN PRODUTO P ON P.CDPRODUTO = R.CDPRODUTO
                                  WHERE R.CDFILAUXPRAT = V_CDFILAUXPRAT
                                    AND R.CDPRATO = V_CDPRATO
                                 ORDER BY R.CDPRODUTO;
                              END IF;
                           END IF;

                        END IF;

                        IF C_DESCART.IDFORMACALCULO IN ('QUENTE', 'FRIO') THEN
                           V_COMENSAIS := V_QTUNIDADES/C_DIATRAB.QTCOMENSAIS;
                        ELSIF C_DESCART.IDFORMACALCULO = 'PERCAPITA' THEN
                           V_COMENSAIS := 1;
                        ELSE
                           V_COMENSAIS := 1/C_DIATRAB.QTCOMENSAIS;
                        END IF;
                        V_COMENSAIS := V_COMENSAIS * 100;
                        
                        UPDATE COMPCARDTRAB
                           SET VRPECONSCARDTRAB = NVL(V_COMENSAIS, 0),
                               NRORGULTATU = P_NRORG,
                               CDOPERULTATU = P_CDOPERADOR,
                               DTULTATU = SYSDATE
                         WHERE NRCOMPCARDTRAB = V_NRCOMPCARDTRAB;

                     END IF;
                  END IF;               
               END LOOP;
            END IF;
         END LOOP;
      --=========================================================
      --=== 5ª etapa: Limpeza
      --=========================================================
          SELECT MAX(L.NRCONFIGCARDBASE), MAX(C.CDTIPOPRAT), MAX(C.DSCOMPLEMENTO), MAX(T.NMTIPOPRAT || ' (' || NVL(C.DSCOMPLEMENTO, ' ') || ')')
            INTO V_NRCONFIGCARDBASE, V_CDTIPOPRATLIMPEZA, V_DSCOMPLEMENTO, V_DESCRICAO
            FROM LIMPEZACARDBASE L
                 INNER JOIN CONFIGCARDBASE C ON C.NRCONFIGCARDBASE = L.NRCONFIGCARDBASE
                 INNER JOIN TIPOPRAT T ON T.CDTIPOPRAT = C.CDTIPOPRAT
           WHERE L.NRCARDAPIOBASE = P_NRCARDAPIOBASE
             AND NVL(P_QTSEGSEX, NVL(P_QTSABADO, P_QTDOMFERI)) BETWEEN QTINICIAL AND QTFINAL;
         IF V_NRCONFIGCARDBASE IS NOT NULL THEN            
            V_NRCONFIGCARDTRAB := TO_NUMBER(RETORNA_NOVO_CODIGO('CONFIGCARDTRAB', 1));

            SELECT MAX(NRORDEM)
              INTO V_NRORDEM
              FROM CONFIGCARDTRAB
             WHERE NRCARDAPIOTRAB = V_NRCARDAPIOTRAB;
            V_NRORDEM := NVL(V_NRORDEM + 1, 1);

            INSERT INTO CONFIGCARDTRAB
            (NRCONFIGCARDTRAB, NRCARDAPIOTRAB,
             CDTIPOPRAT, DSCOMPLEMENTO, IDCLASSIFICACAO, 
             NRORDEM,IDTEMPERATURA, NRCONFIGCARDBASE,
             NRORG, NRORGINCLUSAO, NRORGULTATU,
             CDOPERINCLUSAO, CDOPERULTATU,
             DTINCLUSAO, DTULTATU)
            VALUES
            (V_NRCONFIGCARDTRAB, V_NRCARDAPIOTRAB,
             V_CDTIPOPRATLIMPEZA, V_DSCOMPLEMENTO, 'LIMPEZA',
             V_NRORDEM, NULL, V_NRCONFIGCARDBASE,
             P_NRORG, P_NRORG, P_NRORG,
             P_CDOPERADOR, P_CDOPERADOR,
             SYSDATE, SYSDATE);

            FOR C_DIATRAB IN
            (
               SELECT D.NRDIACARDTRAB, LPAD(TO_CHAR( (D.NRSEMANA - 1) * 7 + D.NRDIASEMANA), 2, '0') AS DIA, DB.NRDIACARDBASE, D.QTCOMENSAIS,
                      D.NRSEMANA, D.NRDIASEMANA
                 FROM DIACARDTRAB D
                      INNER JOIN DIACARDBASE DB ON DB.NRSEMANA = D.NRSEMANA AND
                                                   DB.NRDIASEMANA = D.NRDIASEMANA 
                WHERE D.NRCARDAPIOTRAB = V_NRCARDAPIOTRAB
                  AND DB.NRCARDAPIOBASE = P_NRCARDAPIOBASE
                  AND D.QTCOMENSAIS > 0
            ) LOOP
               /*Se não tiver comensais não insere o prato pois não foi solicitado para o dia*/
            
               SELECT MAX(NRCOMPCARDBASE)
                 INTO V_NRCOMPCARDBASE
                 FROM COMPCARDBASE
                WHERE NRCARDAPIOBASE = P_NRCARDAPIOBASE
                  AND NRDIACARDBASE = C_DIATRAB.NRDIACARDBASE
                  AND NRCONFIGCARDBASE = V_NRCONFIGCARDBASE;
               IF V_NRCOMPCARDBASE IS NULL THEN
                  -- Não há pratos no cardápio base para o dia __PARAM0__ e coluna __PARAM1__
                  I_L(MSG('TCOPROC_CARDBASE_N_POSSUI_PRATOS_DIA', NOME_DIA(C_DIATRAB.NRSEMANA, C_DIATRAB.NRDIASEMANA), V_DESCRICAO));
               ELSE
                  SELECT COUNT(1), MAX(P.NRPRATCOMPCARDBASE)
                    INTO V_QTDE, V_NRPRATCOMPCARDBASE
                    FROM PRATCOMPCARDBASE P
                         INNER JOIN REGIAOPRATCARDBASE R ON R.NRPRATCOMPCARDBASE = P.NRPRATCOMPCARDBASE
                   WHERE P.NRCOMPCARDBASE = V_NRCOMPCARDBASE
                     AND R.CDREGIAO = P_CDREGIAO;

                  IF V_QTDE = 0 THEN
                     -- Não há pratos no cardápio base que atendam a região __PARAM0__ no dia __PARAM1__ e coluna __PARAM2__
                     I_L(MSG('TCOPROC_CARDBASE_N_POSSUI_PRATOS_DIA_PARA_REGIAO', V_NMREGIAO, NOME_DIA(C_DIATRAB.NRSEMANA, C_DIATRAB.NRDIASEMANA), V_DESCRICAO));
                  ELSIF V_QTDE > 1 THEN
                     -- Há dois ou mais pratos no cardápio base que atendem a região __PARAM0__ no dia __PARAM1__ e coluna __PARAM2__
                     I_L(MSG('TCOPROC_CARDBASE_MAISDE1_PRATO_DIA_PARA_REGIAO', V_NMREGIAO, NOME_DIA(C_DIATRAB.NRSEMANA, C_DIATRAB.NRDIASEMANA), V_DESCRICAO));
                  ELSE
                     SELECT MAX(P.CDFILAUXPRAT), MAX(P.CDPRATO), MAX(PT.CDPRATO || ' - ' || PT.NMPRATO), MAX(PT.IDATIVO)
                       INTO V_CDFILAUXPRAT, V_CDPRATO, V_NMPRATO, V_IDATIVO
                       FROM PRATCOMPCARDBASE P
                            INNER JOIN PRATO PT ON PT.CDFILAUXPRAT = P.CDFILAUXPRAT AND
                                                   PT.CDPRATO = P.CDPRATO
                      WHERE P.NRPRATCOMPCARDBASE = V_NRPRATCOMPCARDBASE;
                     
                     IF V_IDATIVO = 'N' THEN
                        -- O prato __PARAM0__ está inativo
                        I_L(MSG('TCOPROC_PRATO_INATIVO', V_NMPRATO));
                     END IF;

                     V_NRCOMPCARDTRAB := TO_NUMBER(RETORNA_NOVO_CODIGO('COMPCARDTRAB', 1));

                     V_COMENSAIS := 1/C_DIATRAB.QTCOMENSAIS * 100;

                     INSERT INTO COMPCARDTRAB
                     (NRCOMPCARDTRAB, NRCARDAPIOTRAB, 
                      NRDIACARDTRAB, NRCONFIGCARDTRAB,
                      CDFILAUXPRAT, CDPRATO, VRPECONSCARDTRAB,
                      NRORG, NRORGINCLUSAO, NRORGULTATU,
                      CDOPERINCLUSAO, CDOPERULTATU,
                      DTINCLUSAO, DTULTATU)
                     VALUES
                     (V_NRCOMPCARDTRAB, V_NRCARDAPIOTRAB,
                      C_DIATRAB.NRDIACARDTRAB, V_NRCONFIGCARDTRAB,
                      V_CDFILAUXPRAT, V_CDPRATO, NVL(V_COMENSAIS, 0),
                      P_NRORG, P_NRORG, P_NRORG,
                      P_CDOPERADOR, P_CDOPERADOR,
                      SYSDATE, SYSDATE);

                     SELECT COUNT(1)
                       INTO V_QTDE
                       FROM RECEPRATCARDTRAB
                      WHERE NRCARDAPIOTRAB = V_NRCARDAPIOTRAB
                        AND CDFILAUXPRAT = V_CDFILAUXPRAT
                        AND CDPRATO = V_CDPRATO;

                     IF V_QTDE = 0 THEN
                        V_IDRECEITA := RECE_UTIL_TCO(V_CDFILAUXPRAT,
                                                      V_CDPRATO,
                                                      V_CDFILIAL,
                                                      V_NRSERVICOPROPOSTA,
                                                      V_NRPADRAOQUALIDADE,
                                                      P_CDREGIAO,
                                                      NULL);

                        IF V_IDRECEITA IS NULL THEN
                           -- O prato __PARAM0__ não possui receita cadastrada
                           I_L(MSG('TCOPROC_PRATO_SEM_RECEITA', V_NMPRATO));
                        ELSE                              
                           IF V_IDRECEITA = 'R' THEN
                              SELECT COUNT(1)
                                INTO V_QTDE
                                FROM RECEREGIAO
                               WHERE CDFILAUXPRAT = V_CDFILAUXPRAT
                                 AND CDPRATO = V_CDPRATO
                                 AND CDREGIAO = P_CDREGIAO
                                 AND NRPADRAOQUALIDADE = V_NRPADRAOQUALIDADE;

                              V_NRRECEPRATCARDTRAB := TO_NUMBER(RETORNA_NOVO_CODIGO('RECEPRATCARDTRAB', V_QTDE));

                              INSERT INTO RECEPRATCARDTRAB
                              (NRRECEPRATCARDTRAB, NRCARDAPIOTRAB, 
                               CDFILAUXPRAT, CDPRATO,
                               CDPRODUTO, QTPRODRECCARDTRAB,
                               VRPEFATCOCCARDTRAB, VRPEFATCORCARDTRAB,
                               SGUNIDADE, QTBRUTACARDTRABUNR,
                               IDPRODBASECARDTRAB, IDQTDEFIXCARDTRAB,
                               NRORG, NRORGINCLUSAO, NRORGULTATU,
                               CDOPERINCLUSAO, CDOPERULTATU,
                               DTINCLUSAO, DTULTATU)                                 
                              SELECT V_NRRECEPRATCARDTRAB + (ROW_NUMBER() OVER (ORDER BY R.NRRECEREGIAO) - 1) AS NRRECEPRATCARDTRAB,
                                     V_NRCARDAPIOTRAB, R.CDFILAUXPRAT, R.CDPRATO,
                                     R.CDPRODUTO, R.QTPRODRECREGIAO,
                                     NVL(R.VRPEFATCOCREGIAO, 0), NVL(R.VRPEFATCORREGIAO, 0),
                                     NVL(R.SGUNIDADE, P.SGUNIDADE), R.QTBRUTAREGIAOUNR,
                                     NVL(R.IDPRODBASEREGIAO, 'N'), NVL(R.IDQTDEFIXREGIAO, 'N'),
                                     P_NRORG, P_NRORG, P_NRORG,
                                     P_CDOPERADOR, P_CDOPERADOR,
                                     SYSDATE, SYSDATE
                                FROM RECEREGIAO R INNER JOIN PRODUTO P ON P.CDPRODUTO = R.CDPRODUTO
                               WHERE R.CDFILAUXPRAT = V_CDFILAUXPRAT
                                 AND R.CDPRATO = V_CDPRATO
                                 AND R.CDREGIAO = P_CDREGIAO
                                 AND R.NRPADRAOQUALIDADE = V_NRPADRAOQUALIDADE
                               ORDER BY R.NRRECEREGIAO;

                           ELSIF V_IDRECEITA = 'Q' THEN
                              SELECT COUNT(1)
                                INTO V_QTDE
                                FROM RECEPADQUALI
                               WHERE CDFILAUXPRAT = V_CDFILAUXPRAT
                                 AND CDPRATO = V_CDPRATO
                                 AND NRPADRAOQUALIDADE = V_NRPADRAOQUALIDADE;

                              V_NRRECEPRATCARDTRAB := TO_NUMBER(RETORNA_NOVO_CODIGO('RECEPRATCARDTRAB', V_QTDE));

                              INSERT INTO RECEPRATCARDTRAB
                              (NRRECEPRATCARDTRAB, NRCARDAPIOTRAB, 
                               CDFILAUXPRAT, CDPRATO,
                               CDPRODUTO, QTPRODRECCARDTRAB,
                               VRPEFATCOCCARDTRAB, VRPEFATCORCARDTRAB,
                               SGUNIDADE, QTBRUTACARDTRABUNR,
                               IDPRODBASECARDTRAB, IDQTDEFIXCARDTRAB,
                               NRORG, NRORGINCLUSAO, NRORGULTATU,
                               CDOPERINCLUSAO, CDOPERULTATU,
                               DTINCLUSAO, DTULTATU)                                 
                              SELECT V_NRRECEPRATCARDTRAB + (ROW_NUMBER() OVER (ORDER BY R.NRRECEPADQUALI) - 1) AS NRRECEPRATCARDTRAB,
                                     V_NRCARDAPIOTRAB, R.CDFILAUXPRAT, R.CDPRATO,
                                     R.CDPRODUTO, R.QTPRODRECPADQ,
                                     NVL(R.VRPEFATCOCPADQ, 0), NVL(R.VRPEFATCORPADQ, 0),
                                     NVL(R.SGUNIDADE, P.SGUNIDADE), R.QTBRUTAPADQUNR,
                                     NVL(R.IDPRODBASEPADQ, 'N'), NVL(R.IDQTDEFIXPADQ, 'N'),
                                     P_NRORG, P_NRORG, P_NRORG,
                                     P_CDOPERADOR, P_CDOPERADOR,
                                     SYSDATE, SYSDATE
                                FROM RECEPADQUALI R INNER JOIN PRODUTO P ON P.CDPRODUTO = R.CDPRODUTO
                               WHERE R.CDFILAUXPRAT = V_CDFILAUXPRAT
                                 AND R.CDPRATO = V_CDPRATO
                                 AND R.NRPADRAOQUALIDADE = V_NRPADRAOQUALIDADE
                               ORDER BY R.NRRECEPADQUALI;

                           ELSIF V_IDRECEITA = 'S' THEN                           

                              SELECT COUNT(1)
                                INTO V_QTDE
                                FROM RECESERV
                               WHERE CDFILAUXPRAT = V_CDFILAUXPRAT
                                 AND CDPRATO = V_CDPRATO
                                 AND CDFILIAL = V_CDFILIAL
                                 AND CDSERVFILI = V_CDSERVFILI;

                              SELECT MAX(IDATIVO)
                                INTO V_IDATIVO
                                FROM PRATSERV
                               WHERE CDFILAUXPRAT = V_CDFILAUXPRAT
                                 AND CDPRATO = V_CDPRATO
                                 AND CDFILIAL = V_CDFILIAL
                                 AND CDSERVFILI = V_CDSERVFILI;

                              IF V_IDATIVO = 'N' THEN
                                 -- Receita por servico do prato __PARAM0__ está inativa para unidade __PARAM1__ e servico __PARAM2__
                                 I_L(MSG('TCOPROC_RECESERV_INATIVA', V_NMPRATO, V_CDFILIAL, V_NMSERVICO));
                              END IF;

                              V_NRRECEPRATCARDTRAB := TO_NUMBER(RETORNA_NOVO_CODIGO('RECEPRATCARDTRAB', V_QTDE));

                              INSERT INTO RECEPRATCARDTRAB
                              (NRRECEPRATCARDTRAB, NRCARDAPIOTRAB, 
                               CDFILAUXPRAT, CDPRATO,
                               CDPRODUTO, QTPRODRECCARDTRAB,
                               VRPEFATCOCCARDTRAB, VRPEFATCORCARDTRAB,
                               SGUNIDADE, QTBRUTACARDTRABUNR,
                               IDPRODBASECARDTRAB, IDQTDEFIXCARDTRAB,
                               NRORG, NRORGINCLUSAO, NRORGULTATU,
                               CDOPERINCLUSAO, CDOPERULTATU,
                               DTINCLUSAO, DTULTATU)                                 
                              SELECT V_NRRECEPRATCARDTRAB + (ROW_NUMBER() OVER (ORDER BY R.CDPRODUTO) - 1) AS NRRECEPRATCARDTRAB,
                                     V_NRCARDAPIOTRAB, R.CDFILAUXPRAT, R.CDPRATO,
                                     R.CDPRODUTO, R.QTPRODRECSER,
                                     NVL(R.VRPEFATCOCSE, 0), NVL(R.VRPEFATCORSE, 0),
                                     NVL(R.SGUNIDADE, P.SGUNIDADE), R.QTBRUTASEUNR,
                                     NVL(R.IDPRODBASESE, 'N'), NVL(R.IDQTDEFIXSE, 'N'),
                                     P_NRORG, P_NRORG, P_NRORG,
                                     P_CDOPERADOR, P_CDOPERADOR,
                                     SYSDATE, SYSDATE
                                FROM RECESERV R INNER JOIN PRODUTO P ON P.CDPRODUTO = R.CDPRODUTO
                               WHERE R.CDFILAUXPRAT = V_CDFILAUXPRAT
                                 AND R.CDPRATO = V_CDPRATO
                                 AND R.CDFILIAL = V_CDFILIAL
                                 AND R.CDSERVFILI = V_CDSERVFILI
                               ORDER BY R.CDPRODUTO;

                           ELSIF V_IDRECEITA = 'F' THEN
                              SELECT COUNT(1)
                                INTO V_QTDE
                                FROM RECEFILI
                               WHERE CDFILAUXPRAT = V_CDFILAUXPRAT
                                 AND CDPRATO = V_CDPRATO
                                 AND CDFILIAL = V_CDFILIAL;

                              SELECT MAX(IDATIVO)
                                INTO V_IDATIVO
                                FROM PRATFILI
                               WHERE CDFILAUXPRAT = V_CDFILAUXPRAT
                                 AND CDPRATO = V_CDPRATO
                                 AND CDFILIAL = V_CDFILIAL;

                              IF V_IDATIVO = 'N' THEN
                                 -- Receita por unidade do prato __PARAM0__ está inativa para unidade __PARAM1__
                                 I_L(MSG('TCOPROC_RECEFILI_INATIVA', V_NMPRATO, V_CDFILIAL));
                              END IF;

                              V_NRRECEPRATCARDTRAB := TO_NUMBER(RETORNA_NOVO_CODIGO('RECEPRATCARDTRAB', V_QTDE));

                              INSERT INTO RECEPRATCARDTRAB
                              (NRRECEPRATCARDTRAB, NRCARDAPIOTRAB,
                               CDFILAUXPRAT, CDPRATO,
                               CDPRODUTO, QTPRODRECCARDTRAB,
                               VRPEFATCOCCARDTRAB, VRPEFATCORCARDTRAB,
                               SGUNIDADE, QTBRUTACARDTRABUNR,
                               IDPRODBASECARDTRAB, IDQTDEFIXCARDTRAB,
                               NRORG, NRORGINCLUSAO, NRORGULTATU,
                               CDOPERINCLUSAO, CDOPERULTATU,
                               DTINCLUSAO, DTULTATU)                                 
                              SELECT V_NRRECEPRATCARDTRAB + (ROW_NUMBER() OVER (ORDER BY R.CDPRODUTO) - 1) AS NRRECEPRATCARDTRAB,
                                     V_NRCARDAPIOTRAB, R.CDFILAUXPRAT, R.CDPRATO,
                                     R.CDPRODUTO, R.QTPRODRECLOC,
                                     NVL(R.VRPEFATCOCLO, 0), NVL(R.VRPEFATCORLO, 0),
                                     NVL(R.SGUNIDADE, P.SGUNIDADE), R.QTBRUTALOUNR,
                                     NVL(R.IDPRODBASELO, 'N'), NVL(R.IDQTDEFIXLO, 'N'),
                                     P_NRORG, P_NRORG, P_NRORG,
                                     P_CDOPERADOR, P_CDOPERADOR,
                                     SYSDATE, SYSDATE
                                FROM RECEFILI R INNER JOIN PRODUTO P ON P.CDPRODUTO = R.CDPRODUTO
                               WHERE R.CDFILAUXPRAT = V_CDFILAUXPRAT
                                 AND R.CDPRATO = V_CDPRATO
                                 AND R.CDFILIAL = V_CDFILIAL
                               ORDER BY R.CDPRODUTO;
                           ELSIF V_IDRECEITA = 'P' THEN                           
                              SELECT COUNT(1)
                                INTO V_QTDE
                                FROM RECEPADR
                               WHERE CDFILAUXPRAT = V_CDFILAUXPRAT
                                 AND CDPRATO = V_CDPRATO;

                              SELECT MAX(IDATIVO)
                                INTO V_IDATIVO
                                FROM PRATPADR
                               WHERE CDFILAUXPRAT = V_CDFILAUXPRAT
                                 AND CDPRATO = V_CDPRATO;

                              IF V_IDATIVO = 'N' THEN
                                 -- Receita padrão do prato __PARAM0__ está inativa
                                 I_L(MSG('TCOPROC_RECEPADR_INATIVA', V_NMPRATO));
                              END IF;

                              V_NRRECEPRATCARDTRAB := TO_NUMBER(RETORNA_NOVO_CODIGO('RECEPRATCARDTRAB', V_QTDE));

                              INSERT INTO RECEPRATCARDTRAB
                              (NRRECEPRATCARDTRAB, NRCARDAPIOTRAB,
                               CDFILAUXPRAT, CDPRATO,
                               CDPRODUTO, QTPRODRECCARDTRAB,
                               VRPEFATCOCCARDTRAB, VRPEFATCORCARDTRAB,
                               SGUNIDADE, QTBRUTACARDTRABUNR,
                               IDPRODBASECARDTRAB, IDQTDEFIXCARDTRAB,
                               NRORG, NRORGINCLUSAO, NRORGULTATU,
                               CDOPERINCLUSAO, CDOPERULTATU,
                               DTINCLUSAO, DTULTATU)                                 
                              SELECT V_NRRECEPRATCARDTRAB + (ROW_NUMBER() OVER (ORDER BY R.CDPRODUTO) - 1) AS NRRECEPRATCARDTRAB,
                                     V_NRCARDAPIOTRAB, R.CDFILAUXPRAT, R.CDPRATO,
                                     R.CDPRODUTO, R.QTPRODPRAT,
                                     NVL(R.VRPEFATCOCPR, 0), NVL(R.VRPEFATCORPR, 0),
                                     NVL(R.SGUNIDADE, P.SGUNIDADE), R.QTBRUTAPRUNR,
                                     NVL(R.IDPRODBASEPR, 'N'), NVL(R.IDQTDEFIXPR, 'N'),
                                     P_NRORG, P_NRORG, P_NRORG,
                                     P_CDOPERADOR, P_CDOPERADOR,
                                     SYSDATE, SYSDATE
                                FROM RECEPADR R INNER JOIN PRODUTO P ON P.CDPRODUTO = R.CDPRODUTO
                               WHERE R.CDFILAUXPRAT = V_CDFILAUXPRAT
                                 AND R.CDPRATO = V_CDPRATO
                              ORDER BY R.CDPRODUTO;
                           END IF;
                        END IF;
                     END IF;
                  END IF;
               END IF;                 
            END LOOP;            
         END IF;
      --=========================================================
      --=== Custo dos produtos
      --=========================================================
         -- Busca a central de compras
         SELECT MAX(NVL(FILIAL.CDFILCENTCMP, FILIAL.CDFILIAL))
           INTO V_CDFILCENTCMP
           FROM FILIAL
          WHERE CDFILIAL = V_CDFILIAL;
         -- Busca informações da PARASUPRI
         SELECT MAX(IDTIPOAPUR)
           INTO V_IDTIPOAPUR
           FROM PARASUPRI
          WHERE CDFILIAL = V_CDFILCENTCMP;

         V_CDPRODESTO := NULL;             

         -- Procura a lista de preços calculada para a data.
         SELECT MAX(NRLISTAPRECOTCO)
           INTO V_NRLISTAPRECOTCO
           FROM LISTAPRECOTCO
          WHERE DTREFERENCIA = P_DTCUSTO
            AND CDREGIAO = P_CDREGIAO;

         -- Caso não encontre uma lista já salva, gera uma nova lista de preços do TCO
         IF V_NRLISTAPRECOTCO IS NULL THEN
            GRAVA_LISTAPRECOTCO(P_DTCUSTO, P_CDREGIAO, P_NRORG, P_CDOPERADOR, V_NRLISTAPRECOTCO);              
         END IF;

         -- Se foi salva nova lista de preços
         IF V_NRLISTAPRECOTCO IS NOT NULL THEN
            -- Indica lista de preços tco utilizada no cardápio de trabalho
            UPDATE CARDAPIOTRAB
               SET NRLISTAPRECOTCO = V_NRLISTAPRECOTCO
             WHERE NRCARDAPIOTRAB = V_NRCARDAPIOTRAB;

            FOR C_CUSTOS IN 
            (SELECT NRPRODLISTAPRECOTCO, CDPRODESTO, VRCUSTO, CDMARCA
               FROM PRODLISTAPRECOTCO
              WHERE NRLISTAPRECOTCO = V_NRLISTAPRECOTCO
                AND IDESCOLHIDO = 'S') LOOP

               V_NRPRODUTOCARDTRAB := TO_NUMBER(RETORNA_NOVO_CODIGO('PRODUTOCARDTRAB', 1));

               INSERT INTO PRODUTOCARDTRAB
               (NRPRODUTOCARDTRAB, NRCARDAPIOTRAB, 
                CDPRODUTO, CDMARCA, 
                VRCUSTO,
                NRPRODLISTAPRECOTCO,
                NRORG, NRORGINCLUSAO, NRORGULTATU,
                CDOPERINCLUSAO, CDOPERULTATU,
                DTINCLUSAO, DTULTATU)
               VALUES
               (V_NRPRODUTOCARDTRAB, V_NRCARDAPIOTRAB,
                C_CUSTOS.CDPRODESTO, C_CUSTOS.CDMARCA, 
                C_CUSTOS.VRCUSTO + ( C_CUSTOS.VRCUSTO * (NVL(P_VRPEACRESCUSTO, 0)/100)),
                C_CUSTOS.NRPRODLISTAPRECOTCO,
                P_NRORG, P_NRORG, P_NRORG,
                P_CDOPERADOR, P_CDOPERADOR,
                SYSDATE, SYSDATE);
            END LOOP;            
         END IF;

         -- Verifica produto de estoque em uso em receitas do prato
         FOR C_RECEITAS IN
         (
            SELECT DISTINCT P.CDPRATO || ' - ' || P.NMPRATO AS PRATO, PT.CDARVPROD || ' - ' || PT.NMPRODUTO AS NMPRODUTO
              FROM RECEPRATCARDTRAB R
                   INNER JOIN PRATO P ON P.CDFILAUXPRAT = R.CDFILAUXPRAT AND 
                                         P.CDPRATO = R.CDPRATO
                   INNER JOIN PRODUTO PT ON PT.CDPRODUTO = R.CDPRODUTO
             WHERE R.NRCARDAPIOTRAB = V_NRCARDAPIOTRAB
               AND (PT.CDPRODUTO <> PT.CDPRODESTO OR PT.CDPRODESTO IS NULL)
         ) LOOP
            -- Produto __PARAM0__ não é produto de estoque e está em uso no prato __PARAM1__
            I_L(MSG('TCOPROC_PRODUTO_ESTOQUE_INVALIDO', C_RECEITAS.NMPRODUTO, C_RECEITAS.PRATO));
         END LOOP;

         -- Verifica produto com custo zero
         FOR C_PRODUTOS IN
         (
            SELECT DISTINCT R.CDPRODUTO, PT.CDARVPROD || ' - ' || PT.NMPRODUTO AS NMPRODUTO
              FROM RECEPRATCARDTRAB R
                   INNER JOIN PRODUTO PT ON PT.CDPRODUTO = R.CDPRODUTO
                   LEFT JOIN PRODUTOCARDTRAB P ON P.NRCARDAPIOTRAB = R.NRCARDAPIOTRAB AND
                                                  P.CDPRODUTO = R.CDPRODUTO AND
                                                  P.NRCARDAPIOTRAB = V_NRCARDAPIOTRAB
             WHERE R.NRCARDAPIOTRAB = V_NRCARDAPIOTRAB
               AND P.CDPRODUTO IS NULL
               AND PT.CDPRODUTO = PT.CDPRODESTO
         ) LOOP
            -- Produto __PARAM0__ não possui custo
            I_L(MSG('TCOPROC_PRODUTO_SEM_CUSTO', C_PRODUTOS.NMPRODUTO));
         END LOOP;
      END IF;
--=========================================================
--=== Retorno
--=========================================================
      IF P_LISTAERROS IS NULL THEN
         P_NRCARDAPIOTRAB := V_NRCARDAPIOTRAB; 
      END IF;
   END IF;

END;
/


CREATE OR REPLACE FUNCTION RAMO_ADESAO(P_NRADESAOCARDBASE IN NUMBER) RETURN VARCHAR2
AS
   V_RAMOS VARCHAR2(1000);
BEGIN
   V_RAMOS := '';
   FOR C_RAMOS IN
   (SELECT DISTINCT AC.DSATIVCLI
      FROM ATIVCLIADESAOCBASE A
           INNER JOIN ATIVCLISEGMER ATS ON ATS.NRATIVCLISEGMER = A.NRATIVCLISEGMER
           INNER JOIN ATIVCLIENTE AC ON AC.CDATIVCLI = ATS.CDATIVCLI
     WHERE A.NRADESAOCARDBASE = P_NRADESAOCARDBASE
     ORDER BY AC.DSATIVCLI) LOOP
      --Separador de valores
      IF LENGTH(V_RAMOS) > 0 THEN
         V_RAMOS := V_RAMOS || ', ';
      END IF;
      -- Terminador caso limite tenha sido atingido
      IF LENGTH(V_RAMOS) + LENGTH(C_RAMOS.DSATIVCLI) > 1000 THEN         
         V_RAMOS := V_RAMOS || SUBSTR(C_RAMOS.DSATIVCLI, 1, 995) || '(...)';
      ELSE
         V_RAMOS := V_RAMOS || C_RAMOS.DSATIVCLI;
      END IF;
   END LOOP;
   RETURN V_RAMOS;
END;
/


CREATE OR REPLACE FUNCTION SEGMENTO_ADESAO(P_NRADESAOCARDBASE IN NUMBER) RETURN VARCHAR2
AS
   V_SEGMENTOS VARCHAR2(1000);
BEGIN
   V_SEGMENTOS := '';
   FOR C_SEGS IN
   (SELECT S.DSSEGMER
      FROM SEGMERADESAOCBASE SC
           INNER JOIN SEGMERCADO S ON S.CDSEGMER = SC.CDSEGMER
     WHERE SC.NRADESAOCARDBASE = P_NRADESAOCARDBASE
     ORDER BY S.DSSEGMER) LOOP
      --Separador de valores
      IF LENGTH(V_SEGMENTOS) > 0 THEN
         V_SEGMENTOS := V_SEGMENTOS || ', ';
      END IF;
      -- Terminador caso limite tenha sido atingido
      IF LENGTH(V_SEGMENTOS) + LENGTH(C_SEGS.DSSEGMER) > 1000 THEN         
         V_SEGMENTOS := V_SEGMENTOS || SUBSTR(C_SEGS.DSSEGMER, 1, 995) || '(...)';
      ELSE
         V_SEGMENTOS := V_SEGMENTOS || C_SEGS.DSSEGMER;
      END IF;
   END LOOP;
   RETURN V_SEGMENTOS;
END;
/


DROP TYPE TCO_LIDERADOGN_TABLE
/
DROP TYPE TCO_LIDERADOGN_ROW
/

CREATE TYPE TCO_LIDERADOGN_ROW AS OBJECT
(
  NRGERENTENEGOCIO NUMBER,
  CDOPERADOR VARCHAR2(12),
  CDOPERADORLIDER VARCHAR2(12)
)
/

/**
 * View que lista o operador da equipe comercial e seus liderados
 *  
 */
CREATE TYPE TCO_LIDERADOGN_TABLE AS TABLE OF TCO_LIDERADOGN_ROW
/

CREATE OR REPLACE
FUNCTION LIDERADOGN
(
   P_CDOPERADOR IN VARCHAR2
) RETURN TCO_LIDERADOGN_TABLE PIPELINED
AS
   LINHA TCO_LIDERADOGN_ROW := TCO_LIDERADOGN_ROW(NULL, NULL, NULL);
BEGIN
   FOR C_LIDERADOS IN
   (
      SELECT G.NRGERENTENEGOCIO, G.CDOPERADOR, G.CDOPERADORLIDER
        FROM GERENTENEGOCIO G
       WHERE IDATIVO = 'S'       
       START WITH G.CDOPERADOR IN P_CDOPERADOR
     CONNECT BY PRIOR G.CDOPERADOR = G.CDOPERADORLIDER
   ) LOOP
      LINHA.NRGERENTENEGOCIO := C_LIDERADOS.NRGERENTENEGOCIO;
      LINHA.CDOPERADOR := C_LIDERADOS.CDOPERADOR;
      LINHA.CDOPERADORLIDER := C_LIDERADOS.CDOPERADORLIDER;      

      PIPE ROW (LINHA);
   END LOOP;
   RETURN;
END;
/


CREATE OR REPLACE FUNCTION SIT_PROPCOMERCIAL
(
   P_NRPROPOSTACOMERCIAL IN NUMBER
) RETURN VARCHAR2
AS
   V_SITUACAO VARCHAR2(30);
   V_QTDE NUMBER;
   V_NRVERSAOPROPCOM NUMBER;
BEGIN
   V_SITUACAO := 'PENDENTE';

   SELECT MAX(NRVERSAOPROPCOM)
     INTO V_NRVERSAOPROPCOM
     FROM VERSAOPROPCOM V
    WHERE V.NRPROPOSTACOMERCIAL = P_NRPROPOSTACOMERCIAL
      AND V.IDVERSAOPROPCOM = 'APROVADA';
   -- Se existe versão aprovada, a proposta também é aprovada
   IF V_NRVERSAOPROPCOM IS NOT NULL THEN
      V_SITUACAO := 'APROVADA';
      -- Se todos os serviços da versão aprovada estão efetivados, a proposta é efetivada
      SELECT COUNT(1)
        INTO V_QTDE
        FROM SERVICOPROPCOM
       WHERE NRVERSAOPROPCOM = V_NRVERSAOPROPCOM
         AND IDSERVICOPROPCOM <> 'EFETIVADO';

      IF V_QTDE = 0 THEN
         V_SITUACAO := 'EFETIVADA';
      END IF;
   END IF;
   RETURN V_SITUACAO;
END;
/

CREATE OR REPLACE FUNCTION SIT_VERSAOPROPCOM
(
   P_NRVERSAOPROPCOM IN NUMBER
) RETURN VARCHAR2
AS
   V_SITUACAO VARCHAR2(30);
   V_IDVERSAOPROPCOM VARCHAR2(30);
   V_QTDE NUMBER;
   V_QT_SERV_CALC NUMBER;
BEGIN
   SELECT MAX(IDVERSAOPROPCOM)
     INTO V_IDVERSAOPROPCOM
     FROM VERSAOPROPCOM
    WHERE NRVERSAOPROPCOM = P_NRVERSAOPROPCOM;

   IF V_IDVERSAOPROPCOM = 'CONCLUIDA' THEN
      V_SITUACAO := 'CONCLUIDA';
   ELSIF V_IDVERSAOPROPCOM = 'APROVADA' THEN
      V_SITUACAO := 'APROVADA';
      -- Se todos os serviços da versão estão efetivados,a versão está efetivada
      SELECT COUNT(1)
        INTO V_QTDE
        FROM SERVICOPROPCOM
       WHERE NRVERSAOPROPCOM = P_NRVERSAOPROPCOM
         AND IDSERVICOPROPCOM <> 'EFETIVADO';
      IF V_QTDE = 0 THEN
         V_SITUACAO := 'EFETIVADA';
      END IF;
   ELSE
      V_SITUACAO := 'PENDENTE';

      FOR C_SERVICOS IN
      (
         SELECT S.IDSERVICOPROPCOM, D.NRCARDAPIOTRAB
           FROM SERVICOPROPCOM S
                INNER JOIN DETALHESERVPROPCOM D ON D.NRDETALHESERVPROPCOM = S.NRDETALHESERVPROPCOM
          WHERE S.NRVERSAOPROPCOM = P_NRVERSAOPROPCOM
          ORDER BY S.IDSERVICOPROPCOM
      ) LOOP
         -- A presença de um cardápio de trabalho sinaliza o cálculo do serviço
         IF V_SITUACAO = 'PENDENTE' AND C_SERVICOS.NRCARDAPIOTRAB IS NOT NULL THEN
            V_SITUACAO := 'PARCIAL';
         END IF;
         -- Se existir algum serviço aguardando planejamento, a versão está aguardando planejamento
         IF V_SITUACAO NOT IN ('AGUARDANDOPLANEJAMENTO', 'AGUARDANDOGN') AND
            C_SERVICOS.IDSERVICOPROPCOM = 'AGUARDANDOPLANEJAMENTO' THEN
            V_SITUACAO := 'AGUARDANDOPLANEJAMENTO';
         END IF;
         -- Se a situação for aguardando GN, ela tem prioridade sobre as demais
         IF V_SITUACAO <> 'AGUARDANDOGN' AND C_SERVICOS.IDSERVICOPROPCOM = 'AGUARDANDOGN' THEN
            V_SITUACAO := 'AGUARDANDOGN';
         END IF;      
      END LOOP;

      -- Se todos os serviços estão calculados, a versão está calculada (caso ainda não seja )
      IF V_SITUACAO = 'PARCIAL' THEN
         SELECT COUNT(1), SUM(CASE WHEN NRCARDAPIOTRAB IS NULL THEN 0 ELSE 1 END)
           INTO V_QTDE, V_QT_SERV_CALC
           FROM SERVICOPROPCOM S
                INNER JOIN DETALHESERVPROPCOM D ON D.NRDETALHESERVPROPCOM = S.NRDETALHESERVPROPCOM
          WHERE S. NRVERSAOPROPCOM = P_NRVERSAOPROPCOM;

         IF V_QTDE = V_QT_SERV_CALC THEN
            V_SITUACAO := 'CALCULADA';
         END IF;
      END IF;
   END IF;

   RETURN V_SITUACAO;
END;
/


CREATE OR REPLACE FUNCTION SIT_SERVICOPROPCOM
(
   P_NRSERVICOPROPCOM IN NUMBER,
   P_PLANEJAMENTO IN VARCHAR2 DEFAULT 'N'
) RETURN VARCHAR2
AS
   V_SITUACAO VARCHAR2(30);
   V_NRVERSAOPROPCOM NUMBER;
   V_IDSERVICOPROPCOM VARCHAR2(30);
   V_IDVERSAOPROPCOM VARCHAR2(30);
   V_QTDE NUMBER;
   V_QT_SERV_CALC NUMBER;
   V_NRDETSERVPROPCOMPLAN NUMBER;
   V_NRHISTNOTIFPROPCOM NUMBER;
   V_CDRESPONSAVELPLAN VARCHAR2(12);
   V_IDMOTIVO VARCHAR2(30);
BEGIN
   SELECT MAX(IDSERVICOPROPCOM), MAX(NRVERSAOPROPCOM), MAX(NRDETSERVPROPCOMPLAN)
     INTO V_IDSERVICOPROPCOM, V_NRVERSAOPROPCOM, V_NRDETSERVPROPCOMPLAN
     FROM SERVICOPROPCOM
    WHERE NRSERVICOPROPCOM = P_NRSERVICOPROPCOM;

   SELECT MAX(IDVERSAOPROPCOM)
     INTO V_IDVERSAOPROPCOM
     FROM VERSAOPROPCOM
    WHERE NRVERSAOPROPCOM = V_NRVERSAOPROPCOM;

   IF V_IDVERSAOPROPCOM = 'CONCLUIDA' THEN
      V_SITUACAO := 'CONCLUIDO';
   ELSIF V_IDVERSAOPROPCOM = 'APROVADA' THEN
      IF V_IDSERVICOPROPCOM = 'EFETIVADO' THEN
         V_SITUACAO := 'EFETIVADO';
      ELSE
         V_SITUACAO := 'APROVADO';
      END IF;
   ELSE
      V_SITUACAO := V_IDSERVICOPROPCOM;
      -- Se for chamado em modo de planejamento
      IF P_PLANEJAMENTO = 'S' THEN
         -- Se não foi feita solicitação ao planejamento
         IF V_IDSERVICOPROPCOM IN ('PENDENTE', 'CALCULADO') THEN
            V_SITUACAO := 'NAOSOLICITADO';
         END IF;

         IF V_IDSERVICOPROPCOM = 'AGUARDANDOPLANEJAMENTO' THEN
            SELECT MAX(CDRESPONSAVELPLAN)
              INTO V_CDRESPONSAVELPLAN
              FROM DETALHESERVPROPCOM
             WHERE NRDETALHESERVPROPCOM = V_NRDETSERVPROPCOMPLAN;

            -- Se responsável informado fica em andamento
            IF V_CDRESPONSAVELPLAN IS NOT NULL THEN
               V_SITUACAO := 'EMANDAMENTO';

               -- Verifica se o GN mandou uma resposta
               SELECT MAX(NRHISTNOTIFPROPCOM)
                 INTO V_NRHISTNOTIFPROPCOM
                 FROM HISTNOTIFPROPCOM
                WHERE NRSERVICOPROPCOM = P_NRSERVICOPROPCOM;

               SELECT MAX(IDMOTIVO)
                 INTO V_IDMOTIVO
                 FROM HISTNOTIFPROPCOM
                WHERE NRHISTNOTIFPROPCOM = V_NRHISTNOTIFPROPCOM;

               -- Se dúvida respondida pelo GN, mostra como retorno GN
               IF V_IDMOTIVO = 'DUVIDARESPONDIDA' THEN
                  V_SITUACAO := 'EMANDAMENTO_RETORNOGN';
               END IF;
            END IF;
         END IF;
      END IF;
   END IF;

   RETURN V_SITUACAO;
END;
/


CREATE OR REPLACE PROCEDURE COPIA_CARDAPIOTRAB
(
P_NRCARDAPIOTRAB IN NUMBER,
P_CDOPERADOR IN VARCHAR2,
P_NRORG IN NUMBER,
P_NRCARDAPIOTRABNOVO OUT NUMBER
)
AS
   V_QTDE NUMBER;
   V_NRCARDAPIOTRAB NUMBER;
   V_NRCONFIGCARDTRAB NUMBER;
   V_NRDIACARDTRAB NUMBER;
   V_NRPRODUTOCARDTRAB NUMBER;
   V_NRCOMPCARDTRAB NUMBER;
   V_NRRECEPRATCARDTRAB NUMBER;
BEGIN
   SELECT COUNT(1)
     INTO V_QTDE
     FROM CARDAPIOTRAB
    WHERE NRCARDAPIOTRAB = P_NRCARDAPIOTRAB;
   IF V_QTDE > 0 THEN
      V_NRCARDAPIOTRAB := TO_NUMBER(RETORNA_NOVO_CODIGO('CARDAPIOTRAB', 1));

      INSERT INTO CARDAPIOTRAB
      (NRCARDAPIOTRAB, CDREGIAO, DTCUSTO, CDTIPOCUSTO,
       IDORIGEM, NRCARDAPIOBASE,
       NRORG, NRORGINCLUSAO, NRORGULTATU,
       CDOPERINCLUSAO, CDOPERULTATU,
       DTINCLUSAO, DTULTATU)
      SELECT V_NRCARDAPIOTRAB, C.CDREGIAO, C.DTCUSTO, C.CDTIPOCUSTO,
             C.IDORIGEM, C.NRCARDAPIOBASE,
             P_NRORG, P_NRORG, P_NRORG,
             P_CDOPERADOR, P_CDOPERADOR,
             SYSDATE, SYSDATE
        FROM CARDAPIOTRAB C 
       WHERE C.NRCARDAPIOTRAB = P_NRCARDAPIOTRAB;

      -- Configuração
      SELECT COUNT(1)
        INTO V_QTDE
        FROM CONFIGCARDTRAB
       WHERE NRCARDAPIOTRAB = P_NRCARDAPIOTRAB;

      IF V_QTDE > 0 THEN
         V_NRCONFIGCARDTRAB := TO_NUMBER(RETORNA_NOVO_CODIGO('CONFIGCARDTRAB', V_QTDE));

         INSERT INTO CONFIGCARDTRAB
         (NRCONFIGCARDTRAB, NRCARDAPIOTRAB, CDTIPOPRAT,
          DSCOMPLEMENTO, IDCLASSIFICACAO, NRORDEM, 
          IDTEMPERATURA, NRCONFIGCARDBASE,
          NRORG, NRORGINCLUSAO, NRORGULTATU,
          CDOPERINCLUSAO, CDOPERULTATU,
          DTINCLUSAO, DTULTATU)
         SELECT V_NRCONFIGCARDTRAB + (ROW_NUMBER() OVER (ORDER BY C.NRCONFIGCARDTRAB) - 1) AS NRCONFIGCARDTRAB,
                V_NRCARDAPIOTRAB,
                C.CDTIPOPRAT, C.DSCOMPLEMENTO, C.IDCLASSIFICACAO, C.NRORDEM,
                C.IDTEMPERATURA, C.NRCONFIGCARDBASE,
                P_NRORG, P_NRORG, P_NRORG,
                P_CDOPERADOR, P_CDOPERADOR,
                SYSDATE, SYSDATE
           FROM CONFIGCARDTRAB C
          WHERE C.NRCARDAPIOTRAB = P_NRCARDAPIOTRAB
          ORDER BY C.NRCONFIGCARDTRAB;
      END IF;

      -- Dias
      SELECT COUNT(1)
        INTO V_QTDE
        FROM DIACARDTRAB
       WHERE NRCARDAPIOTRAB = P_NRCARDAPIOTRAB;

      IF V_QTDE > 0 THEN
         V_NRDIACARDTRAB := TO_NUMBER(RETORNA_NOVO_CODIGO('DIACARDTRAB', V_QTDE));

         INSERT INTO DIACARDTRAB
         (NRDIACARDTRAB, NRCARDAPIOTRAB,
          NRSEMANA, NRDIASEMANA, QTCOMENSAIS,
          NRORG, NRORGINCLUSAO, NRORGULTATU,
          CDOPERINCLUSAO, CDOPERULTATU,
          DTINCLUSAO, DTULTATU)
         SELECT V_NRDIACARDTRAB + (ROW_NUMBER() OVER (ORDER BY D.NRDIACARDTRAB) - 1) AS V_NRDIACARDTRAB,
                V_NRCARDAPIOTRAB,
                D.NRSEMANA, D.NRDIASEMANA, D.QTCOMENSAIS,
                P_NRORG, P_NRORG, P_NRORG,
                P_CDOPERADOR, P_CDOPERADOR,
                SYSDATE, SYSDATE
           FROM DIACARDTRAB D
          WHERE D.NRCARDAPIOTRAB = P_NRCARDAPIOTRAB
          ORDER BY D.NRDIACARDTRAB;            
      END IF;

      -- Produtos
      SELECT COUNT(1)
        INTO V_QTDE
        FROM PRODUTOCARDTRAB
       WHERE NRCARDAPIOTRAB = P_NRCARDAPIOTRAB;

      IF V_QTDE > 0 THEN
         V_NRPRODUTOCARDTRAB := TO_NUMBER(RETORNA_NOVO_CODIGO('PRODUTOCARDTRAB', V_QTDE));

         INSERT INTO PRODUTOCARDTRAB
         (NRPRODUTOCARDTRAB, NRCARDAPIOTRAB,
          CDPRODUTO, CDMARCA, VRCUSTO,
          NRORG, NRORGINCLUSAO, NRORGULTATU,
          CDOPERINCLUSAO, CDOPERULTATU,
          DTINCLUSAO, DTULTATU)
         SELECT V_NRPRODUTOCARDTRAB + (ROW_NUMBER() OVER (ORDER BY P.NRPRODUTOCARDTRAB) - 1) AS NRPRODUTOCARDTRAB,
                V_NRCARDAPIOTRAB,
                P.CDPRODUTO, P.CDMARCA, P.VRCUSTO,
                P_NRORG, P_NRORG, P_NRORG,
                P_CDOPERADOR, P_CDOPERADOR,
                SYSDATE, SYSDATE
           FROM PRODUTOCARDTRAB P
          WHERE P.NRCARDAPIOTRAB = P_NRCARDAPIOTRAB
          ORDER BY P.NRPRODUTOCARDTRAB;
      END IF;

      -- Composição
      SELECT COUNT(1)
        INTO V_QTDE
        FROM COMPCARDTRAB
       WHERE NRCARDAPIOTRAB = P_NRCARDAPIOTRAB;

      IF V_QTDE > 0 THEN
         V_NRCOMPCARDTRAB := TO_NUMBER(RETORNA_NOVO_CODIGO('COMPCARDTRAB', V_QTDE));

         INSERT INTO COMPCARDTRAB
         (NRCOMPCARDTRAB, NRCARDAPIOTRAB,
          NRDIACARDTRAB, NRCONFIGCARDTRAB,
          CDFILAUXPRAT, CDPRATO,
          NRORG, NRORGINCLUSAO, NRORGULTATU,
          CDOPERINCLUSAO, CDOPERULTATU,
          DTINCLUSAO, DTULTATU)
         SELECT V_NRCOMPCARDTRAB + (ROW_NUMBER() OVER (ORDER BY C.NRCOMPCARDTRAB) - 1) AS NRCOMPCARDTRAB, 
                V_NRCARDAPIOTRAB,
                DDEST.NRDIACARDTRABDEST,
                CNFDEST.NRCONFIGCARDTRABDEST,
                C.CDFILAUXPRAT, C.CDPRATO,
                P_NRORG, P_NRORG, P_NRORG,
                P_CDOPERADOR, P_CDOPERADOR,
                SYSDATE, SYSDATE
           FROM COMPCARDTRAB C
                INNER JOIN 
                (SELECT D.NRDIACARDTRAB, 
                        V_NRDIACARDTRAB + (ROW_NUMBER() OVER (ORDER BY D.NRDIACARDTRAB) - 1) AS NRDIACARDTRABDEST                   
                   FROM DIACARDTRAB D
                  WHERE D.NRCARDAPIOTRAB = P_NRCARDAPIOTRAB
                  ORDER BY D.NRDIACARDTRAB
                ) DDEST ON DDEST.NRDIACARDTRAB = C.NRDIACARDTRAB
                INNER JOIN
                (SELECT C.NRCONFIGCARDTRAB,
                        V_NRCONFIGCARDTRAB + (ROW_NUMBER() OVER (ORDER BY C.NRCONFIGCARDTRAB) - 1) AS NRCONFIGCARDTRABDEST
                   FROM CONFIGCARDTRAB C
                  WHERE C.NRCARDAPIOTRAB = P_NRCARDAPIOTRAB
                  ORDER BY C.NRCONFIGCARDTRAB
                ) CNFDEST ON CNFDEST.NRCONFIGCARDTRAB = C.NRCONFIGCARDTRAB
          WHERE C.NRCARDAPIOTRAB = P_NRCARDAPIOTRAB
          ORDER BY C.NRCOMPCARDTRAB;
      END IF;

      -- Receitas
      SELECT COUNT(1)
        INTO V_QTDE
        FROM RECEPRATCARDTRAB
       WHERE NRCARDAPIOTRAB = P_NRCARDAPIOTRAB;

      IF V_QTDE > 0 THEN
         V_NRRECEPRATCARDTRAB := TO_NUMBER(RETORNA_NOVO_CODIGO('RECEPRATCARDTRAB', V_QTDE));

         INSERT INTO RECEPRATCARDTRAB
         (NRRECEPRATCARDTRAB, NRCARDAPIOTRAB,
          CDFILAUXPRAT, CDPRATO,            
          CDPRODUTO, QTPRODRECCARDTRAB,
          VRPEFATCOCCARDTRAB, VRPEFATCORCARDTRAB,
          SGUNIDADE, QTBRUTACARDTRABUNR,
          IDPRODBASECARDTRAB, IDQTDEFIXCARDTRAB,
          NRORG, NRORGINCLUSAO, NRORGULTATU,
          CDOPERINCLUSAO, CDOPERULTATU,
          DTINCLUSAO, DTULTATU)
         SELECT V_NRRECEPRATCARDTRAB + (ROW_NUMBER() OVER (ORDER BY R.NRRECEPRATCARDTRAB) - 1) AS NRRECEPRATCARDTRAB,
                V_NRCARDAPIOTRAB,
                R.CDFILAUXPRAT, R.CDPRATO,
                CDPRODUTO, QTPRODRECCARDTRAB,
                VRPEFATCOCCARDTRAB, VRPEFATCORCARDTRAB,
                SGUNIDADE, QTBRUTACARDTRABUNR,
                IDPRODBASECARDTRAB, IDQTDEFIXCARDTRAB,
                P_NRORG, P_NRORG, P_NRORG,
                P_CDOPERADOR, P_CDOPERADOR,
                SYSDATE, SYSDATE
           FROM RECEPRATCARDTRAB R
          WHERE R.NRCARDAPIOTRAB = P_NRCARDAPIOTRAB
          ORDER BY R.NRRECEPRATCARDTRAB;
      END IF;

      P_NRCARDAPIOTRABNOVO := V_NRCARDAPIOTRAB;
   END IF;
END;
/


CREATE OR REPLACE PROCEDURE COPIA_DETALHESERVPROPCOM
(
P_NRDETALHESERVPROPCOM IN NUMBER,
P_COPIA_CARD IN VARCHAR2,
P_CDOPERADOR IN VARCHAR2,
P_NRORG IN NUMBER,
P_NRDETALHESERVPROPCOMNOVO OUT NUMBER
)
AS
   V_QTDE NUMBER;
   V_NRSERVICOPROPCOM NUMBER;
   V_NRCARDAPIOTRAB NUMBER;
   V_NRCARDAPIOTRABNOVO NUMBER;
   V_NRDETALHESERVPROPCOM NUMBER;
   V_NRPRODUTOPROPCOM NUMBER;
   V_NRINCIDENCIAPROPCOM NUMBER;
   V_NRCONFGRUPOTPPROPCOM NUMBER;
   V_NRCONFIGSERVPROPCOM NUMBER;
BEGIN
   SELECT MAX(NRSERVICOPROPCOM), MAX(NRCARDAPIOTRAB)
     INTO V_NRSERVICOPROPCOM, V_NRCARDAPIOTRAB
     FROM DETALHESERVPROPCOM
    WHERE NRDETALHESERVPROPCOM = P_NRDETALHESERVPROPCOM;

   IF V_NRSERVICOPROPCOM IS NOT NULL THEN

      V_NRCARDAPIOTRABNOVO := NULL;
      IF P_COPIA_CARD = 'S' THEN
         -- Duplica cardápio de trabalho do detalhe do serviço         
         IF V_NRCARDAPIOTRAB IS NOT NULL THEN
            COPIA_CARDAPIOTRAB(V_NRCARDAPIOTRAB, P_CDOPERADOR, P_NRORG, V_NRCARDAPIOTRABNOVO);
         END IF;
      END IF;
      
      V_NRDETALHESERVPROPCOM := TO_NUMBER(RETORNA_NOVO_CODIGO('DETALHESERVPROPCOM', 1));
      -- Inclui novo detalhe de serviço
      INSERT INTO DETALHESERVPROPCOM
      (NRDETALHESERVPROPCOM, NRSERVICOPROPCOM, NRCARDAPIOTRAB,
       NRORG, NRORGINCLUSAO, NRORGULTATU,
       CDOPERINCLUSAO, CDOPERULTATU,
       DTINCLUSAO, DTULTATU)
      VALUES
      (V_NRDETALHESERVPROPCOM, V_NRSERVICOPROPCOM, V_NRCARDAPIOTRABNOVO,
       P_NRORG, P_NRORG, P_NRORG,
       P_CDOPERADOR, P_CDOPERADOR,
       SYSDATE, SYSDATE);
      -- Configuração
      SELECT COUNT(1)
        INTO V_QTDE
        FROM CONFIGSERVPROPCOM
       WHERE NRDETALHESERVPROPCOM = P_NRDETALHESERVPROPCOM;
      IF V_QTDE > 0 THEN
         V_NRCONFIGSERVPROPCOM := TO_NUMBER(RETORNA_NOVO_CODIGO('CONFIGSERVPROPCOM', V_QTDE));
         INSERT INTO CONFIGSERVPROPCOM
         (NRCONFIGSERVPROPCOM, NRDETALHESERVPROPCOM,
          NRCONFIGCARDBASE, CDTIPOPRAT, DSCOMPLEMENTO,
          NRORDEM, IDTEMPERATURA,
          NRORG, NRORGINCLUSAO, NRORGULTATU,
          CDOPERINCLUSAO, CDOPERULTATU,
          DTINCLUSAO, DTULTATU)
         SELECT V_NRCONFIGSERVPROPCOM + (ROW_NUMBER() OVER (ORDER BY C.NRCONFIGSERVPROPCOM) - 1) AS NRCONFIGSERVPROPCOM,
                V_NRDETALHESERVPROPCOM,
                C.NRCONFIGCARDBASE, C.CDTIPOPRAT, C.DSCOMPLEMENTO,
                C.NRORDEM, C.IDTEMPERATURA,
                P_NRORG, P_NRORG, P_NRORG,
                P_CDOPERADOR, P_CDOPERADOR,
                SYSDATE, SYSDATE
           FROM CONFIGSERVPROPCOM C
          WHERE C.NRDETALHESERVPROPCOM = P_NRDETALHESERVPROPCOM
          ORDER BY C.NRCONFIGSERVPROPCOM;
      END IF;
      -- Grupos de tipo de prato
      SELECT COUNT(1)
        INTO V_QTDE
        FROM CONFGRUPOTPPROPCOM
       WHERE NRDETALHESERVPROPCOM = P_NRDETALHESERVPROPCOM;
      IF V_QTDE > 0 THEN
         V_NRCONFGRUPOTPPROPCOM := TO_NUMBER(RETORNA_NOVO_CODIGO('CONFGRUPOTPPROPCOM', V_QTDE));
         INSERT INTO CONFGRUPOTPPROPCOM
         (NRCONFGRUPOTPPROPCOM, NRDETALHESERVPROPCOM,
          CDGRTIPOPR, NRPORCIONAMENTO, NRGRAMATURACARDBASE,
          NRORG, NRORGINCLUSAO, NRORGULTATU,
          CDOPERINCLUSAO, CDOPERULTATU,
          DTINCLUSAO, DTULTATU)
         SELECT V_NRCONFGRUPOTPPROPCOM + (ROW_NUMBER() OVER (ORDER BY C.NRCONFGRUPOTPPROPCOM) - 1) AS NRCONFGRUPOTPPROPCOM, 
                V_NRDETALHESERVPROPCOM,
                C.CDGRTIPOPR, C.NRPORCIONAMENTO, C.NRGRAMATURACARDBASE,
                P_NRORG, P_NRORG, P_NRORG,
                P_CDOPERADOR, P_CDOPERADOR,
                SYSDATE, SYSDATE
           FROM CONFGRUPOTPPROPCOM C
          WHERE C.NRDETALHESERVPROPCOM = P_NRDETALHESERVPROPCOM
          ORDER BY C.NRCONFGRUPOTPPROPCOM;
      END IF;

      IF P_COPIA_CARD = 'S' THEN
         -- Produtos
         SELECT COUNT(1)
           INTO V_QTDE
           FROM PRODUTOPROPCOM
          WHERE NRDETALHESERVPROPCOM = P_NRDETALHESERVPROPCOM;
         IF V_QTDE > 0 THEN
            V_NRPRODUTOPROPCOM := TO_NUMBER(RETORNA_NOVO_CODIGO('PRODUTOPROPCOM' , V_QTDE));
            INSERT INTO PRODUTOPROPCOM
            (NRPRODUTOPROPCOM, NRDETALHESERVPROPCOM,
             CDPRODUTO, CDMARCASOLICITADA, CDMARCAESCOLHIDA,
             VRPEACRESCIMO,          
             NRORG, NRORGINCLUSAO, NRORGULTATU,
             CDOPERINCLUSAO, CDOPERULTATU,
             DTINCLUSAO, DTULTATU)
            SELECT V_NRPRODUTOPROPCOM + (ROW_NUMBER() OVER (ORDER BY P.NRPRODUTOPROPCOM) - 1) AS NRPRODUTOPROPCOM, 
                   V_NRDETALHESERVPROPCOM,
                   P.CDPRODUTO, P.CDMARCASOLICITADA, P.CDMARCAESCOLHIDA,
                   P.VRPEACRESCIMO,
                   P_NRORG, P_NRORG, P_NRORG,
                   P_CDOPERADOR, P_CDOPERADOR,
                   SYSDATE, SYSDATE
              FROM PRODUTOPROPCOM P
             WHERE P.NRDETALHESERVPROPCOM = P_NRDETALHESERVPROPCOM
             ORDER BY P.NRPRODUTOPROPCOM;
         END IF;
         -- Incidências
         SELECT COUNT(1)
           INTO V_QTDE
           FROM INCIDENCIAPROPCOM
          WHERE NRDETALHESERVPROPCOM = P_NRDETALHESERVPROPCOM;
         IF V_QTDE > 0 THEN
            V_NRINCIDENCIAPROPCOM := TO_NUMBER(RETORNA_NOVO_CODIGO('INCIDENCIAPROPCOM', V_QTDE));
            INSERT INTO INCIDENCIAPROPCOM
            (NRINCIDENCIAPROPCOM, NRDETALHESERVPROPCOM,
             NRGRUPOPRATOSERV, QTSOLICITADA,
             NRORG, NRORGINCLUSAO, NRORGULTATU,
             CDOPERINCLUSAO, CDOPERULTATU,
             DTINCLUSAO, DTULTATU)
            SELECT V_NRINCIDENCIAPROPCOM + (ROW_NUMBER() OVER (ORDER BY I.NRINCIDENCIAPROPCOM) - 1) AS NRINCIDENCIAPROPCOM, 
                   V_NRDETALHESERVPROPCOM,
                   NRGRUPOPRATOSERV, QTSOLICITADA,
                   P_NRORG, P_NRORG, P_NRORG,
                   P_CDOPERADOR, P_CDOPERADOR,
                   SYSDATE, SYSDATE
              FROM INCIDENCIAPROPCOM I
             WHERE I.NRDETALHESERVPROPCOM = P_NRDETALHESERVPROPCOM
             ORDER BY I.NRINCIDENCIAPROPCOM;
         END IF;
      END IF;
      P_NRDETALHESERVPROPCOMNOVO := V_NRDETALHESERVPROPCOM;
   END IF;
END;
/


CREATE OR REPLACE PROCEDURE SOL_ALT_SERVPROPCOM
(
P_NRSERVICOPROPCOM IN NUMBER,
P_IDORIGEM IN VARCHAR2,
P_IDDESTINO IN VARCHAR2,
P_IDMOTIVO IN VARCHAR2,
P_DSOBSERVACAO IN VARCHAR2,
P_TXHISTORICO IN CLOB,
P_CDOPERADOR IN VARCHAR2,
P_NRORG IN NUMBER
)
AS
   V_QTDE NUMBER;
   V_NRHISTNOTIFPROPCOM NUMBER;
   V_NRDETALHESERVPROPCOM NUMBER;
   V_NRDETALHESERVPROPCOMNOVO NUMBER;
   V_NRCARDAPIOTRAB NUMBER;
   V_NRDETSERVPROPCOMPLAN NUMBER;
   V_NRDETSERVPROPCOMPLANNOVO NUMBER;
   V_NRCARDAPIOTRABPLAN NUMBER;
   V_IDSERVICOPROPCOM VARCHAR2(30);
   V_IDSERVICOPROPCOMNOVO VARCHAR2(30);   

   -- Função auxiliar para agilizar 
   PROCEDURE MSGERRO(MSG IN VARCHAR2)
   AS
   BEGIN
      RAISE_APPLICATION_ERROR(-20000, MSG);
   END;

BEGIN
   SELECT COUNT(1), MAX(S.NRDETALHESERVPROPCOM), MAX(D.NRCARDAPIOTRAB), MAX(S.IDSERVICOPROPCOM),
          MAX(S.NRDETSERVPROPCOMPLAN), MAX(DP.NRCARDAPIOTRAB)
     INTO V_QTDE, V_NRDETALHESERVPROPCOM, V_NRCARDAPIOTRAB, V_IDSERVICOPROPCOM, 
          V_NRDETSERVPROPCOMPLAN, V_NRCARDAPIOTRABPLAN
     FROM SERVICOPROPCOM S
          LEFT JOIN DETALHESERVPROPCOM D ON D.NRDETALHESERVPROPCOM = S.NRDETALHESERVPROPCOM
          LEFT JOIN DETALHESERVPROPCOM DP ON DP.NRDETALHESERVPROPCOM = S.NRDETSERVPROPCOMPLAN
    WHERE S.NRSERVICOPROPCOM = P_NRSERVICOPROPCOM;   

   IF V_NRDETALHESERVPROPCOM IS NULL THEN
      -- Operação bloqueada. Serviço da proposta ainda não configurado pelo gerente de negócio
      MSGERRO(MSG('TCOPROC_SERVPROPCOMERCIAL_N_TRAB_GN'));
   END IF;

   IF P_IDORIGEM = P_IDDESTINO THEN
      -- Operação bloqueada. Origem da solicitação é igual ao destino da solicitação
      MSGERRO(MSG('TCOPROC_ORIGEM_SOL=DESTINO_SOL'));
   END IF;

   IF P_IDMOTIVO = 'SEMCARDBASE' OR 
      P_IDMOTIVO = 'ERROCALCULO' OR      
      P_IDMOTIVO = 'EDITAL' OR 
      P_IDMOTIVO = 'CUSTOMIZACAO' OR
      P_IDMOTIVO = 'DUVIDARESPONDIDA' OR
      P_IDMOTIVO = 'SERVICOCOMPLEMENTAR' THEN
      IF P_IDORIGEM <> 'GN' THEN         
         -- Operação bloqueada. Não é possível gerar solicitação com o motivo informado pelo planejamento.
         MSGERRO(MSG('TCOPROC_SOLICITACAO_INCORRETA_PLANEJAMENTO'));
      END IF;
      IF V_IDSERVICOPROPCOM = 'AGUARDANDOPLANEJAMENTO' THEN
         -- Operação bloqueada. Serviço da proposta já está aguardando planejamento
         MSGERRO(MSG('TCOPROC_SERVPROPOSTA_EM_PLANEJAMENTO'));
      END IF;
      V_IDSERVICOPROPCOMNOVO := 'AGUARDANDOPLANEJAMENTO';
   END IF;

   V_NRDETALHESERVPROPCOMNOVO := V_NRDETALHESERVPROPCOM;   

   IF P_IDMOTIVO = 'DUVIDA' OR
      P_IDMOTIVO = 'RECUSADO' OR
      P_IDMOTIVO = 'FINALIZADO' THEN
      IF P_IDORIGEM <> 'PLANEJAMENTO' THEN
         -- Operação bloqueada. Não é possível gerar solicitação com o motivo informado pelo gerente de negócio.
         MSGERRO(MSG('TCOPROC_SOLICITACAO_INCORRETA_GN'));
      END IF;
      IF V_IDSERVICOPROPCOM <> 'AGUARDANDOPLANEJAMENTO' THEN
         -- Operação bloqueada. Serviço da proposta não está aguardando planejamento
         MSGERRO(MSG('TCOPROC_SERVPROPOSTA_N_ESTA_EM_PLANEJAMENTO'));
      END IF;

      IF P_IDMOTIVO = 'DUVIDA' THEN
         V_IDSERVICOPROPCOMNOVO := 'AGUARDANDOGN';
      ELSIF P_IDMOTIVO = 'RECUSADO' THEN
         V_IDSERVICOPROPCOMNOVO := 'RECUSADO';
      ELSIF P_IDMOTIVO = 'FINALIZADO' THEN         
         V_NRDETALHESERVPROPCOMNOVO := V_NRDETSERVPROPCOMPLAN;
         V_IDSERVICOPROPCOMNOVO := 'FINALIZADOPLANEJAMENTO';
      END IF;      
   END IF;

   IF P_IDMOTIVO = 'APROVADO' THEN      
      IF P_IDORIGEM <> 'GN' THEN
         -- Operação bloqueada. Não é possível gerar solicitação com o motivo informado pelo planejamento.
         MSGERRO(MSG('TCOPROC_SOLICITACAO_INCORRETA_PLANEJAMENTO'));
      END IF;

      V_IDSERVICOPROPCOMNOVO := V_IDSERVICOPROPCOM;      
   END IF;
   
   IF V_IDSERVICOPROPCOMNOVO IS NULL THEN
      -- Operação bloqueada. Não é possível gerar solicitação com o motivo informado pelo planejamento.
      MSGERRO(MSG('TCOPROC_SERVPROPOSTA_SITUACAO_N_DEFINIDA'));
   END IF;

   -- Cópia do detalhe de serviço caso esteja enviando ao planejamento   
   V_NRDETSERVPROPCOMPLANNOVO := V_NRDETSERVPROPCOMPLAN;
   IF P_IDORIGEM = 'GN' THEN
      IF P_IDMOTIVO IN ('DUVIDARESPONDIDA', 'APROVADO') THEN
         COPIA_DETALHESERVPROPCOM(V_NRDETALHESERVPROPCOM, 'S', P_CDOPERADOR, P_NRORG, V_NRDETSERVPROPCOMPLANNOVO);
      END IF;
   END IF;

   UPDATE SERVICOPROPCOM
      SET IDSERVICOPROPCOM = V_IDSERVICOPROPCOMNOVO,
          NRDETALHESERVPROPCOM = V_NRDETALHESERVPROPCOMNOVO,
          NRDETSERVPROPCOMPLAN = V_NRDETSERVPROPCOMPLANNOVO,
          NRORGULTATU = P_NRORG,
          CDOPERULTATU = P_CDOPERADOR,
          DTULTATU = SYSDATE
    WHERE NRSERVICOPROPCOM = P_NRSERVICOPROPCOM;

   -- Registro do histórico de notificação do serviço da proposta
   V_NRHISTNOTIFPROPCOM := TO_NUMBER(RETORNA_NOVO_CODIGO('HISTNOTIFPROPCOM', 1));   
   INSERT INTO HISTNOTIFPROPCOM
   (NRHISTNOTIFPROPCOM, NRSERVICOPROPCOM,
    IDORIGEM, IDDESTINO, IDMOTIVO,
    DSOBSERVACAO, TXHISTORICO,
    NRORG, NRORGINCLUSAO, NRORGULTATU,
    CDOPERINCLUSAO, CDOPERULTATU,
    DTINCLUSAO, DTULTATU)
   VALUES
   (V_NRHISTNOTIFPROPCOM, P_NRSERVICOPROPCOM,
    P_IDORIGEM, P_IDDESTINO, P_IDMOTIVO,
    P_DSOBSERVACAO, P_TXHISTORICO,
    P_NRORG, P_NRORG, P_NRORG,
    P_CDOPERADOR, P_CDOPERADOR,
    SYSDATE, SYSDATE);   
END;
/


CREATE OR REPLACE FUNCTION CUSTO_PROD_CARDTRAB
(
   P_NRCARDAPIOTRAB IN NUMBER,
   P_CDPRODUTO IN VARCHAR2
) RETURN FLOAT
AS
   V_VRCUSTO FLOAT := 0;
BEGIN
   SELECT MAX(VRCUSTO)
     INTO V_VRCUSTO
     FROM PRODUTOCARDTRAB
    WHERE NRCARDAPIOTRAB = P_NRCARDAPIOTRAB
      AND CDPRODUTO = P_CDPRODUTO;

   RETURN ROUND(NVL(V_VRCUSTO, 0.00), 5);
END;
/


CREATE OR REPLACE FUNCTION CUSTO_PRAT_CARDTRAB
(
   P_NRCARDAPIOTRAB IN NUMBER,
   P_CDFILAUXPRAT IN VARCHAR2,
   P_CDPRATO IN VARCHAR2
) RETURN FLOAT
AS
   V_VRCUSTO FLOAT := 0;
BEGIN
   SELECT SUM(NVL(QTBRUTACARDTRABUNR, 0) * CUSTO_PROD_CARDTRAB(NRCARDAPIOTRAB, CDPRODUTO))
     INTO V_VRCUSTO
     FROM
   (
    SELECT QTBRUTACARDTRABUNR, NRCARDAPIOTRAB, CDPRODUTO     
      FROM RECEPRATCARDTRAB
     WHERE NRCARDAPIOTRAB = P_NRCARDAPIOTRAB
       AND CDFILAUXPRAT = P_CDFILAUXPRAT
       AND CDPRATO = P_CDPRATO
   ) S;
   RETURN ROUND(NVL(V_VRCUSTO, 0), 5);
END;
/


CREATE OR REPLACE FUNCTION CUSTO_DIA_CARDTRAB
(
   P_NRCARDAPIOTRAB IN NUMBER,
   P_NRDIACARDTRAB IN NUMBER
) RETURN FLOAT
AS
   V_VRCUSTO FLOAT := 0;
BEGIN
   SELECT SUM(NVL(C.VRPECONSCARDTRAB/100 * D.QTCOMENSAIS, 0) * CUSTO_PRAT_CARDTRAB(C.NRCARDAPIOTRAB, C.CDFILAUXPRAT, C.CDPRATO))
     INTO V_VRCUSTO
        FROM COMPCARDTRAB C             
             INNER JOIN DIACARDTRAB D ON D.NRDIACARDTRAB = C.NRDIACARDTRAB
       WHERE C.NRCARDAPIOTRAB = P_NRCARDAPIOTRAB
         AND C.NRDIACARDTRAB = P_NRDIACARDTRAB;
   
   RETURN ROUND(NVL(V_VRCUSTO, 0), 5);
END;
/


CREATE OR REPLACE FUNCTION CUSTO_PERC_COL_CARDTRAB
(
   P_NRCARDAPIOTRAB IN NUMBER,
   P_NRCONFIGCARDTRAB IN NUMBER
) RETURN FLOAT
AS
   V_VRCUSTO FLOAT := 0;
   V_QTTOTCOMENSAIS FLOAT := 0;
BEGIN
   FOR C_PRATOS IN
   (
      SELECT S.QTCOMENSAIS, S.VRPECONSCARDTRAB/100 * S.QTCOMENSAIS AS QTCOMENSAIS_ESTIMADOS,
             CUSTO_PRAT_CARDTRAB(S.NRCARDAPIOTRAB, S.CDFILAUXPRAT, S.CDPRATO) AS VRCUSTO        
        FROM
        (SELECT D.QTCOMENSAIS, C.VRPECONSCARDTRAB, C.NRCARDAPIOTRAB, C.CDFILAUXPRAT, C.CDPRATO
        FROM DIACARDTRAB D        
             LEFT JOIN COMPCARDTRAB C ON C.NRCARDAPIOTRAB = D.NRCARDAPIOTRAB AND
                                         C.NRDIACARDTRAB = D.NRDIACARDTRAB AND
                                         C.NRCONFIGCARDTRAB = P_NRCONFIGCARDTRAB
       WHERE D.NRCARDAPIOTRAB = P_NRCARDAPIOTRAB
         AND D.QTCOMENSAIS > 0
        ) S
   ) LOOP
      V_VRCUSTO := V_VRCUSTO + NVL(C_PRATOS.QTCOMENSAIS_ESTIMADOS, 0) * NVL(C_PRATOS.VRCUSTO, 0);
      V_QTTOTCOMENSAIS := V_QTTOTCOMENSAIS + C_PRATOS.QTCOMENSAIS;
   END LOOP;
   IF V_QTTOTCOMENSAIS > 0 THEN
      RETURN ROUND(V_VRCUSTO/V_QTTOTCOMENSAIS, 5);
   END IF;

   RETURN 0;
END;
/


CREATE OR REPLACE FUNCTION CUSTO_PERC_CARDTRAB
(
   P_NRCARDAPIOTRAB IN NUMBER,
   P_IDTIPO IN VARCHAR2 DEFAULT NULL
) RETURN FLOAT
AS
   V_VRCUSTO FLOAT := 0;
BEGIN
   FOR C_COLS IN
   (
      SELECT CUSTO_PERC_COL_CARDTRAB(NRCARDAPIOTRAB, NRCONFIGCARDTRAB) AS VRCUSTO
        FROM
      (
      SELECT NRCARDAPIOTRAB, NRCONFIGCARDTRAB
        FROM CONFIGCARDTRAB
       WHERE NRCARDAPIOTRAB = P_NRCARDAPIOTRAB
         AND (P_IDTIPO IS NULL OR IDCLASSIFICACAO = P_IDTIPO)
      ) S
   ) LOOP
      V_VRCUSTO := V_VRCUSTO + C_COLS.VRCUSTO;
   END LOOP;

   RETURN ROUND(V_VRCUSTO, 5);
END;
/


CREATE OR REPLACE PROCEDURE VALIDA_CARDTRAB
(
   P_NRCARDAPIOTRAB IN NUMBER,
   P_NRORG IN NUMBER,
   P_CDOPERADOR IN VARCHAR2,
   P_CDFILIALLOGADA IN VARCHAR2,   
   P_LISTAERROS OUT VARCHAR2,
   P_IDIOMA IN VARCHAR2 DEFAULT 'PT_BR'
)
AS
   -- Procedure auxiliar para agilizar inclusão na lista de erros
   PROCEDURE I_L(MENSAGEM IN VARCHAR2)
   AS
   BEGIN
      INSERE_LISTA_ERROS(P_CDFILIALLOGADA, MENSAGEM,
                         P_CDOPERADOR, P_NRORG, P_LISTAERROS);
   END;

   FUNCTION NOME_DIA(NRSEMANA IN NUMBER, NRDIASEMANA IN NUMBER) RETURN VARCHAR2
   AS
   BEGIN
      IF UPPER(P_IDIOMA) = 'PT_BR' THEN
         IF NRDIASEMANA = 1 THEN
          RETURN TO_CHAR(NRSEMANA) || 'º DOM';
         ELSIF NRDIASEMANA = 2 THEN
          RETURN TO_CHAR(NRSEMANA) || 'º SEG';
         ELSIF NRDIASEMANA = 3 THEN
          RETURN TO_CHAR(NRSEMANA) || 'º TER';
         ELSIF NRDIASEMANA = 4 THEN
          RETURN TO_CHAR(NRSEMANA) || 'º QUA';
         ELSIF NRDIASEMANA = 5 THEN
          RETURN TO_CHAR(NRSEMANA) || 'º QUI';
         ELSIF NRDIASEMANA = 6 THEN           
          RETURN TO_CHAR(NRSEMANA) || 'º SEX';
         ELSIF NRDIASEMANA = 7 THEN
          RETURN TO_CHAR(NRSEMANA) || 'º SAB';
         END IF;
      END IF;
      RETURN NULL;
   END;
BEGIN
   -- Percorre todas as células do cardápio
   FOR C_COMP IN
   (SELECT TO_CHAR((D.NRSEMANA - 1) * 7 + D.NRDIASEMANA) AS DIA,
           D.NRSEMANA, D.NRDIASEMANA,
           T.NMTIPOPRAT || ' (' || NVL(C.DSCOMPLEMENTO, ' ') || ')' AS DESCRICAO,
           C.IDCLASSIFICACAO, COMP.NRCOMPCARDTRAB, D.QTCOMENSAIS,
           P.CDFILAUXPRAT, P.CDPRATO, P.CDPRATO || ' - ' || P.NMPRATO AS NMPRATO, 
           P.IDATIVO           
      FROM DIACARDTRAB D
           INNER JOIN CONFIGCARDTRAB C ON C.NRCARDAPIOTRAB = D.NRCARDAPIOTRAB
           INNER JOIN TIPOPRAT T ON T.CDTIPOPRAT = C.CDTIPOPRAT
           LEFT JOIN COMPCARDTRAB COMP ON COMP.NRCARDAPIOTRAB = D.NRCARDAPIOTRAB AND
                                          COMP.NRDIACARDTRAB = D.NRDIACARDTRAB AND
                                          COMP.NRCONFIGCARDTRAB = C.NRCONFIGCARDTRAB
           LEFT JOIN PRATO P ON P.CDFILAUXPRAT = COMP.CDFILAUXPRAT AND
                                P.CDPRATO = COMP.CDPRATO
     WHERE D.NRCARDAPIOTRAB = P_NRCARDAPIOTRAB
       AND C.NRCARDAPIOTRAB = P_NRCARDAPIOTRAB) LOOP

      -- Se não possui prato na coluna alimentar em um dia que foi solicitado na proposta comercial
      IF (C_COMP.QTCOMENSAIS > 0) AND (C_COMP.IDCLASSIFICACAO = 'ALIMENTAR') AND (C_COMP.NRCOMPCARDTRAB IS NULL) THEN
         -- Dia __PARAM0__ do tipo de prato __PARAM1__ não possui prato
         I_L(MSG('TCOPROC_CARDTRAB_N_POSSUI_PRATO', NOME_DIA(C_COMP.NRSEMANA, C_COMP.NRDIASEMANA), C_COMP.DESCRICAO));
      END IF;

      -- Verifica se o prato está ativo
      IF (C_COMP.IDATIVO = 'N') THEN
         -- Prato __PARAM0__ está inativo
         I_L(MSG('TCOPROC_PRATO_INATIVO', C_COMP.NMPRATO));
      END IF;

      -- Verifica se os produtos estão inativos ou com custo zero      
      FOR C_PRODUTOS IN
      (
         SELECT R.CDPRODUTO, P.IDPRODATIVPR, P.CDARVPROD || ' - ' || P.NMPRODUTO AS NMPRODUTO
           FROM RECEPRATCARDTRAB R
                INNER JOIN PRODUTO P ON P.CDPRODUTO = R.CDPRODUTO
          WHERE R.NRCARDAPIOTRAB = P_NRCARDAPIOTRAB
            AND R.CDFILAUXPRAT = C_COMP.CDFILAUXPRAT
            AND R.CDPRATO = C_COMP.CDPRATO
      ) LOOP
         -- Se produto sem custo
         IF CUSTO_PROD_CARDTRAB(P_NRCARDAPIOTRAB, C_PRODUTOS.CDPRODUTO) = 0 THEN
            -- Produto __PARAM0__ do prato __PARAM1__ não possui custo
            I_L(MSG('TCOPROC_PRODUTO_SEM_CUSTO_PRATO', C_PRODUTOS.NMPRODUTO, C_COMP.NMPRATO));
         END IF;
         -- Se produto inativo
         IF C_PRODUTOS.IDPRODATIVPR = 'N' THEN
            -- Produto __PARAM0__ do prato __PARAM1__ está inativo
            I_L(MSG('TCOPROC_PRODUTO_INATIVO_PRATO', C_PRODUTOS.NMPRODUTO, C_COMP.NMPRATO));
         END IF;
      END LOOP;
      
   END LOOP;
END;
/


CREATE OR REPLACE FUNCTION COMPLEMENTARA_CARDBASE
(P_NRCARDAPIOBASE IN NUMBER) RETURN VARCHAR2
AS
   V_CARDAPIOSB VARCHAR2(1000);
BEGIN
   V_CARDAPIOSB := '';
   FOR C_CARDS IN
   (SELECT CBCOMPL.CDCARDAPIOBASE
      FROM CARDAPIOBASE C      
           INNER JOIN CARDCOMPLCARDBASE CCOMPL ON CCOMPL.NRCARDAPIOBASE = C.NRCARDAPIOBASE
           INNER JOIN CARDAPIOBASE CBCOMPL ON CBCOMPL.NRCARDAPIOBASE = CCOMPL.NRCARDAPIOBASECOMPL
     WHERE C.NRCARDAPIOBASE = P_NRCARDAPIOBASE
     ORDER BY CBCOMPL.CDCARDAPIOBASE
   ) LOOP
      --Separador de valores
      IF LENGTH(V_CARDAPIOSB) > 0 THEN
         V_CARDAPIOSB := V_CARDAPIOSB || ', ';
      END IF;
      -- Terminador caso limite tenha sido atingido
      IF LENGTH(V_CARDAPIOSB) + LENGTH(C_CARDS.CDCARDAPIOBASE) > 1000 THEN         
         V_CARDAPIOSB := V_CARDAPIOSB || SUBSTR(C_CARDS.CDCARDAPIOBASE, 1, 995) || '(...)';
      ELSE
         V_CARDAPIOSB := V_CARDAPIOSB || C_CARDS.CDCARDAPIOBASE;
      END IF;
   END LOOP;
   RETURN V_CARDAPIOSB;
END;
/


CREATE OR REPLACE PROCEDURE TROCAPRATO_CARDBASE
(
P_NRCARDAPIOBASE NUMBER,
P_NRCARDAPIOTRAB NUMBER,
P_NRCOMPCARDTRAB NUMBER,
P_CDREGIAO VARCHAR2,
P_NRORG NUMBER,
P_CDOPERADOR VARCHAR2
)
AS
	V_NRSEMANA NUMBER;
	V_NRDIASEMANA NUMBER;
	V_NRDIACARDBASE NUMBER;
	V_NRCONFIGCARDBASE NUMBER;
	V_NRCOMPCARDBASE NUMBER;
	V_CDFILAUXPRAT VARCHAR2(4);
	V_CDPRATO VARCHAR2(10);
	V_NRPRATCOMPCARDBASE NUMBER;
	V_NRREGIAOPRATCARDBASE NUMBER;
BEGIN
	SELECT C.CDFILAUXPRAT, C.CDPRATO, D.NRSEMANA, D.NRDIASEMANA, CNF.NRCONFIGCARDBASE
	  INTO V_CDFILAUXPRAT, V_CDPRATO, V_NRSEMANA, V_NRDIASEMANA, V_NRCONFIGCARDBASE
	  FROM COMPCARDTRAB C
	       INNER JOIN DIACARDTRAB D ON D.NRDIACARDTRAB = C.NRDIACARDTRAB
	       INNER JOIN CONFIGCARDTRAB CNF ON CNF.NRCONFIGCARDTRAB = C.NRCONFIGCARDTRAB
	 WHERE C.NRCOMPCARDTRAB = P_NRCOMPCARDTRAB
	   AND C.NRCARDAPIOTRAB = P_NRCARDAPIOTRAB;

	IF (V_NRCONFIGCARDBASE IS NOT NULL) THEN
		SELECT MAX(NRDIACARDBASE)
		  INTO V_NRDIACARDBASE
		  FROM DIACARDBASE
		 WHERE NRCARDAPIOBASE = P_NRCARDAPIOBASE
		   AND NRSEMANA = V_NRSEMANA
		   AND NRDIASEMANA = V_NRDIASEMANA;

		IF V_NRDIACARDBASE IS NOT NULL THEN
			SELECT MAX(NRCOMPCARDBASE)
			  INTO V_NRCOMPCARDBASE
			  FROM COMPCARDBASE
			 WHERE NRCARDAPIOBASE = P_NRCARDAPIOBASE
			   AND NRDIACARDBASE = V_NRDIACARDBASE
			   AND NRCONFIGCARDBASE = V_NRCONFIGCARDBASE;

			IF (V_NRCOMPCARDBASE IS NOT NULL) THEN
				-- Verifica se o prato informado já está no cardápio
				SELECT MAX(NRPRATCOMPCARDBASE)
				  INTO V_NRPRATCOMPCARDBASE
				  FROM PRATCOMPCARDBASE
				 WHERE NRCOMPCARDBASE = V_NRCOMPCARDBASE
				   AND CDFILAUXPRAT = V_CDFILAUXPRAT
				   AND CDPRATO = V_CDPRATO;
				-- inclui caso o prato ainda não esteja no cardápio
				IF V_NRPRATCOMPCARDBASE IS NULL THEN
					V_NRPRATCOMPCARDBASE := TO_NUMBER(RETORNA_NOVO_CODIGO('PRATCOMPCARDBASE', 1));

		            INSERT INTO PRATCOMPCARDBASE
		            (NRPRATCOMPCARDBASE, NRCOMPCARDBASE,
		             CDFILAUXPRAT, CDPRATO, IDPRATOEXIBICAO,
		             NRORG, NRORGINCLUSAO, NRORGULTATU,
		             CDOPERINCLUSAO, CDOPERULTATU,
		             DTINCLUSAO, DTULTATU)
		            VALUES
		            (V_NRPRATCOMPCARDBASE, V_NRCOMPCARDBASE,
		             V_CDFILAUXPRAT, V_CDPRATO, 'N',
		             P_NRORG, P_NRORG, P_NRORG,
		             P_CDOPERADOR, P_CDOPERADOR,
		             SYSDATE, SYSDATE);
				END IF;

				-- Apaga a região do prato que a atende
				FOR C_REGIAO IN
				(
					SELECT NRREGIAOPRATCARDBASE				  
					  FROM PRATCOMPCARDBASE P
					       INNER JOIN REGIAOPRATCARDBASE R ON P.NRPRATCOMPCARDBASE = R.NRPRATCOMPCARDBASE
					 WHERE P.NRCOMPCARDBASE = V_NRCOMPCARDBASE
					   AND CDREGIAO = P_CDREGIAO
				) LOOP
					DELETE FROM REGIAOPRATCARDBASE WHERE NRREGIAOPRATCARDBASE = C_REGIAO.NRREGIAOPRATCARDBASE;										
				END LOOP;

				-- Limpa pratos que não possuem região vinculada
				FOR C_PRATOS IN
				(
					SELECT NRPRATCOMPCARDBASE
					  FROM PRATCOMPCARDBASE P
					 WHERE P.NRCOMPCARDBASE = V_NRCOMPCARDBASE
					   AND P.NRPRATCOMPCARDBASE <> V_NRPRATCOMPCARDBASE
					   AND NOT EXISTS
					   (
					      SELECT 1
					        FROM REGIAOPRATCARDBASE R
					       WHERE R.NRPRATCOMPCARDBASE = P.NRPRATCOMPCARDBASE
					   )
				) LOOP
					DELETE FROM PRATCOMPCARDBASE WHERE NRPRATCOMPCARDBASE = C_PRATOS.NRPRATCOMPCARDBASE;
				END LOOP;

				-- Indica que a região é atendida pelo prato substituído.
				V_NRREGIAOPRATCARDBASE := TO_NUMBER(RETORNA_NOVO_CODIGO('REGIAOPRATCARDBASE', 1));

				INSERT INTO REGIAOPRATCARDBASE
				(NRREGIAOPRATCARDBASE, NRPRATCOMPCARDBASE, CDREGIAO,
				NRORG, NRORGINCLUSAO, NRORGULTATU,
				CDOPERINCLUSAO, CDOPERULTATU,
				DTINCLUSAO, DTULTATU)
				VALUES				
				(V_NRREGIAOPRATCARDBASE, V_NRPRATCOMPCARDBASE, P_CDREGIAO,
				P_NRORG, P_NRORG, P_NRORG,
				P_CDOPERADOR, P_CDOPERADOR,
				SYSDATE, SYSDATE);

			END IF;
		END IF;

	END IF;	
	RETURN;
END;
/


CREATE OR REPLACE PROCEDURE DELETA_CARDTRAB
(
	P_NRCARDAPIOTRAB NUMBER
)
AS
BEGIN
	-- Receitas
	DELETE FROM RECEPRATCARDTRAB
	 WHERE NRCARDAPIOTRAB = P_NRCARDAPIOTRAB;

	-- Produtos
	DELETE FROM PRODUTOCARDTRAB
	 WHERE NRCARDAPIOTRAB = P_NRCARDAPIOTRAB;
	-- Dias 
	FOR C_DIAS IN
	(
		SELECT NRDIACARDTRAB
		  FROM DIACARDTRAB
		 WHERE NRCARDAPIOTRAB = P_NRCARDAPIOTRAB		 
	) LOOP
		-- Configuração
		FOR C_CNF IN
		(
			SELECT NRCONFIGCARDTRAB
			  FROM CONFIGCARDTRAB
			 WHERE NRCARDAPIOTRAB = P_NRCARDAPIOTRAB			 
		) LOOP
			-- Composição
			FOR C_COMP IN
			(
				SELECT NRCOMPCARDTRAB
				  FROM COMPCARDTRAB
				 WHERE NRCARDAPIOTRAB = P_NRCARDAPIOTRAB
				   AND NRDIACARDTRAB = C_DIAS.NRDIACARDTRAB
				   AND NRCONFIGCARDTRAB = C_CNF.NRCONFIGCARDTRAB
			) LOOP
				DELETE FROM COMPCARDTRAB
				 WHERE NRCOMPCARDTRAB = C_COMP.NRCOMPCARDTRAB;
			END LOOP;
			
		END LOOP;		
	END LOOP;

	DELETE FROM DIACARDTRAB
	 WHERE NRCARDAPIOTRAB = P_NRCARDAPIOTRAB;

	DELETE FROM CONFIGCARDTRAB
	  WHERE NRCARDAPIOTRAB = P_NRCARDAPIOTRAB;

	DELETE FROM CARDAPIOTRAB	
	 WHERE NRCARDAPIOTRAB = P_NRCARDAPIOTRAB;
END;
/


CREATE OR REPLACE PROCEDURE DUPLICA_SERVICOPROPCOM
(
	P_NRSERVICOPROPCOM NUMBER,
	P_NRNOVAVERSAOPROPCOM NUMBER,
	P_NRORG NUMBER,
	P_CDOPERADOR VARCHAR2
)
AS
	V_NRSERVICOPROPCOM NUMBER;
	V_NRDETALHESERVPROPCOM NUMBER;
	V_NRDETALHESERVPROPCOMNOVO NUMBER;
   V_NRSERVICOPROPCOMCOMPL NUMBER;
   V_NRSERVICOPROPCOMCOMPLNOVO NUMBER;
   V_NRSERVICOPROPOSTA NUMBER;
   V_NRPADRAOQUALIDADE NUMBER;
   V_NRTIPOPUBLICO NUMBER;
   V_NRCARDAPIOTRAB NUMBER;
BEGIN	
   -- Busca as informações do serviço a duplicar
	SELECT MAX(S.NRDETALHESERVPROPCOM), MAX(S.NRSERVICOPROPCOMCOMPL),
          MAX(S.NRSERVICOPROPOSTA), MAX(S.NRPADRAOQUALIDADE), MAX(S.NRTIPOPUBLICO),
          MAX(D.NRCARDAPIOTRAB)
	  INTO V_NRDETALHESERVPROPCOM, V_NRSERVICOPROPCOMCOMPL,
          V_NRSERVICOPROPOSTA, V_NRPADRAOQUALIDADE, V_NRTIPOPUBLICO,
          V_NRCARDAPIOTRAB
	  FROM SERVICOPROPCOM S
          INNER JOIN DETALHESERVPROPCOM D ON D.NRDETALHESERVPROPCOM = S.NRDETALHESERVPROPCOM
	 WHERE S.NRSERVICOPROPCOM = P_NRSERVICOPROPCOM;

   -- Caso seja um serviço complementar, verifica na nova versão quem ele complementa
   IF V_NRSERVICOPROPCOMCOMPL IS NOT NULL THEN
      SELECT MAX(NRSERVICOPROPCOM)
        INTO V_NRSERVICOPROPCOMCOMPLNOVO
        FROM SERVICOPROPCOM
       WHERE NRVERSAOPROPCOM = P_NRNOVAVERSAOPROPCOM
         AND NRSERVICOPROPOSTA = V_NRSERVICOPROPOSTA
         AND NRPADRAOQUALIDADE = V_NRPADRAOQUALIDADE
         AND NRTIPOPUBLICO = V_NRTIPOPUBLICO;
   END IF; 

   /* Duplica estrutura do detalhe do serviço. Novo detalhe gerado estará apontando para o detalhe de origem
   ele é movido ao final da rotina para o serviço de destino*/
	IF(V_NRDETALHESERVPROPCOM IS NOT NULL) THEN
		COPIA_DETALHESERVPROPCOM(V_NRDETALHESERVPROPCOM, 'N', P_CDOPERADOR, P_NRORG, V_NRDETALHESERVPROPCOMNOVO);
	END IF;
   
   --Insere a cópia do serviço na nova versão
   V_NRSERVICOPROPCOM := TO_NUMBER(RETORNA_NOVO_CODIGO('SERVICOPROPCOM', 1));

   INSERT INTO SERVICOPROPCOM
   (
      NRSERVICOPROPCOM, NRVERSAOPROPCOM,
      NRSERVICOPROPOSTA, NRPADRAOQUALIDADE, NRTIPOPUBLICO,      
      IDSERVICOPROPCOM,
      NRDETALHESERVPROPCOM, NRSERVICOPROPCOMCOMPL,
      QTSEGSEX, QTSABADO, QTDOMFERI, 
      QTTOTDIAS, QTTURNOS, QTTOTREFEICOES,
      NRCARDAPIOBASE,
      NRORG, NRORGINCLUSAO, NRORGULTATU,
      DTINCLUSAO, DTULTATU,
      CDOPERINCLUSAO, CDOPERULTATU
   )
   SELECT V_NRSERVICOPROPCOM, P_NRNOVAVERSAOPROPCOM,
          S.NRSERVICOPROPOSTA, S.NRPADRAOQUALIDADE, S.NRTIPOPUBLICO,           
          CASE WHEN V_NRCARDAPIOTRAB IS NULL THEN 'PENDENTE' ELSE 'CALCULADO' END,
          V_NRDETALHESERVPROPCOMNOVO, V_NRSERVICOPROPCOMCOMPLNOVO,
          S.QTSEGSEX, S.QTSABADO, S.QTDOMFERI, 
      	 S.QTTOTDIAS, S.QTTURNOS, S.QTTOTREFEICOES,
      	 S.NRCARDAPIOBASE,
      	 P_NRORG, P_NRORG, P_NRORG,
      	 SYSDATE, SYSDATE,
      	 P_CDOPERADOR, P_CDOPERADOR
     FROM SERVICOPROPCOM S
    WHERE S.NRSERVICOPROPCOM = P_NRSERVICOPROPCOM;

   -- Aponta o detalhe gerado para o serviço duplicado.
   UPDATE DETALHESERVPROPCOM
      SET NRSERVICOPROPCOM = V_NRSERVICOPROPCOM
    WHERE NRDETALHESERVPROPCOM = V_NRDETALHESERVPROPCOMNOVO;
END;
/


CREATE OR REPLACE PROCEDURE DUPLICA_VERSAOPROPCOM
(	
	P_NRVERSAOPROPCOM NUMBER,
	P_NRORG NUMBER,
	P_CDOPERADOR VARCHAR2
)
AS
	V_NRPROPOSTACOMERCIAL NUMBER;	
	V_NRVERSAOPROPCOM NUMBER;
	V_CDVERSAOPROPCOM VARCHAR2(10);
BEGIN
	SELECT MAX(NRPROPOSTACOMERCIAL)
	  INTO V_NRPROPOSTACOMERCIAL
	  FROM VERSAOPROPCOM
	 WHERE NRVERSAOPROPCOM = P_NRVERSAOPROPCOM;

	IF(SIT_PROPCOMERCIAL(V_NRPROPOSTACOMERCIAL) = 'PENDENTE') THEN
		-- Busca o último número de versão
		SELECT MAX(CDVERSAOPROPCOM)
		  INTO V_CDVERSAOPROPCOM
		  FROM VERSAOPROPCOM
		 WHERE NRPROPOSTACOMERCIAL = V_NRPROPOSTACOMERCIAL;

		BEGIN
			V_CDVERSAOPROPCOM := LPAD(TO_CHAR(TO_NUMBER(NVL(V_CDVERSAOPROPCOM, 0)) + 1), 3, '0');
		EXCEPTION			
			WHEN OTHERS THEN
			   V_CDVERSAOPROPCOM := '001';
		END;

		-- Insere nova versão
		V_NRVERSAOPROPCOM := TO_NUMBER(RETORNA_NOVO_CODIGO('VERSAOPROPCOM', 1));
		INSERT INTO VERSAOPROPCOM
		(
			NRVERSAOPROPCOM, NRPROPOSTACOMERCIAL, CDVERSAOPROPCOM, 
			NRORG, NRORGINCLUSAO, NRORGULTATU,
			DTINCLUSAO, DTULTATU,
			CDOPERINCLUSAO, CDOPERULTATU
		)
		VALUES
		(
			V_NRVERSAOPROPCOM, V_NRPROPOSTACOMERCIAL, V_CDVERSAOPROPCOM,
			P_NRORG, P_NRORG, P_NRORG,
			SYSDATE, SYSDATE,
			P_CDOPERADOR, P_CDOPERADOR
		);
		
		-- Percorre os serviços da versão de origem
		FOR C_SERV IN
		(
			SELECT NRSERVICOPROPCOM, 
			       CASE WHEN NRSERVICOPROPCOMCOMPL IS NULL THEN 0 ELSE 1 END AS ORDEM
			  FROM SERVICOPROPCOM
			 WHERE NRVERSAOPROPCOM = P_NRVERSAOPROPCOM
			 ORDER BY ORDEM
		) LOOP
			-- Cria cópia dos serviços dentro 
			DUPLICA_SERVICOPROPCOM(C_SERV.NRSERVICOPROPCOM, V_NRVERSAOPROPCOM, P_NRORG, P_CDOPERADOR);
		END LOOP;
	END IF;
END;
/


CREATE OR REPLACE PROCEDURE COPIA_PRATO_CARDBASE
(
   P_NRCARDAPIOBASE IN NUMBER,
	P_NRCOMPCARDBASE IN NUMBER,
	P_NRDIACARDBASEDEST IN NUMBER,
	P_NRCONFIGCARDBASEDEST IN NUMBER,
	P_NRORG IN NUMBER,
	P_CDOPERADOR IN VARCHAR2,
   P_SUBTITUIR IN VARCHAR2 DEFAULT 'S'
)
AS 
   V_QTDE NUMBER;  
   V_NRDIACARDBASEORI NUMBER;
   V_NRCONFIGCARDBASEORI NUMBER;
   V_NRCOMPCARDBASEDEST NUMBER;
   V_NRPRATCOMPCARDBASE NUMBER;   
   V_NRREGIAOPRATCARDBASE NUMBER;
BEGIN
   SELECT MAX(NRDIACARDBASE), MAX(NRCONFIGCARDBASE)
     INTO V_NRDIACARDBASEORI, V_NRCONFIGCARDBASEORI
     FROM COMPCARDBASE
    WHERE NRCOMPCARDBASE = P_NRCOMPCARDBASE
      AND NRCARDAPIOBASE = P_NRCARDAPIOBASE;
   
   IF V_NRDIACARDBASEORI IS NOT NULL AND 
      V_NRCONFIGCARDBASEORI IS NOT NULL AND
      (V_NRDIACARDBASEORI <> P_NRDIACARDBASEDEST OR 
      V_NRCONFIGCARDBASEORI <> P_NRCONFIGCARDBASEDEST) THEN
      
      SELECT MAX(NRCOMPCARDBASE)
        INTO V_NRCOMPCARDBASEDEST
        FROM COMPCARDBASE
       WHERE NRCARDAPIOBASE = P_NRCARDAPIOBASE
         AND NRDIACARDBASE = P_NRDIACARDBASEDEST
         AND NRCONFIGCARDBASE = P_NRCONFIGCARDBASEDEST;

      IF V_NRCOMPCARDBASEDEST IS NOT NULL THEN

         /*Se não pode substituir sai da função*/
         IF P_SUBTITUIR = 'N' THEN
            RETURN;
         ELSE
            DELETE FROM REGIAOPRATCARDBASE R
             WHERE EXISTS (SELECT 1
                             FROM PRATCOMPCARDBASE P
                            WHERE P.NRPRATCOMPCARDBASE = R.NRPRATCOMPCARDBASE
                              AND P.NRCOMPCARDBASE = V_NRCOMPCARDBASEDEST);
            
            DELETE FROM PRATCOMPCARDBASE
             WHERE NRCOMPCARDBASE = V_NRCOMPCARDBASEDEST;
         END IF;
      ELSE      
         V_NRCOMPCARDBASEDEST := TO_NUMBER(RETORNA_NOVO_CODIGO('COMPCARDBASE', 1));
         INSERT INTO COMPCARDBASE
         (NRCOMPCARDBASE, NRCARDAPIOBASE, NRDIACARDBASE, NRCONFIGCARDBASE,
          NRORG, NRORGINCLUSAO, NRORGULTATU,
          CDOPERINCLUSAO, CDOPERULTATU,
          DTINCLUSAO, DTULTATU)
         VALUES
         (V_NRCOMPCARDBASEDEST, P_NRCARDAPIOBASE, P_NRDIACARDBASEDEST, P_NRCONFIGCARDBASEDEST,
          P_NRORG, P_NRORG, P_NRORG,
          P_CDOPERADOR, P_CDOPERADOR,
          SYSDATE, SYSDATE);         
      END IF;

      SELECT COUNT(1)
        INTO V_QTDE
        FROM PRATCOMPCARDBASE
       WHERE NRCOMPCARDBASE = P_NRCOMPCARDBASE;

      IF V_QTDE > 0 THEN
         V_NRPRATCOMPCARDBASE := TO_NUMBER(RETORNA_NOVO_CODIGO('PRATCOMPCARDBASE', V_QTDE));

         INSERT INTO PRATCOMPCARDBASE
         (NRPRATCOMPCARDBASE, NRCOMPCARDBASE, 
          CDFILAUXPRAT, CDPRATO, IDPRATOEXIBICAO,
          NRORG, NRORGINCLUSAO, NRORGULTATU,
          CDOPERINCLUSAO, CDOPERULTATU,
          DTINCLUSAO, DTULTATU)
         SELECT V_NRPRATCOMPCARDBASE + (ROW_NUMBER() OVER (ORDER BY P.NRPRATCOMPCARDBASE) - 1),
                V_NRCOMPCARDBASEDEST,
                P.CDFILAUXPRAT, P.CDPRATO, P.IDPRATOEXIBICAO,
                P_NRORG, P_NRORG, P_NRORG,
                P_CDOPERADOR, P_CDOPERADOR,
                SYSDATE, SYSDATE
           FROM PRATCOMPCARDBASE P                
          WHERE P.NRCOMPCARDBASE = P_NRCOMPCARDBASE
          ORDER BY P.NRPRATCOMPCARDBASE; --Importante para inclusão múltipla de região
      END IF;

      -- Regiões
      SELECT COUNT(1)
        INTO V_QTDE
        FROM REGIAOPRATCARDBASE R
             INNER JOIN PRATCOMPCARDBASE P ON P.NRPRATCOMPCARDBASE = R.NRPRATCOMPCARDBASE
       WHERE P.NRCOMPCARDBASE = P_NRCOMPCARDBASE;

      IF V_QTDE > 0 THEN
         V_NRREGIAOPRATCARDBASE := TO_NUMBER(RETORNA_NOVO_CODIGO('REGIAOPRATCARDBASE', V_QTDE));

         INSERT INTO REGIAOPRATCARDBASE
         (NRREGIAOPRATCARDBASE, NRPRATCOMPCARDBASE, CDREGIAO,
          NRORG, NRORGINCLUSAO, NRORGULTATU,
          CDOPERINCLUSAO, CDOPERULTATU,
          DTINCLUSAO, DTULTATU)
         SELECT V_NRREGIAOPRATCARDBASE + (ROW_NUMBER() OVER (ORDER BY R.NRREGIAOPRATCARDBASE) - 1),
                PD.NRPRATCOMPCARDBASEDEST,
                R.CDREGIAO,
                P_NRORG, P_NRORG, P_NRORG,
                P_CDOPERADOR, P_CDOPERADOR,
                SYSDATE, SYSDATE
           FROM REGIAOPRATCARDBASE R
                INNER JOIN PRATCOMPCARDBASE P ON P.NRPRATCOMPCARDBASE = R.NRPRATCOMPCARDBASE                
                INNER JOIN 
                (SELECT P.NRPRATCOMPCARDBASE,
                        V_NRPRATCOMPCARDBASE + (ROW_NUMBER() OVER (ORDER BY P.NRPRATCOMPCARDBASE) - 1) AS NRPRATCOMPCARDBASEDEST
                   FROM PRATCOMPCARDBASE P
                  WHERE P.NRCOMPCARDBASE = P_NRCOMPCARDBASE
                  ORDER BY P.NRPRATCOMPCARDBASE) PD ON PD.NRPRATCOMPCARDBASE = P.NRPRATCOMPCARDBASE
          WHERE P.NRCOMPCARDBASE = P_NRCOMPCARDBASE
          ORDER BY R.NRREGIAOPRATCARDBASE;
      END IF;
   END IF;       
END;
/


CREATE OR REPLACE PROCEDURE DELETA_SERVICOPROPCOM
(
  P_NRSERVICOPROPCOM IN NUMBER
)
AS  
  V_IDSITUACAO VARCHAR2(30);
BEGIN
   V_IDSITUACAO := SIT_SERVICOPROPCOM(P_NRSERVICOPROPCOM);

   IF V_IDSITUACAO NOT IN ('PENDENTE', 'CALCULADO') THEN
      RAISE_APPLICATION_ERROR(-20000, MSG('TCOPROC_SERVPROPCOMERCIAL_N_PODE_EXCLUIR'));
   END IF;

   -- Histórico de notificações
   DELETE FROM HISTNOTIFPROPCOM
    WHERE NRSERVICOPROPCOM = P_NRSERVICOPROPCOM;

   -- limpa detalhes do serviço
   UPDATE SERVICOPROPCOM SET NRDETALHESERVPROPCOM = NULL, NRDETSERVPROPCOMPLAN = NULL
    WHERE NRSERVICOPROPCOM = P_NRSERVICOPROPCOM;

   -- Configuração de serviço
   DELETE FROM CONFIGSERVPROPCOM C
    WHERE EXISTS (
             SELECT 1
               FROM DETALHESERVPROPCOM D
              WHERE D.NRDETALHESERVPROPCOM = C.NRDETALHESERVPROPCOM
          );
   
   -- Configuração de grupo de tipo de prato
   DELETE FROM CONFGRUPOTPPROPCOM C
    WHERE EXISTS (
             SELECT 1
               FROM DETALHESERVPROPCOM D
              WHERE D.NRDETALHESERVPROPCOM = C.NRDETALHESERVPROPCOM
          );
   
   -- Incidências solicitadas
   DELETE FROM INCIDENCIAPROPCOM I
    WHERE EXISTS (
             SELECT 1
               FROM DETALHESERVPROPCOM D
              WHERE D.NRDETALHESERVPROPCOM = I.NRDETALHESERVPROPCOM
          );

   -- Produto
   DELETE FROM PRODUTOPROPCOM P
    WHERE EXISTS (
             SELECT 1
               FROM DETALHESERVPROPCOM D
              WHERE D.NRDETALHESERVPROPCOM = P.NRDETALHESERVPROPCOM
          );

   -- Detalhes do Serviço
   DELETE FROM DETALHESERVPROPCOM
    WHERE NRSERVICOPROPCOM = P_NRSERVICOPROPCOM;

   -- Serviço
   DELETE FROM SERVICOPROPCOM
    WHERE NRSERVICOPROPCOM = P_NRSERVICOPROPCOM;   
END;
/


CREATE OR REPLACE PROCEDURE REPLICA_PRATO_CARDBASE
(
   P_NRCARDAPIOBASE IN NUMBER,
   P_NRCOMPCARDBASE IN NUMBER,
   P_NRORG IN NUMBER,
   P_CDOPERADOR IN VARCHAR2,
   P_DOM IN VARCHAR2,
   P_SEG IN VARCHAR2,
   P_TER IN VARCHAR2,
   P_QUA IN VARCHAR2,
   P_QUI IN VARCHAR2,
   P_SEX IN VARCHAR2,
   P_SAB IN VARCHAR2,
   P_SUBTITUIR IN VARCHAR2 DEFAULT 'S'
)
AS   
   V_NRDIACARDBASEORI NUMBER;
   V_NRSEMANA NUMBER;
   V_NRDIASEMANA NUMBER;
   V_NRCONFIGCARDBASEORI NUMBER;
BEGIN
   SELECT MAX(C.NRDIACARDBASE), MAX(C.NRCONFIGCARDBASE), MAX(D.NRSEMANA), MAX(D.NRDIASEMANA)
     INTO V_NRDIACARDBASEORI, V_NRCONFIGCARDBASEORI, V_NRSEMANA, V_NRDIASEMANA
     FROM COMPCARDBASE C
          INNER JOIN DIACARDBASE D ON D.NRDIACARDBASE = C.NRDIACARDBASE
    WHERE C.NRCOMPCARDBASE = P_NRCOMPCARDBASE
      AND C.NRCARDAPIOBASE = P_NRCARDAPIOBASE;
   
   IF V_NRDIACARDBASEORI IS NOT NULL AND 
      V_NRCONFIGCARDBASEORI IS NOT NULL THEN
      FOR C_DIAS IN
      (
         SELECT NRDIACARDBASE
           FROM DIACARDBASE
          WHERE NRCARDAPIOBASE = P_NRCARDAPIOBASE
            AND ((NRSEMANA <> V_NRSEMANA) OR (NRDIASEMANA <> V_NRDIASEMANA))
            AND ((NRDIASEMANA = 1 AND P_DOM = 'S') OR
                 (NRDIASEMANA = 2 AND P_SEG = 'S') OR
                 (NRDIASEMANA = 3 AND P_TER = 'S') OR
                 (NRDIASEMANA = 4 AND P_QUA = 'S') OR
                 (NRDIASEMANA = 5 AND P_QUI = 'S') OR
                 (NRDIASEMANA = 6 AND P_SEX = 'S') OR
                 (NRDIASEMANA = 7 AND P_SAB = 'S'))
      ) LOOP
         COPIA_PRATO_CARDBASE( P_NRCARDAPIOBASE, P_NRCOMPCARDBASE, C_DIAS.NRDIACARDBASE, V_NRCONFIGCARDBASEORI, P_NRORG, P_CDOPERADOR, P_SUBTITUIR );
      END LOOP;
   END IF;
END;
/


CREATE OR REPLACE PROCEDURE LIMPEZATCO
AS
BEGIN
   /*Limpa LISTA, lista de valores genérica do sistema*/
   DELETE FROM LISTA WHERE DTULTATULIST < TRUNC(SYSDATE - 5);
   /*Limpa LISTAERROS, lista de erros de procedure*/
   DELETE FROM LISTAERROS WHERE DTINCLUSAO < TRUNC(SYSDATE - 5);
   COMMIT;      
   /*Apaga os cardápios de trabalho*/
   FOR C_TRAB IN
   (
      SELECT NRCARDAPIOTRAB
        FROM CARDAPIOTRAB
       WHERE DTINCLUSAO < TRUNC(SYSDATE - 5)
   ) LOOP
      BEGIN
        DELETA_CARDTRAB(C_TRAB.NRCARDAPIOTRAB);
      EXCEPTION
        WHEN OTHERS THEN
          CONTINUE;
      END;
   END LOOP;
   COMMIT;
END;
/

DECLARE
  V_JOB NUMBER;
BEGIN
  FOR C_JOBS IN (SELECT JOB
                   FROM ALL_JOBS
                  WHERE WHAT LIKE '%LIMPEZATCO%') LOOP
    DBMS_JOB.REMOVE(C_JOBS.JOB);
  END LOOP;

  DBMS_JOB.SUBMIT(V_JOB, WHAT => 'BEGIN LIMPEZATCO; END;', 
  NEXT_DATE => TRUNC(SYSDATE + 5), 
  INTERVAL => 'TRUNC(SYSDATE + 5)');
  COMMIT;
END;
/


CREATE OR REPLACE PROCEDURE EFETIVA_SERVICOPROPCOM
(
   P_NRSERVICOPROPCOM IN NUMBER,
   P_CDFILIAL IN VARCHAR2,
   P_CDSERVFILI IN VARCHAR2,
   P_DTINICARD IN DATE,
   P_NUM_MESES IN NUMBER,
   P_CDOPERADOR IN VARCHAR2,
   P_NRORG IN NUMBER,
   P_CDFILIALLOGADA IN VARCHAR2,   
   P_LISTAERROS OUT VARCHAR2
)
AS
   V_QTDE NUMBER;
   V_IDVERSAOPROPCOM VARCHAR2(30);
   V_IDSERVICOPROPCOM VARCHAR2(30);
   V_NRCARDAPIOTRAB NUMBER;   
   V_INSERE_POR_SERVICO VARCHAR2(1);
   V_CDFILAUXPRAT VARCHAR2(4);
   V_SEQ NUMBER;
   V_PAG NUMBER;
   V_NRPORCIONAMENTO NUMBER;
   V_NRGRAMATURACARDBASE NUMBER;
   V_NRDETALHESERVPROPCOM NUMBER;
   V_NRTIPOCONTRATO NUMBER;
   V_NRTIPOPUBLICO NUMBER;
   V_NRPADRAOQUALIDADE NUMBER;
   V_VRCUSTO FLOAT;
   V_I NUMBER;
   V_J NUMBER;
   V_NUM_CARD NUMBER;
   V_NUM_DIAS_CARD NUMBER;
   V_NUM_DIAS_MES NUMBER;
   V_DATA DATE;   
   V_MAX_SEMANA NUMBER;
   V_MAX_DIASEMANA NUMBER;
   V_DIA NUMBER;
   V_SEMANA NUMBER;
   V_DTCUSTO DATE;
   V_NRDIACARDTRAB NUMBER; 
   V_QTCOMENSAIS FLOAT;
   V_NRCARDAPIO VARCHAR2(10);   
   V_IDCARDIAUTIL VARCHAR2(1);
   V_CONTFERIFILI NUMBER;
   V_IDTIPOSERV VARCHAR2(1);
BEGIN
--=========================================================
--=== Validação inicial
--=========================================================
   SELECT COUNT(1), MAX(IDTIPOSERV)
     INTO V_QTDE, V_IDTIPOSERV
     FROM SERVICO S          
    WHERE S.CDFILIAL = P_CDFILIAL
      AND S.CDSERVFILI = P_CDSERVFILI;

   IF V_QTDE = 0 THEN
      -- Operação bloqueada. Serviço de planejamento informado não existe na filial de destino.
      RAISE_APPLICATION_ERROR(-20000, MSG('TCOPROC_SERVICOPLAN_N_EXISTE'));
   ELSIF V_IDTIPOSERV <> 'N' THEN
      -- Operação bloqueada. Serviço de planejamento informado não é do tipo Corporativo(Restaurante).
      RAISE_APPLICATION_ERROR(-20000, MSG('TCOPROC_SERVICOPLAN_N_VALIDO'));
   END IF;

   SELECT MAX(V.IDVERSAOPROPCOM), MAX(S.IDSERVICOPROPCOM), MAX(D.NRCARDAPIOTRAB), MAX(S.NRDETALHESERVPROPCOM),
          MAX(P.NRTIPOCONTRATO), MAX(S.NRTIPOPUBLICO), MAX(S.NRPADRAOQUALIDADE),
          MAX(CUSTO_PERC_CARDTRAB(C.NRCARDAPIOTRAB)), MAX(C.DTCUSTO)
     INTO V_IDVERSAOPROPCOM, V_IDSERVICOPROPCOM, V_NRCARDAPIOTRAB, V_NRDETALHESERVPROPCOM,
          V_NRTIPOCONTRATO, V_NRTIPOPUBLICO, V_NRPADRAOQUALIDADE, 
          V_VRCUSTO, V_DTCUSTO
     FROM SERVICOPROPCOM S
          INNER JOIN VERSAOPROPCOM V ON V.NRVERSAOPROPCOM = S.NRVERSAOPROPCOM
          INNER JOIN PROPOSTACOMERCIAL P ON P.NRPROPOSTACOMERCIAL = V.NRPROPOSTACOMERCIAL
          INNER JOIN DETALHESERVPROPCOM D ON D.NRDETALHESERVPROPCOM = S.NRDETALHESERVPROPCOM
          INNER JOIN CARDAPIOTRAB C ON C.NRCARDAPIOTRAB = D.NRCARDAPIOTRAB
    WHERE S.NRSERVICOPROPCOM = P_NRSERVICOPROPCOM;

    IF V_NRCARDAPIOTRAB IS NULL THEN
       -- Operação bloqueada. Serviço da proposta informado não é existe ou não foi calculado.
       RAISE_APPLICATION_ERROR(-20000, MSG('TCOPROC_SERVICOPROP_N_EXISTE_OU_N_CALC'));
    END IF;

   IF V_IDVERSAOPROPCOM <> 'APROVADA' THEN
      -- Operação bloqueada. Simulação vinculada ao serviço não está aprovada.
      RAISE_APPLICATION_ERROR(-20000, MSG('TCOPROC_VERSAO_SERV_N_APROVADA'));
   END IF;

   IF V_IDSERVICOPROPCOM = 'EFETIVADO' THEN
      -- Operação bloqueada. Serviço da proposta já foi efetivado.
      RAISE_APPLICATION_ERROR(-20000, MSG('TCOPROC_SERVICOPROP_JA_EFETIVADO'));
   END IF;

   SELECT COUNT(1)
     INTO V_QTDE
     FROM CARDADIA
    WHERE CDFILIAL = P_CDFILIAL
      AND CDSERVFILI = P_CDSERVFILI
      AND DTCARDAPIO BETWEEN P_DTINICARD AND ADD_MONTHS(P_DTINICARD, (NVL(P_NUM_MESES, 1) - 1));

   IF V_QTDE > 0 THEN
      -- Operação bloqueada. Serviço de planejamento informado já possui cardápio cadastrado no sistema para data informada.
      RAISE_APPLICATION_ERROR(-20000, MSG('TCOPROC_SERVPLAN_JA_POSSUI_CARD'));
   END IF;

   -- Valida informações do cardápio conforme
   VALIDA_CARDTRAB(V_NRCARDAPIOTRAB,P_NRORG, P_CDOPERADOR, P_CDFILIALLOGADA, P_LISTAERROS);
   IF P_LISTAERROS IS NOT NULL THEN
      RETURN;
   END IF;

   /* Verifica se o parâmetro "Verifica custo padrão na Montagem do Cardapio" está marcado */
   SELECT MAX(IDCARDIAUTIL)
     INTO V_IDCARDIAUTIL
     FROM PARAMPLANEJA
    WHERE CDFILIAL = P_CDFILIAL;   
--=========================================================
--=== Revisão dos pratos na filial
--=========================================================
   FOR C_PRATOS IN
   (
      SELECT DISTINCT P.CDFILAUXPRAT, P.CDPRATO, P.IDATIVO
        FROM RECEPRATCARDTRAB R
             INNER JOIN PRATO P ON P.CDFILAUXPRAT = R.CDFILAUXPRAT AND
                                   P.CDPRATO = R.CDPRATO
             INNER JOIN PRODUTO PT ON PT.CDPRODUTO = R.CDPRODUTO
       WHERE NRCARDAPIOTRAB = V_NRCARDAPIOTRAB
   ) LOOP
      V_INSERE_POR_SERVICO := 'N';

      V_CDFILAUXPRAT := 'P';
      IF C_PRATOS.CDFILAUXPRAT <> 'P' THEN
         V_CDFILAUXPRAT := P_CDFILIAL;
      END IF;
      -- Verifica se : Existe receita na filial
      SELECT COUNT(1)
        INTO V_QTDE
        FROM RECEFILI
       WHERE CDFILAUXPRAT = V_CDFILAUXPRAT
         AND CDPRATO = C_PRATOS.CDPRATO
         AND CDFILIAL = P_CDFILIAL;

      IF V_QTDE > 0 THEN
         SELECT COUNT(1)
           INTO V_QTDE
           FROM (
                  SELECT R.CDPRODUTO,
                         R.QTPRODRECCARDTRAB AS QTPRONTA,
                         R.VRPEFATCOCCARDTRAB AS VRPEFATCOC,
                         R.VRPEFATCORCARDTRAB AS VRPEFATCOR,
                         R.SGUNIDADE,                         
                         R.QTBRUTACARDTRABUNR AS QTBRUTA,
                         R.IDPRODBASECARDTRAB AS IDPRODBASE,
                         R.IDQTDEFIXCARDTRAB AS IDQTDEFIX
                    FROM RECEPRATCARDTRAB R 
                   WHERE R.NRCARDAPIOTRAB = V_NRCARDAPIOTRAB
                     AND R.CDFILAUXPRAT = V_CDFILAUXPRAT
                     AND R.CDPRATO = C_PRATOS.CDPRATO
                ) RC
                FULL OUTER JOIN
                (
                  SELECT R.CDPRODUTO,
                         NVL(R.QTPRODRECLOC, 0.00) AS QTPRONTA,
                         NVL(R.VRPEFATCOCLO, 0.00) AS VRPEFATCOC,
                         NVL(R.VRPEFATCORLO, 0.00) AS VRPEFATCOR,
                         NVL(R.SGUNIDADE, P.SGUNIDADE) AS SGUNIDADE,
                         NVL(R.QTBRUTALOUNR, 0.00) AS QTBRUTA,
                         NVL(R.IDPRODBASELO, 'N') AS IDPRODBASE,
                         NVL(R.IDQTDEFIXLO, 'N') AS IDQTDEFIX
                    FROM RECEFILI R
                         INNER JOIN PRODUTO P ON P.CDPRODUTO = R.CDPRODUTO
                   WHERE R.CDFILAUXPRAT = V_CDFILAUXPRAT
                     AND R.CDPRATO = C_PRATOS.CDPRATO
                     AND R.CDFILIAL = P_CDFILIAL
                ) RF ON RF.CDPRODUTO = RC.CDPRODUTO
          WHERE RC.CDPRODUTO IS NULL OR
                RF.CDPRODUTO IS NULL OR
                RC.QTPRONTA <> RF.QTPRONTA OR
                --RC.VRPEFATCOC <> RF.VRPEFATCOC OR
                --RC.VRPEFATCOR <> RF.VRPEFATCOR OR
                RC.SGUNIDADE <> RF.SGUNIDADE OR
                RC.QTBRUTA <> RF.QTBRUTA OR
                RC.IDPRODBASE <> RF.IDPRODBASE OR
                RC.IDQTDEFIX <> RF.IDQTDEFIX;
         IF V_QTDE > 0 THEN
            V_INSERE_POR_SERVICO := 'S';
         ELSE
            /* Se o prato na filial já possui receita, e ela é idêntica, 
               segue para a inclusão de outro prato*/
            CONTINUE;
         END IF;
      END IF;

      FOR C_RECEITA IN
      (
         SELECT R.CDPRODUTO,
                R.QTPRODRECCARDTRAB AS QTPRONTA,
                R.VRPEFATCOCCARDTRAB AS VRPEFATCOC,
                R.VRPEFATCORCARDTRAB AS VRPEFATCOR,
                R.SGUNIDADE,                         
                R.QTBRUTACARDTRABUNR AS QTBRUTA,
                R.IDPRODBASECARDTRAB AS IDPRODBASE,
                R.IDQTDEFIXCARDTRAB AS IDQTDEFIX
           FROM RECEPRATCARDTRAB R 
          WHERE R.NRCARDAPIOTRAB = V_NRCARDAPIOTRAB
            AND R.CDFILAUXPRAT = V_CDFILAUXPRAT
            AND R.CDPRATO = C_PRATOS.CDPRATO
      ) LOOP
         IF V_INSERE_POR_SERVICO = 'N' THEN
            -- Insere receita na filial
            INSERT INTO RECEFILI
            (CDFILAUXPRAT, CDPRATO, 
             CDFILIAL, CDPRODUTO,
             QTPRODRECLOC, SGUNIDADE,
             VRPEFATCOCLO, VRPEFATCORLO,
             QTBRUTALOUNR, QTBRUTALO, 
             IDPRODBASELO, IDQTDEFIXLO,
             VRPEFATNUTLO, QTCALCNUTRLO,
             NRORG, NRORGINCLUSAO, NRORGULTATU,
             CDOPERINCLUSAO, CDOPERULTATU,
             DTINCLUSAO, DTULTATU)
            VALUES
            (V_CDFILAUXPRAT, C_PRATOS.CDPRATO,
             P_CDFILIAL, C_RECEITA.CDPRODUTO,
             C_RECEITA.QTBRUTA, C_RECEITA.SGUNIDADE,
             0, 0,
             C_RECEITA.QTBRUTA, C_RECEITA.QTBRUTA,
             C_RECEITA.IDPRODBASE, C_RECEITA.IDQTDEFIX,
             100, C_RECEITA.QTPRONTA,
             P_NRORG, P_NRORG, P_NRORG,
             P_CDOPERADOR, P_CDOPERADOR,
             SYSDATE, SYSDATE);
         ELSE
            -- Insere receita no serviço da filial
            DELETE FROM RECESERV WHERE CDFILAUXPRAT = V_CDFILAUXPRAT AND
                                       CDPRATO = C_PRATOS.CDPRATO AND
                                       CDFILIAL = P_CDFILIAL AND
                                       CDSERVFILI = P_CDSERVFILI;
            INSERT INTO RECESERV
            (CDFILAUXPRAT, CDPRATO, 
             CDFILIAL, CDSERVFILI, CDPRODUTO,
             QTPRODRECSER, SGUNIDADE,
             VRPEFATCOCSE, VRPEFATCORSE,
             QTBRUTASEUNR, QTBRUTASE, 
             IDPRODBASESE, IDQTDEFIXSE,
             VRPEFATNUTSE, QTCALCNUTRSE,
             NRORG, NRORGINCLUSAO, NRORGULTATU,
             CDOPERINCLUSAO, CDOPERULTATU,
             DTINCLUSAO, DTULTATU)
            VALUES
            (V_CDFILAUXPRAT, C_PRATOS.CDPRATO,
             P_CDFILIAL, P_CDSERVFILI, C_RECEITA.CDPRODUTO,
             C_RECEITA.QTPRONTA, C_RECEITA.SGUNIDADE,
             C_RECEITA.VRPEFATCOC, C_RECEITA.VRPEFATCOR,
             C_RECEITA.QTBRUTA, C_RECEITA.QTBRUTA,
             C_RECEITA.IDPRODBASE, C_RECEITA.IDQTDEFIX,
             100, C_RECEITA.QTPRONTA,
             P_NRORG, P_NRORG, P_NRORG,
             P_CDOPERADOR, P_CDOPERADOR,
             SYSDATE, SYSDATE);
         END IF;
      END LOOP;

   END LOOP;
--=========================================================
--=== Substituição da configuração do serviço de destino
--=========================================================
   -- Apagar configuração atual
   DELETE FROM CONFCARD WHERE CDFILIAL = P_CDFILIAL AND
                              CDSERVFILI = P_CDSERVFILI;
   -- Inserir configuração do serviço
   V_SEQ := 1;
   V_PAG := 1;
   FOR C_CONFIGURACAO IN
   (
      SELECT C.CDTIPOPRAT, C.DSCOMPLEMENTO, C.IDCLASSIFICACAO, C.IDTEMPERATURA, T.CDGRTIPOPR
        FROM CONFIGCARDTRAB C
             INNER JOIN TIPOPRAT T ON T.CDTIPOPRAT = C.CDTIPOPRAT
       WHERE C.NRCARDAPIOTRAB = V_NRCARDAPIOTRAB
       ORDER BY C.NRORDEM
   ) LOOP
      SELECT MAX(NRPORCIONAMENTO), MAX(NRGRAMATURACARDBASE)
        INTO V_NRPORCIONAMENTO, V_NRGRAMATURACARDBASE
        FROM CONFGRUPOTPPROPCOM
       WHERE NRDETALHESERVPROPCOM = V_NRDETALHESERVPROPCOM
         AND CDGRTIPOPR = C_CONFIGURACAO.CDGRTIPOPR;

      INSERT INTO CONFCARD
      (CDFILIAL, CDSERVFILI, NRSEQCNFCARD,
       CDTIPOPRAT, IDOPCCNFCARD, 
       IDIMPCNFCARD, NRPAGCNFCARD, 
       VRPERCOMCARD, NRORDCNFCARD,
       DSCOMPLTP, NRPORCIONAMENTO,
       NRGRAMATURACARDBASE, IDCLASSIFICACAO,
       IDTEMPERATURA, NRORG, NRORGULTATU, NRORGINCLUSAO,
       CDOPERINCLUSAO, CDOPERULTATU,
       DTINCLUSAO, DTULTATU)
      VALUES
      (P_CDFILIAL, P_CDSERVFILI, V_SEQ,
       C_CONFIGURACAO.CDTIPOPRAT, 'N',
       'S', V_PAG,
       0, V_SEQ,
       SUBSTR(C_CONFIGURACAO.DSCOMPLEMENTO, 1, 15), V_NRPORCIONAMENTO,
       V_NRGRAMATURACARDBASE, C_CONFIGURACAO.IDCLASSIFICACAO,
       C_CONFIGURACAO.IDTEMPERATURA, P_NRORG, P_NRORG, P_NRORG,
       P_CDOPERADOR, P_CDOPERADOR,
       SYSDATE, SYSDATE);

      V_SEQ := V_SEQ + 1;
      IF MOD(V_SEQ, 2) = 0 THEN
         V_PAG := 1;
      ELSE
         V_PAG := V_PAG + 1;
      END IF;
   END LOOP;

--=========================================================
--=== Informações no serviço de planejamento
--=========================================================
   UPDATE SERVICO
      SET NRTIPOCONTRATO = V_NRTIPOCONTRATO,
          NRTIPOPUBLICO = V_NRTIPOPUBLICO,
          NRPADRAOQUALIDADE = V_NRPADRAOQUALIDADE,
          NRSERVICOPROPCOM = P_NRSERVICOPROPCOM,
          NRORGULTATU = P_NRORG,
          DTULTATU = SYSDATE,
          CDOPERULTATU = P_CDOPERADOR
    WHERE CDFILIAL = P_CDFILIAL
      AND CDSERVFILI = P_CDSERVFILI;
--=========================================================
--=== Criação do cardápio do serviço (1 ou mais)
--=========================================================
   SELECT COUNT(1), MAX(NRSEMANA)
     INTO V_NUM_DIAS_CARD, V_MAX_SEMANA
     FROM DIACARDTRAB
    WHERE NRCARDAPIOTRAB = V_NRCARDAPIOTRAB;

   SELECT MAX(NRDIASEMANA)
     INTO V_MAX_DIASEMANA
     FROM DIACARDTRAB
    WHERE NRCARDAPIOTRAB = V_NRCARDAPIOTRAB
      AND NRSEMANA = V_MAX_SEMANA;

   V_NUM_CARD := P_NUM_MESES;
   IF V_NUM_CARD IS NULL THEN
      V_NUM_CARD := 1;
   END IF;

   FOR V_I IN 1..V_NUM_CARD LOOP
      V_DATA := ADD_MONTHS(P_DTINICARD, (V_I - 1));
      -- Obtém número de dias do mês
      V_NUM_DIAS_MES := 1+TRUNC(LAST_DAY(V_DATA))-TRUNC(V_DATA,'MM');   
      V_SEMANA := 1;
      V_DIA := TO_NUMBER(TO_CHAR(V_DATA, 'D'));

    --=========================================================
    --=== Definição do custo padrão
    --=========================================================
         
      -- Apaga custo existente para o mês
      DELETE FROM CUSTPADR
       WHERE CDFILIAL = P_CDFILIAL
         AND CDSERVFILI = P_CDSERVFILI
         AND DTREFCUSPADR = V_DATA;         
      

      -- Insere o custo percapita do cardápio de trabalho para o mês atual
      INSERT INTO CUSTPADR
      (CDFILIAL, CDSERVFILI, DTREFCUSPADR,
       VRCUSTPADR,
       NRORG, NRORGINCLUSAO, NRORGULTATU,
       CDOPERINCLUSAO, CDOPERULTATU,
       DTINCLUSAO, DTULTATU)
      VALUES
      (P_CDFILIAL, P_CDSERVFILI, V_DATA,
       V_VRCUSTO,
       P_NRORG, P_NRORG,P_NRORG,
       P_CDOPERADOR,P_CDOPERADOR,
       SYSDATE,SYSDATE);

    --=========================================================
    --=== Cabeçalho do Cardápio
    --=========================================================
      -- Insere CARDAMES
      INSERT INTO CARDAMES
      (CDFILIAL, CDSERVFILI, DTMESCARDAPIO,
       DTREFECUSTREC, DTREFECUSTMES,
       NRORG, NRORGINCLUSAO, NRORGULTATU,
       CDOPERINCLUSAO, CDOPERULTATU, 
       DTINCLUSAO, DTULTATU)
      VALUES
      (P_CDFILIAL, P_CDSERVFILI, V_DATA,
       V_DTCUSTO, V_DTCUSTO,
       P_NRORG, P_NRORG, P_NRORG,
       P_CDOPERADOR, P_CDOPERADOR,
       SYSDATE, SYSDATE);
      
      -- Insere configuração do cardápio
      V_SEQ := 1;
      V_PAG := 1;
      FOR C_CONFIGURACAO IN
      (
         SELECT C.CDTIPOPRAT, C.DSCOMPLEMENTO, C.IDCLASSIFICACAO, C.IDTEMPERATURA, T.CDGRTIPOPR
           FROM CONFIGCARDTRAB C
                INNER JOIN TIPOPRAT T ON T.CDTIPOPRAT = C.CDTIPOPRAT
          WHERE C.NRCARDAPIOTRAB = V_NRCARDAPIOTRAB
          ORDER BY C.NRORDEM
      ) LOOP         

         INSERT INTO CNFCAMES
         (CDFILIAL, CDSERVFILI, NRSEQCNFMES,
          DTREFECNFMES, CDTIPOPRAT, 
          IDOPCCNFMES, IDIMPCNFMES, 
          NRPAGCNFMES, VRPERCOMMES,
          NRORDCNFMES, DSCOMPLTPMES,
          NRORG, NRORGULTATU, NRORGINCLUSAO,
          CDOPERINCLUSAO, CDOPERULTATU,
          DTINCLUSAO, DTULTATU)
         VALUES
         (P_CDFILIAL, P_CDSERVFILI, V_SEQ,
          V_DATA, C_CONFIGURACAO.CDTIPOPRAT, 
          'N', 'S', 
          V_PAG, 0, 
          V_SEQ, SUBSTR(C_CONFIGURACAO.DSCOMPLEMENTO, 1, 15),
          P_NRORG, P_NRORG, P_NRORG,
          P_CDOPERADOR, P_CDOPERADOR,
          SYSDATE, SYSDATE);

         V_SEQ := V_SEQ + 1;
         IF MOD(V_SEQ, 2) = 0 THEN
            V_PAG := 1;
         ELSE
            V_PAG := V_PAG + 1;
         END IF;
      END LOOP;
    
    --=========================================================
    --=== Insere na COMPCARD
    --=========================================================
      WHILE(V_NUM_DIAS_MES > 0) LOOP
         SELECT COUNT(1)
           INTO V_CONTFERIFILI
           FROM FERIFILI
          WHERE CDFILIAL = P_CDFILIAL AND
                DTFERIFILI = V_DATA;

         SELECT MAX(NRDIACARDTRAB), MAX(QTCOMENSAIS)
           INTO V_NRDIACARDTRAB, V_QTCOMENSAIS
              FROM DIACARDTRAB D
          WHERE D.NRCARDAPIOTRAB = V_NRCARDAPIOTRAB
            AND NRSEMANA = V_SEMANA
            AND NRDIASEMANA = V_DIA;

         /* Somente inclui no cardápio se o dia posuir comensais e
         não restringe cardápios a dia útil ou restringe e é um dia útil*/
         IF (V_QTCOMENSAIS > 0) AND 
            (NVL(V_IDCARDIAUTIL, 'N') = 'N' OR (V_IDCARDIAUTIL = 'S' AND V_CONTFERIFILI = 0)) THEN
            -- Insere na CARDADIA
            V_NRCARDAPIO := RETORNA_NOVO_CODIGO('CARDAPIO'|| P_CDFILIAL, 1, 10);
            INSERT INTO CARDADIA
            (CDFILIAL, CDSERVFILI, NRCARDAPIO,
             CDOPERADOR, DTCARDAPIO,
             QTCOMESTICAR, QTCLIESTICAR, 
             QTFUNESTICAR, QTDOAESTICAR,
             DTMESCARD, DTREFECUST,
             NRORG, NRORGULTATU, NRORGINCLUSAO,
             CDOPERINCLUSAO, CDOPERULTATU,
             DTINCLUSAO, DTULTATU)
            VALUES
            (P_CDFILIAL, P_CDSERVFILI, V_NRCARDAPIO,
             P_CDOPERADOR, V_DATA,
             V_QTCOMENSAIS, V_QTCOMENSAIS,
             0.00, 0.00,
             TRUNC(V_DATA, 'MM'), V_DTCUSTO,
             P_NRORG, P_NRORG, P_NRORG,
             P_CDOPERADOR, P_CDOPERADOR,
             SYSDATE, SYSDATE);

            FOR C_COMPOSICAO IN
            (
               SELECT ROW_NUMBER() OVER (ORDER BY CNF.NRORDEM) AS NRSEQCNFMES,
                      C.CDFILAUXPRAT,
                      C.CDPRATO,
                      CNF.CDTIPOPRAT,
                      C.VRPECONSCARDTRAB
                 FROM CONFIGCARDTRAB CNF
                      LEFT JOIN COMPCARDTRAB C ON C.NRCARDAPIOTRAB = CNF.NRCARDAPIOTRAB AND
                                                  C.NRCONFIGCARDTRAB = CNF.NRCONFIGCARDTRAB AND
                                                  C.NRDIACARDTRAB = V_NRDIACARDTRAB
                WHERE CNF.NRCARDAPIOTRAB = V_NRCARDAPIOTRAB                  
                ORDER BY CNF.NRORDEM
            ) LOOP
               IF C_COMPOSICAO.CDPRATO IS NOT NULL THEN
                  INSERT INTO COMPCARD 
                  (CDFILIAL, NRCARDAPIO, NRSEQPRATCAR, CDFILAUXPRAT, CDPRATO,
                   VRPECONSCARD, CDTIPOPRAT, NRORDPRATCAR,
                   NRORG, NRORGINCLUSAO, NRORGULTATU,
                   CDOPERINCLUSAO, CDOPERULTATU,
                   DTINCLUSAO, DTULTATU)
                  VALUES
                  (P_CDFILIAL, V_NRCARDAPIO, C_COMPOSICAO.NRSEQCNFMES, C_COMPOSICAO.CDFILAUXPRAT, C_COMPOSICAO.CDPRATO,
                   C_COMPOSICAO.VRPECONSCARDTRAB, C_COMPOSICAO.CDTIPOPRAT, C_COMPOSICAO.NRSEQCNFMES,
                   P_NRORG, P_NRORG, P_NRORG,
                   P_CDOPERADOR, P_CDOPERADOR,
                   SYSDATE, SYSDATE);
               END IF;
            END LOOP;
         END IF;        
         
         -- Controle cíclico para o cardápio de trabalho
         IF (V_SEMANA = V_MAX_SEMANA AND V_DIA = V_MAX_DIASEMANA) THEN
            V_SEMANA := 1;
         ELSIF V_DIA = 7 THEN            
            V_SEMANA := V_SEMANA + 1;
            IF (V_SEMANA > V_MAX_SEMANA) THEN
               V_SEMANA := 1;
            END IF;
         END IF;

         V_DATA := V_DATA + 1;         
         V_DIA := TO_NUMBER(TO_CHAR(V_DATA, 'D'));
         -- Indica mais um dia do mês preenchido
         V_NUM_DIAS_MES := V_NUM_DIAS_MES - 1;         
      END LOOP;
   END LOOP;
--=========================================================
--=== Indica efetivação do serviço da proposta
--=========================================================
   UPDATE SERVICOPROPCOM
      SET IDSERVICOPROPCOM = 'EFETIVADO',
          NRORGULTATU = P_NRORG,
          CDOPERULTATU = P_CDOPERADOR,
          DTULTATU = SYSDATE
    WHERE NRSERVICOPROPCOM = P_NRSERVICOPROPCOM;
END;
/


CREATE OR REPLACE PROCEDURE CALC_SERVCOMPLEMENTAR
(
   P_NRCARDAPIOBASE IN NUMBER,
   P_IDORIGEM IN VARCHAR2,
   P_NRATIVCLISEGMER IN NUMBER,
   P_CDREGIAO IN VARCHAR2,
   P_VRPEACRESCUSTO IN FLOAT,
   P_NRTIPOPUBLICO IN NUMBER,
   P_QTSEGSEX IN FLOAT,
   P_QTSABADO IN FLOAT,
   P_QTDOMFERI IN FLOAT,
   P_QTTURNOS IN FLOAT,   
   P_DTCUSTO IN DATE,
   P_NRCARDTRABCOMPLEMENTADO IN NUMBER,
   P_NRORG IN NUMBER,
   P_CDOPERADOR IN VARCHAR2,
   P_CDFILIALLOGADA IN VARCHAR2,
   P_NRCARDAPIOTRAB OUT NUMBER,
   P_LISTAERROS OUT VARCHAR2,
   P_IDIOMA IN VARCHAR2 DEFAULT 'PT_BR'
)
AS
   PRAGMA AUTONOMOUS_TRANSACTION;   
   V_CONFIGURACOES VARCHAR2(10);
   V_GRUPOS VARCHAR2(10);
BEGIN
   V_CONFIGURACOES := RETORNA_NOVO_CODIGO('LISTA', 1, 10);
   V_GRUPOS := RETORNA_NOVO_CODIGO('LISTA', 1, 10);
   
   -- Monta lista de itens da configuração
   INSERT INTO LISTA
   (NRLISTA, CDLISTA,
   NRORG, NRORGULTATU, NRORGINCLUSAO,
   CDOPERINCLUSAO, CDOPERULTATU,
   DTINCLUSAO, DTULTATU)
   SELECT V_CONFIGURACOES, TO_CHAR(C.NRCONFIGCARDBASE),
        P_NRORG, P_NRORG, P_NRORG,
        P_CDOPERADOR, P_CDOPERADOR,
        SYSDATE, SYSDATE         
   FROM CONFIGCARDBASE C
   WHERE C.NRCARDAPIOBASE = P_NRCARDAPIOBASE
    AND C.IDCLASSIFICACAO = 'ALIMENTAR';

   -- Monta lista dos grupos
   INSERT INTO LISTA
   (NRLISTA, CDLISTA,
   NRORG, NRORGULTATU, NRORGINCLUSAO,
   CDOPERINCLUSAO, CDOPERULTATU,
   DTINCLUSAO, DTULTATU)
   SELECT DISTINCT V_GRUPOS, TO_CHAR(G.CDGRTIPOPR) || '|' || TO_CHAR(P.NRPORCIONAMENTO) || '|' || TO_CHAR(GR.NRGRAMATURACARDBASE),
        P_NRORG, P_NRORG, P_NRORG,
        P_CDOPERADOR, P_CDOPERADOR,
        SYSDATE, SYSDATE         
   FROM CONFIGCARDBASE C
        INNER JOIN TIPOPRAT T ON T.CDTIPOPRAT = C.CDTIPOPRAT
        INNER JOIN GRTIPOPR G ON G.CDGRTIPOPR = T.CDGRTIPOPR
        LEFT JOIN (SELECT A.CDGRTIPOPR, MAX(NRPORCIONAMENTO) AS NRPORCIONAMENTO
                     FROM ADESAOCARDBASE A
                          INNER JOIN ITEMADESAOCBASE I ON I.NRADESAOCARDBASE = A.NRADESAOCARDBASE
                    WHERE A.NRCARDAPIOBASE = P_NRCARDAPIOBASE
                    GROUP BY A.CDGRTIPOPR) P ON P.CDGRTIPOPR = G.CDGRTIPOPR
        LEFT JOIN (SELECT G.CDGRTIPOPR, MAX(G.NRGRAMATURACARDBASE) NRGRAMATURACARDBASE
                     FROM GRAMATURACARDBASE G
                    WHERE G.NRCARDAPIOBASE = P_NRCARDAPIOBASE
                      AND (G.NRTIPOPUBLICO = P_NRTIPOPUBLICO OR 
                             (G.NRTIPOPUBLICO IS NULL AND
                               NOT EXISTS (
                                             SELECT 1
                                               FROM GRAMATURACARDBASE
                                              WHERE NRCARDAPIOBASE = G.NRCARDAPIOBASE
                                                AND CDGRTIPOPR = G.CDGRTIPOPR                                                     
                                                AND VRGRAMATURA = G.VRGRAMATURA
                                                AND SGUNIDADE = G.SGUNIDADE
                                                AND NRTIPOPUBLICO = P_NRTIPOPUBLICO
                                          )
                             )
                          )
                    GROUP BY CDGRTIPOPR) GR ON GR.CDGRTIPOPR = G.CDGRTIPOPR      
   WHERE C.NRCARDAPIOBASE = P_NRCARDAPIOBASE
    AND C.IDCLASSIFICACAO = 'ALIMENTAR';

   IMPORTA_CARDBASE_NO_CARDTRAB(P_NRCARDAPIOBASE, P_IDORIGEM,
                                P_NRATIVCLISEGMER, P_CDREGIAO,
                                P_VRPEACRESCUSTO, P_NRTIPOPUBLICO,
                                P_QTSEGSEX, P_QTSABADO,
                                P_QTDOMFERI, P_QTTURNOS,
                                V_CONFIGURACOES, V_GRUPOS,
                                P_DTCUSTO, P_NRCARDTRABCOMPLEMENTADO,
                                P_NRORG, P_CDOPERADOR,
                                P_CDFILIALLOGADA, P_NRCARDAPIOTRAB,
                                P_LISTAERROS, P_IDIOMA);
   
   -- Apaga lista de itens da configuração
   DELETE FROM LISTA WHERE NRLISTA = V_CONFIGURACOES;
   -- Apaga lista de grupos
   DELETE FROM LISTA WHERE NRLISTA = V_GRUPOS;

   IF P_LISTAERROS IS NOT NULL THEN
      ROLLBACK;
   ELSE
      COMMIT;
   END IF;
END;
/

CREATE OR REPLACE PROCEDURE SERVCOMPLEMENTAR_SERVPROPCOM
(
	P_NRSERVICOPROPCOM IN NUMBER,
	P_CDOPERADOR IN VARCHAR2,
	P_NRORG IN NUMBER,
	P_CDFILIALLOGADA IN VARCHAR2,
	P_LISTACARD OUT VARCHAR2,
  P_PLANEJAMENTO IN VARCHAR2 DEFAULT 'N'
)
AS
   V_IDSERVICOPROPCOM VARCHAR2(30);
   V_NRCARDAPIOBASE NUMBER;
   V_NRCARDAPIOTRAB NUMBER;	
   V_NRCARDAPIOTRAB_COMPLEMENTAR NUMBER;
   V_LISTAERROS NUMBER;
   V_CDSEGMER VARCHAR2(5);
   V_CDATIVCLI VARCHAR2(10);
   V_CDREGIAO VARCHAR2(3);
   V_VRPEACRESCUSTO FLOAT;
   V_NRTIPOPUBLICO NUMBER;
   V_NRPADRAOQUALIDADE NUMBER;
   V_QTSEGSEX FLOAT;
   V_QTSABADO FLOAT;
   V_QTDOMFERI FLOAT;
   V_QTTURNOS FLOAT;
   V_RETORNO VARCHAR2(4000);
   V_NRATIVCLISEGMER NUMBER;
BEGIN
--=========================================================
--=== Validação inicial
--=========================================================
	SELECT MAX(SIT_SERVICOPROPCOM(S.NRSERVICOPROPCOM)),
	       MAX(C.NRCARDAPIOTRAB),
	       MAX(S.NRCARDAPIOBASE),
          MAX(P.CDSEGMER),
          MAX(P.CDATIVCLI),
          MAX(C.CDREGIAO),
          MAX(C.VRPEACRESCUSTO),
          MAX(S.NRTIPOPUBLICO),
          MAX(S.QTSEGSEX),
          MAX(S.QTSABADO),
          MAX(S.QTDOMFERI),
          MAX(S.QTTURNOS),
          MAX(S.NRPADRAOQUALIDADE)
	  INTO V_IDSERVICOPROPCOM,	  
	       V_NRCARDAPIOTRAB,
	       V_NRCARDAPIOBASE,
          V_CDSEGMER,
          V_CDATIVCLI,
          V_CDREGIAO,
          V_VRPEACRESCUSTO,
          V_NRTIPOPUBLICO,
          V_QTSEGSEX,
          V_QTSABADO,
          V_QTDOMFERI,
          V_QTTURNOS,
          V_NRPADRAOQUALIDADE
	  FROM SERVICOPROPCOM S
          INNER JOIN VERSAOPROPCOM V ON V.NRVERSAOPROPCOM = S.NRVERSAOPROPCOM
          INNER JOIN PROPOSTACOMERCIAL P ON P.NRPROPOSTACOMERCIAL = V.NRPROPOSTACOMERCIAL
	  	    INNER JOIN DETALHESERVPROPCOM D ON D.NRDETALHESERVPROPCOM = S.NRDETALHESERVPROPCOM
          LEFT JOIN CARDAPIOTRAB C ON C.NRCARDAPIOTRAB = D.NRCARDAPIOTRAB
	 WHERE S.NRSERVICOPROPCOM = P_NRSERVICOPROPCOM;

	IF (P_PLANEJAMENTO = 'N') AND (V_IDSERVICOPROPCOM = 'AGUARDANDOPLANEJAMENTO') THEN
		-- Operação bloqueada. Serviço está aguardando equipe de planejamento.
		RAISE_APPLICATION_ERROR(-20000, MSG('TCOPROC_SERVPROP_AGUARDANDOPLANEJAMENTO'));
	ELSIF V_NRCARDAPIOTRAB IS NULL THEN
		-- Operação bloqueada. Serviço não foi calculado.	
		RAISE_APPLICATION_ERROR(-20000, MSG('TCOPROC_SERVPROP_N_CALCULADO'));
	END IF;

	P_LISTACARD := RETORNA_NOVO_CODIGO('LISTA', 1, 10);	

   SELECT MAX(NRATIVCLISEGMER)
     INTO V_NRATIVCLISEGMER
     FROM ATIVCLISEGMER
    WHERE CDSEGMER = V_CDSEGMER
      AND CDATIVCLI = V_CDATIVCLI;

   -- Encontra os cardápios bases cadastrados como complementar ao cardápio base do serviço
	FOR C_SERVCOMPLEMENTAR IN
	(
		SELECT CB.NRCARDAPIOBASE,
			     CB.NRSERVICOPROPOSTA
		  FROM CARDCOMPLCARDBASE C
		       INNER JOIN CARDAPIOBASE CB ON CB.NRCARDAPIOBASE = C.NRCARDAPIOBASE
		       INNER JOIN SERVICOPROPOSTA S ON S.NRSERVICOPROPOSTA = CB.NRSERVICOPROPOSTA
		 WHERE C.NRCARDAPIOBASECOMPL = V_NRCARDAPIOBASE
		   AND CB.NRPADRAOQUALIDADE = V_NRPADRAOQUALIDADE
		   AND CB.IDATIVO = 'S'
		   AND (TRUNC(SYSDATE) BETWEEN CB.DTINIVIGENCIA AND CB.DTFIMVIGENCIA)
		   AND EXISTS (
		                SELECT 1
		                 FROM SEGMERCARDBASE
		                WHERE NRCARDAPIOBASE = CB.NRCARDAPIOBASE
		                  AND CDSEGMER = V_CDSEGMER
		             )
	) LOOP
      /*Calcula o serviço complementar de acordo com o cardápio já gerado no serviço informado como parâmetro*/
		CALC_SERVCOMPLEMENTAR(C_SERVCOMPLEMENTAR.NRCARDAPIOBASE, 'CALCULOGN',
                            V_NRATIVCLISEGMER, V_CDREGIAO,
                            V_VRPEACRESCUSTO, V_NRTIPOPUBLICO,
                            V_QTSEGSEX, V_QTSABADO,
                            V_QTDOMFERI, V_QTTURNOS,                            
                            TRUNC(SYSDATE), V_NRCARDAPIOTRAB,
                            P_NRORG, P_CDOPERADOR,
                            P_CDFILIALLOGADA, V_NRCARDAPIOTRAB_COMPLEMENTAR,
                            V_LISTAERROS);
		
      IF V_LISTAERROS IS NULL THEN
         V_RETORNO := TO_CHAR(C_SERVCOMPLEMENTAR.NRCARDAPIOBASE) || '|' || 'S' || '|' || TO_CHAR(V_NRCARDAPIOTRAB_COMPLEMENTAR);
      ELSE
         V_RETORNO := TO_CHAR(C_SERVCOMPLEMENTAR.NRCARDAPIOBASE) || '|' || 'N' || '|' || TO_CHAR(V_LISTAERROS);
      END IF;

      INSERT INTO LISTA
      (NRLISTA, CDLISTA,
       NRORG, NRORGULTATU, NRORGINCLUSAO,
       CDOPERINCLUSAO, CDOPERULTATU,
       DTINCLUSAO, DTULTATU)
      VALUES
      (P_LISTACARD, V_RETORNO,
       P_NRORG, P_NRORG, P_NRORG,
       P_CDOPERADOR, P_CDOPERADOR,
       SYSDATE, SYSDATE);

	END LOOP;
END;
/


CREATE OR REPLACE PROCEDURE CRIA_SERVCOMPLEMENTAR_PROPCOM
(
  P_NRSERVICOPROPCOM IN NUMBER,
  P_NRCARDAPIOBASE IN NUMBER,
  P_NRCARDAPIOTRAB IN NUMBER,
  P_CDOPERADOR IN VARCHAR2,
  P_NRORG IN NUMBER
)
AS   
   V_NRVERSAOPROPCOM NUMBER;
   V_NRTIPOPUBLICO NUMBER;
   V_NRPADRAOQUALIDADE NUMBER;
   V_QTSEGSEX FLOAT;
   V_QTSABADO FLOAT;
   V_QTDOMFERI FLOAT;
   V_QTTURNOS FLOAT;   
   V_QTTOTDIAS FLOAT;
   V_QTTOTREFEICOES FLOAT;
   V_RETORNO VARCHAR2(4000);
   V_NRATIVCLISEGMER NUMBER;
   V_NRSERVICOPROPCOM NUMBER;
   V_NRSERVICOPROPOSTA NUMBER;
   V_NRDETALHESERVPROPCOM NUMBER;
   V_NRCONFIGSERVPROPCOM NUMBER;
   V_NRCONFGRUPOTPPROPCOM NUMBER;
   V_QTDE NUMBER;
BEGIN
   IF P_NRSERVICOPROPCOM IS NULL OR P_NRCARDAPIOBASE IS NULL OR P_NRCARDAPIOTRAB IS NULL THEN
      RETURN;
   END IF;

   SELECT COUNT(1)
     INTO V_QTDE
     FROM CARDAPIOTRAB
    WHERE NRCARDAPIOTRAB = P_NRCARDAPIOTRAB;

   IF V_QTDE = 0 THEN
      RETURN;
   END IF;

--=========================================================
--=== Inclusão do serviço da proposta
--=========================================================
	SELECT MAX(S.NRVERSAOPROPCOM),
          MAX(S.NRTIPOPUBLICO),
          MAX(S.QTSEGSEX),
          MAX(S.QTSABADO),
          MAX(S.QTDOMFERI),
          MAX(S.QTTURNOS),
          MAX(S.QTTOTDIAS),
          MAX(S.QTTOTREFEICOES),
          MAX(S.NRPADRAOQUALIDADE)
	  INTO V_NRVERSAOPROPCOM,
          V_NRTIPOPUBLICO,
          V_QTSEGSEX,
          V_QTSABADO,
          V_QTDOMFERI,
          V_QTTURNOS,
          V_QTTOTDIAS,
          V_QTTOTREFEICOES,
          V_NRPADRAOQUALIDADE
	  FROM SERVICOPROPCOM S
	 WHERE S.NRSERVICOPROPCOM = P_NRSERVICOPROPCOM;

    SELECT MAX(NRSERVICOPROPOSTA)
      INTO V_NRSERVICOPROPOSTA
      FROM CARDAPIOBASE 
     WHERE NRCARDAPIOBASE = P_NRCARDAPIOBASE;   
   
   V_NRSERVICOPROPCOM := TO_NUMBER(RETORNA_NOVO_CODIGO('SERVICOPROPCOM', 1));

   INSERT INTO SERVICOPROPCOM
   (
      NRSERVICOPROPCOM, NRVERSAOPROPCOM,
      NRSERVICOPROPOSTA, NRPADRAOQUALIDADE,
      NRTIPOPUBLICO, IDSERVICOPROPCOM,
      QTSEGSEX, QTSABADO, QTDOMFERI, 
      QTTOTDIAS, QTTURNOS, QTTOTREFEICOES,
      NRCARDAPIOBASE, NRSERVICOPROPCOMCOMPL,
      NRORG, NRORGINCLUSAO, NRORGULTATU,
      DTINCLUSAO, DTULTATU,
      CDOPERINCLUSAO, CDOPERULTATU
   )
   VALUES
   (
      V_NRSERVICOPROPCOM, V_NRVERSAOPROPCOM,
      V_NRSERVICOPROPOSTA, V_NRPADRAOQUALIDADE,
      V_NRTIPOPUBLICO, 'CALCULADO',
      V_QTSEGSEX, V_QTSABADO, V_QTDOMFERI,
      V_QTTOTDIAS, V_QTTURNOS, V_QTTOTREFEICOES,
      P_NRCARDAPIOBASE, P_NRSERVICOPROPCOM,
      P_NRORG, P_NRORG, P_NRORG,
      SYSDATE, SYSDATE,
      P_CDOPERADOR, P_CDOPERADOR
   );   
--=========================================================
--=== Inclusão do detalhe e configurações
--=========================================================
   V_NRDETALHESERVPROPCOM := TO_NUMBER(RETORNA_NOVO_CODIGO('DETALHESERVPROPCOM', 1));
   -- Inclui novo detalhe de serviço
   INSERT INTO DETALHESERVPROPCOM
   (NRDETALHESERVPROPCOM, NRSERVICOPROPCOM, NRCARDAPIOTRAB,
    NRORG, NRORGINCLUSAO, NRORGULTATU,
    CDOPERINCLUSAO, CDOPERULTATU,
    DTINCLUSAO, DTULTATU)
   VALUES
   (V_NRDETALHESERVPROPCOM, V_NRSERVICOPROPCOM, P_NRCARDAPIOTRAB,    
    P_NRORG, P_NRORG, P_NRORG,
    P_CDOPERADOR, P_CDOPERADOR,
    SYSDATE, SYSDATE);

   UPDATE SERVICOPROPCOM
      SET NRDETALHESERVPROPCOM = V_NRDETALHESERVPROPCOM
    WHERE NRSERVICOPROPCOM = V_NRSERVICOPROPCOM;   

   -- Inclui configuração do serviço
   FOR C_CONFIG IN
   (
      SELECT C.NRCONFIGCARDBASE, C.CDTIPOPRAT, C.DSCOMPLEMENTO,
             C.NRORDEM, C.IDTEMPERATURA
        FROM CONFIGCARDBASE C
       WHERE C.NRCARDAPIOBASE = P_NRCARDAPIOBASE
         AND C.IDCLASSIFICACAO = 'ALIMENTAR'
   ) LOOP
      V_NRCONFIGSERVPROPCOM := TO_NUMBER(RETORNA_NOVO_CODIGO('CONFIGSERVPROPCOM', 1));
      INSERT INTO CONFIGSERVPROPCOM
      (NRCONFIGSERVPROPCOM, NRDETALHESERVPROPCOM,
       NRCONFIGCARDBASE, CDTIPOPRAT, DSCOMPLEMENTO,
       NRORDEM, IDTEMPERATURA,
       NRORG, NRORGINCLUSAO, NRORGULTATU,
       CDOPERINCLUSAO, CDOPERULTATU,
       DTINCLUSAO, DTULTATU)
      VALUES
      (V_NRCONFIGSERVPROPCOM, V_NRDETALHESERVPROPCOM,
       C_CONFIG.NRCONFIGCARDBASE, C_CONFIG.CDTIPOPRAT, C_CONFIG.DSCOMPLEMENTO,
       C_CONFIG.NRORDEM, C_CONFIG.IDTEMPERATURA,
       P_NRORG, P_NRORG, P_NRORG,
       P_CDOPERADOR, P_CDOPERADOR,
       SYSDATE, SYSDATE);
   END LOOP;

   -- Insere grupos
   FOR C_GRUPOS IN
   (
      SELECT DISTINCT G.CDGRTIPOPR, P.NRPORCIONAMENTO, GR.NRGRAMATURACARDBASE
        FROM CONFIGCARDBASE C
             INNER JOIN TIPOPRAT T ON T.CDTIPOPRAT = C.CDTIPOPRAT
             INNER JOIN GRTIPOPR G ON G.CDGRTIPOPR = T.CDGRTIPOPR
             LEFT JOIN (SELECT A.CDGRTIPOPR, MAX(NRPORCIONAMENTO) AS NRPORCIONAMENTO
                          FROM ADESAOCARDBASE A
                               INNER JOIN ITEMADESAOCBASE I ON I.NRADESAOCARDBASE = A.NRADESAOCARDBASE
                         WHERE A.NRCARDAPIOBASE = P_NRCARDAPIOBASE
                         GROUP BY A.CDGRTIPOPR) P ON P.CDGRTIPOPR = G.CDGRTIPOPR
             LEFT JOIN (SELECT G.CDGRTIPOPR, MAX(G.NRGRAMATURACARDBASE) NRGRAMATURACARDBASE
                          FROM GRAMATURACARDBASE G
                         WHERE G.NRCARDAPIOBASE = P_NRCARDAPIOBASE
                           AND (G.NRTIPOPUBLICO = V_NRTIPOPUBLICO OR 
                                  (G.NRTIPOPUBLICO IS NULL AND
                                    NOT EXISTS (
                                                  SELECT 1
                                                    FROM GRAMATURACARDBASE
                                                   WHERE NRCARDAPIOBASE = G.NRCARDAPIOBASE
                                                     AND CDGRTIPOPR = G.CDGRTIPOPR                                                     
                                                     AND VRGRAMATURA = G.VRGRAMATURA
                                                     AND SGUNIDADE = G.SGUNIDADE
                                                     AND NRTIPOPUBLICO = V_NRTIPOPUBLICO
                                               )
                                  )
                               )
                         GROUP BY CDGRTIPOPR) GR ON GR.CDGRTIPOPR = G.CDGRTIPOPR      
       WHERE C.NRCARDAPIOBASE = P_NRCARDAPIOBASE
         AND C.IDCLASSIFICACAO = 'ALIMENTAR'
   ) LOOP
      V_NRCONFGRUPOTPPROPCOM := TO_NUMBER(RETORNA_NOVO_CODIGO('CONFGRUPOTPPROPCOM', 1));
      INSERT INTO CONFGRUPOTPPROPCOM
      (NRCONFGRUPOTPPROPCOM, NRDETALHESERVPROPCOM,
       CDGRTIPOPR, NRPORCIONAMENTO, NRGRAMATURACARDBASE,
       NRORG, NRORGINCLUSAO, NRORGULTATU,
       CDOPERINCLUSAO, CDOPERULTATU,
       DTINCLUSAO, DTULTATU)
      VALUES
      (V_NRCONFGRUPOTPPROPCOM, V_NRDETALHESERVPROPCOM,
       C_GRUPOS.CDGRTIPOPR, C_GRUPOS.NRPORCIONAMENTO, C_GRUPOS.NRGRAMATURACARDBASE,       
       P_NRORG, P_NRORG, P_NRORG,
       P_CDOPERADOR, P_CDOPERADOR,
       SYSDATE, SYSDATE);
   END LOOP;
END;
/


CREATE OR REPLACE PROCEDURE REGISTRA_LISTAPRECOTCO_DIA
AS
	V_CDFILIAL VARCHAR2(4);
	V_CDOPERADOR VARCHAR2(12);
	V_NRORG NUMBER;
	V_NRLISTAPRECOTCO NUMBER;
BEGIN
	SELECT MAX(CDFILIAL), MAX(CDOPERINCLUSAO), MAX(NRORG)
	  INTO V_CDFILIAL, V_CDOPERADOR, V_NRORG
	  FROM PARAMTCO;

	IF V_CDFILIAL IS NOT NULL AND V_NRORG IS NOT NULL AND V_CDOPERADOR IS NOT NULL THEN
		FOR C_REGIAO IN
		(
			SELECT CDREGIAO
			  FROM REGIAO	  
		) LOOP
			GRAVA_LISTAPRECOTCO(TRUNC(SYSDATE), C_REGIAO.CDREGIAO, V_NRORG, V_CDOPERADOR, V_NRLISTAPRECOTCO);
		END LOOP;
	END IF;

	COMMIT;
END;
/

/**
 * Registro do job para execução diária da rotina REGISTRA_LISTAPRECOTCO_DIA
 */
DECLARE
  V_JOB NUMBER;
BEGIN
  FOR C_JOBS IN (SELECT JOB
                   FROM ALL_JOBS
                  WHERE WHAT LIKE '%REGISTRA_LISTAPRECOTCO_DIA%') LOOP
    DBMS_JOB.REMOVE(C_JOBS.JOB);
  END LOOP;

  DBMS_JOB.SUBMIT(V_JOB, WHAT => 'BEGIN REGISTRA_LISTAPRECOTCO_DIA; END;', 
  NEXT_DATE => TO_DATE(TO_CHAR(TRUNC(SYSDATE + 1), 'DD/MM/YYYY') || ' 00:00', 'DD/MM/YYYY HH24:MI'),
  INTERVAL => 'TO_DATE(TO_CHAR(TRUNC(SYSDATE + 1), ''DD/MM/YYYY'') || '' 00:00'', ''DD/MM/YYYY HH24:MI'')');
  COMMIT;
END;
/


CREATE OR REPLACE PROCEDURE GERA_HISTCARDAMES
(
	P_CDFILIAL VARCHAR2,
	P_CDSERVFILI VARCHAR2,
	P_DTMESCARD DATE,
	P_CDTIPOCUSTO VARCHAR2,
	P_DTREFECUSTO DATE,
	P_NRORG NUMBER,
	P_CDOPERADOR VARCHAR2
)
AS
	V_QTDE NUMBER;
	V_NRVERCARDAMES NUMBER;
	V_NRVERCARDADIA NUMBER;
	V_NRVERCARDACLI NUMBER;
	V_NRVERCONSSERV NUMBER;
	V_NRVERCNFCAMES NUMBER;
	V_NRVERCOMPCARD NUMBER;
	V_NRVERCUSTOPRODUTOCAR NUMBER;
	V_NRVERRECEPRATOCAR NUMBER;
	V_IDTIPORECE VARCHAR2(1);
	V_SGUNIDADE VARCHAR2(10);
	V_VRCUSTO FLOAT;
	CUR_CONSSERV UTIL_CONSPLAN_PLA.CONSSERV_CURTYPE;
   REC_CONSSERV UTIL_CONSPLAN_PLA.CONSSERV_RECTYPE;
   CUR_PRODPRAT UTIL_CONSPLAN_PLA.PRODPRAT_CURTYPE;
   REC_PRODPRAT UTIL_CONSPLAN_PLA.PRODPRAT_RECTYPE;
BEGIN
	SELECT COUNT(1)
	  INTO V_QTDE
	  FROM CARDADIA
	 WHERE CDFILIAL = P_CDFILIAL
	   AND CDSERVFILI = P_CDSERVFILI
	   AND DTMESCARD = P_DTMESCARD;
	IF V_QTDE = 0 THEN		
		/*Se n¿existe card¿o n¿gera congelamento*/		
		RETURN;
	END IF;

	SELECT COUNT(1)
	  INTO V_QTDE
	  FROM CARDAMES
	 WHERE CDFILIAL = P_CDFILIAL
	   AND CDSERVFILI = P_CDSERVFILI
	   AND DTMESCARDAPIO = P_DTMESCARD;

	IF V_QTDE = 0 THEN
		INSERT INTO CARDAMES
		(CDFILIAL, CDSERVFILI, DTMESCARDAPIO, 
		 DTREFECUSTMES)
      VALUES 
      (P_CDFILIAL, P_CDSERVFILI, P_DTMESCARD, 
       P_DTREFECUSTO);
	END IF;

	-- Mant¿apenas o ¿mo congelamento para cada CARDAMES
	SELECT MAX(NRVERCARDAMES)
	  INTO V_NRVERCARDAMES
	  FROM VERCARDAMES
	 WHERE CDFILIAL = P_CDFILIAL
	   AND CDSERVFILI = P_CDSERVFILI
	   AND DTMESCARDAPIO = P_DTMESCARD;

	IF V_NRVERCARDAMES IS NOT NULL THEN
		/*Filhas s¿apagadas por cascata*/
		DELETE FROM VERCARDAMES
		WHERE NRVERCARDAMES = V_NRVERCARDAMES;
	END IF;

	V_NRVERCARDAMES := TO_NUMBER(RETORNA_NOVO_CODIGO('VERCARDAMES', 1));
	
	INSERT INTO VERCARDAMES
   (NRVERCARDAMES, CDFILIAL, CDSERVFILI, 
    DTMESCARDAPIO, CDTIPOCUSTO, DTREFECUSTMES, 
    NRORG, NRORGINCLUSAO, NRORGULTATU, 
    CDOPERINCLUSAO, CDOPERULTATU, 
    DTINCLUSAO, DTULTATU)
	VALUES
	(V_NRVERCARDAMES, P_CDFILIAL, P_CDSERVFILI,
	 P_DTMESCARD, P_CDTIPOCUSTO, P_DTREFECUSTO,
	 P_NRORG, P_NRORG, P_NRORG,
	 P_CDOPERADOR, P_CDOPERADOR,
	 SYSDATE, SYSDATE);

	FOR C_CNF IN
	(
		SELECT CDTIPOPRAT, 
             NRORDCNFMES, IDOPCCNFMES, IDIMPCNFMES, 
             NRPAGCNFMES, DSCOMPLTPMES, NRSEQCNFMES,
             IDTPPRATSEGM, IDTPPRATTERM, IDTPPRATQUAM, 
             IDTPPRATQUIM, IDTPPRATSEXM, IDTPPRATSABM, 
             IDTPPRATDOMM, IDTPPRATFERM
		  FROM CNFCAMES
		 WHERE CDFILIAL = P_CDFILIAL
		   AND CDSERVFILI = P_CDSERVFILI
		   AND DTREFECNFMES = P_DTMESCARD
	) LOOP
		V_NRVERCNFCAMES := TO_NUMBER(RETORNA_NOVO_CODIGO('VERCNFCAMES', 1));
		INSERT INTO VERCNFCAMES 
      (NRVERCNFCAMES, NRVERCARDAMES, CDTIPOPRAT, 
       NRORDCNFMES, IDOPCCNFMES, IDIMPCNFMES, 
       NRPAGCNFMES, DSCOMPLTPMES, NRSEQCNFMES,
       IDTPPRATSEGM, IDTPPRATTERM, IDTPPRATQUAM, 
       IDTPPRATQUIM, IDTPPRATSEXM, IDTPPRATSABM, 
       IDTPPRATDOMM, IDTPPRATFERM, 
	    NRORG, NRORGINCLUSAO, NRORGULTATU,
		 CDOPERINCLUSAO, CDOPERULTATU,
		 DTINCLUSAO, DTULTATU)
      VALUES
      (V_NRVERCNFCAMES, V_NRVERCARDAMES, C_CNF.CDTIPOPRAT, 
       C_CNF.NRORDCNFMES, C_CNF.IDOPCCNFMES, C_CNF.IDIMPCNFMES, 
       C_CNF.NRPAGCNFMES, C_CNF.DSCOMPLTPMES, C_CNF.NRSEQCNFMES,
       C_CNF.IDTPPRATSEGM, C_CNF.IDTPPRATTERM, C_CNF.IDTPPRATQUAM, 
       C_CNF.IDTPPRATQUIM, C_CNF.IDTPPRATSEXM, C_CNF.IDTPPRATSABM, 
       C_CNF.IDTPPRATDOMM, C_CNF.IDTPPRATFERM, 
	    P_NRORG, P_NRORG, P_NRORG,
	    P_CDOPERADOR, P_CDOPERADOR,
	    SYSDATE, SYSDATE);
	END LOOP;

	FOR C_CARDADIA IN
	(
		SELECT CDFILIAL, CDSERVFILI, NRCARDAPIO, DTCARDAPIO, CDDIETPAD, 
		       QTCOMESTICAR, QTCLIESTICAR, QTFUNESTICAR, QTDOAESTICAR,
		       QTESTITURNO1, QTESTITURNO2, QTESTITURNO3, QTESTITURNO4,
             QTCOMEFETCAR, QTCLIEFETCAR, QTFUNEFETCAR, QTDOAEFETCAR
		  FROM CARDADIA
		 WHERE CDFILIAL = P_CDFILIAL
		   AND CDSERVFILI = P_CDSERVFILI
		   AND DTMESCARD = P_DTMESCARD
	) LOOP
		V_NRVERCARDADIA := TO_NUMBER(RETORNA_NOVO_CODIGO('VERCARDADIA', 1));

		INSERT INTO VERCARDADIA
      (NRVERCARDADIA, NRVERCARDAMES, DTCARDAPIO, CDFILIAL, NRCARDAPIO,
       CDDIETPAD, QTCOMESTICAR, QTCLIESTICAR, QTFUNESTICAR, QTDOAESTICAR,
       QTESTITURNO1, QTESTITURNO2, QTESTITURNO3, QTESTITURNO4,
       QTCOMEFETCAR, QTCLIEFETCAR, QTFUNEFETCAR, QTDOAEFETCAR,       
 	    NRORG, NRORGINCLUSAO, NRORGULTATU,
		 CDOPERINCLUSAO, CDOPERULTATU,
		 DTINCLUSAO, DTULTATU)
     	VALUES
     	(V_NRVERCARDADIA, V_NRVERCARDAMES, C_CARDADIA.DTCARDAPIO, C_CARDADIA.CDFILIAL, C_CARDADIA.NRCARDAPIO,
     	 C_CARDADIA.CDDIETPAD, C_CARDADIA.QTCOMESTICAR, C_CARDADIA.QTCLIESTICAR, C_CARDADIA.QTFUNESTICAR, C_CARDADIA.QTDOAESTICAR,
       C_CARDADIA.QTESTITURNO1, C_CARDADIA.QTESTITURNO2, C_CARDADIA.QTESTITURNO3, C_CARDADIA.QTESTITURNO4,  
       C_CARDADIA.QTCOMEFETCAR, C_CARDADIA.QTCLIEFETCAR, C_CARDADIA.QTFUNEFETCAR, C_CARDADIA.QTDOAEFETCAR,
       P_NRORG, P_NRORG, P_NRORG,
	    P_CDOPERADOR, P_CDOPERADOR,
	    SYSDATE, SYSDATE);
     	
		FOR C_CARDACLI IN
		(
			SELECT CDCLIENTE, CDFILIAL, CDDESTFILI, QTCOMESTICLI
			  FROM CARDACLI
			 WHERE CDFILIAL = C_CARDADIA.CDFILIAL			   
			   AND NRCARDAPIO = C_CARDADIA.NRCARDAPIO
		) LOOP
			V_NRVERCARDACLI := TO_NUMBER(RETORNA_NOVO_CODIGO('VERCARDACLI', 1));
			INSERT INTO VERCARDACLI
			(NRVERCARDACLI, NRVERCARDADIA, CDCLIENTE, CDFILIAL, 
			 CDDESTFILI, QTCOMESTICLI, 
			 NRORG, NRORGINCLUSAO, NRORGULTATU,
			 CDOPERINCLUSAO, CDOPERULTATU,
			 DTINCLUSAO, DTULTATU)
			VALUES
			(V_NRVERCARDACLI, V_NRVERCARDADIA, C_CARDACLI.CDCLIENTE, C_CARDACLI.CDFILIAL, 
			 C_CARDACLI.CDDESTFILI, C_CARDACLI.QTCOMESTICLI,
			 P_NRORG, P_NRORG, P_NRORG,
	       P_CDOPERADOR, P_CDOPERADOR,
	       SYSDATE, SYSDATE);
		END LOOP;

		-- Verifica se ¿eriado
      SELECT COUNT(*)
        INTO V_QTDE
      FROM FERIFILI
      WHERE CDFILIAL = C_CARDADIA.CDFILIAL AND
            DTFERIFILI = C_CARDADIA.DTCARDAPIO;
		-- Abre o cursor do consumo
		UTIL_CONSPLAN_PLA.OPEN_CONSSERV_CURSOR(CUR_CONSSERV,
                                             C_CARDADIA.CDFILIAL,
                                             C_CARDADIA.CDSERVFILI,
                                             C_CARDADIA.DTCARDAPIO,
                                             V_QTDE,
                                             '0',
                                             'zzzzzzzzzzzzzzzzzzzz',
                                             'T');
      LOOP
         FETCH CUR_CONSSERV INTO REC_CONSSERV;
         EXIT WHEN CUR_CONSSERV%NOTFOUND;

         V_NRVERCONSSERV := TO_NUMBER(RETORNA_NOVO_CODIGO('VERCONSSERV', 1));

			INSERT INTO VERCONSSERV
			(NRVERCONSSERV, NRVERCARDADIA, IDTIPOCONSUMO, 
			 CDPRODUTO, QTPRODUTO, 
			 NRORG, NRORGINCLUSAO, NRORGULTATU,
			 CDOPERINCLUSAO, CDOPERULTATU,
			 DTINCLUSAO, DTULTATU)
			VALUES
			(V_NRVERCONSSERV, V_NRVERCARDADIA, REC_CONSSERV.IDQTDECONS,
			 REC_CONSSERV.CDPRODUTO, REC_CONSSERV.QTCONSSERV,
			 P_NRORG, P_NRORG, P_NRORG,
	       P_CDOPERADOR, P_CDOPERADOR,
	       SYSDATE, SYSDATE);
		END LOOP;
		CLOSE CUR_CONSSERV;
		
		FOR C_COMP IN
		(
			SELECT CDFILAUXPRAT, CDPRATO, 
			       VRPECONSCARD, NRSEQPRATCAR, 
			       CDTIPOPRAT, QTCOMEFETPRA
			  FROM COMPCARD
			 WHERE CDFILIAL = C_CARDADIA.CDFILIAL
			   AND NRCARDAPIO = C_CARDADIA.NRCARDAPIO
		) LOOP
			V_NRVERCOMPCARD := TO_NUMBER(RETORNA_NOVO_CODIGO('VERCOMPCARD', 1));
			
			SELECT MAX(NRVERCNFCAMES)
			  INTO V_NRVERCNFCAMES
			  FROM VERCNFCAMES
			 WHERE NRVERCARDAMES = V_NRVERCARDAMES
			   AND NRSEQCNFMES = C_COMP.NRSEQPRATCAR;
			IF V_NRVERCNFCAMES IS NULL THEN
				CONTINUE;
			END IF;

			INSERT INTO VERCOMPCARD
			(NRVERCOMPCARD, NRVERCARDAMES, NRVERCARDADIA, 
			 NRVERCNFCAMES, CDFILAUXPRAT, CDPRATO, CDTIPOPRAT, 
			 VRPECONSCARD, QTCOMEFETPRA,
			 CDFILIAL, NRCARDAPIO, NRSEQPRATCAR,
			 NRORG, NRORGINCLUSAO, NRORGULTATU,
			 CDOPERINCLUSAO, CDOPERULTATU,
			 DTINCLUSAO, DTULTATU)
			VALUES
			(V_NRVERCOMPCARD, V_NRVERCARDAMES, V_NRVERCARDADIA,
			 V_NRVERCNFCAMES, C_COMP.CDFILAUXPRAT, C_COMP.CDPRATO, C_COMP.CDTIPOPRAT,
			 C_COMP.VRPECONSCARD, C_COMP.QTCOMEFETPRA,
			 C_CARDADIA.CDFILIAL, C_CARDADIA.NRCARDAPIO, C_COMP.NRSEQPRATCAR,
			 P_NRORG, P_NRORG, P_NRORG,
	       P_CDOPERADOR, P_CDOPERADOR,
	       SYSDATE, SYSDATE);

			
	      SELECT COUNT(1)
	        INTO V_QTDE
	        FROM VERRECEPRATOCAR
	       WHERE NRVERCARDAMES = V_NRVERCARDAMES
	         AND CDFILAUXPRAT = C_COMP.CDFILAUXPRAT
	         AND CDPRATO = C_COMP.CDPRATO;
	      -- Insere receita do prato se ela ainda n¿existir na vers¿salva
	      IF V_QTDE = 0 THEN
	      	V_IDTIPORECE := RECEITA_UTILIZADA(C_COMP.CDPRATO, C_COMP.CDFILAUXPRAT, 
	      		                               C_CARDADIA.CDFILIAL, C_CARDADIA.CDSERVFILI);

	      	FOR C_PRODRECE IN
	      	(
	      		SELECT CDPRODUTO,
	                   QTPRODPRAT AS QTPRODREC, VRPEFATCOCPR AS VRPEFATCOC, VRPEFATCORPR AS VRPEFATCOR,
	                   SGUNIDADE, QTBRUTAPRUNR AS QTBRUTAUNR,
	                   IDPRODBASEPR AS IDPRODBASE, IDQTDEFIXPR AS IDQTDEFIX
	      		  FROM RECEPADR
	      		 WHERE CDFILAUXPRAT = C_COMP.CDFILAUXPRAT
	      		   AND CDPRATO = C_COMP.CDPRATO
	      		   AND V_IDTIPORECE = 'P'
	      		UNION ALL
	      		SELECT CDPRODUTO,
	                   QTPRODRECLOC AS QTPRODREC, VRPEFATCOCLO AS VRPEFATCOC, VRPEFATCORLO AS VRPEFATCOR,
	                   SGUNIDADE, QTBRUTALOUNR AS QTBRUTAUNR, 
	                   IDPRODBASELO AS IDPRODBASE, IDQTDEFIXLO AS IDQTDEFIX
	      		  FROM RECEFILI
	      		 WHERE CDFILAUXPRAT = C_COMP.CDFILAUXPRAT
	      		   AND CDPRATO = C_COMP.CDPRATO
	      		   AND CDFILIAL = C_CARDADIA.CDFILIAL
	      		   AND V_IDTIPORECE = 'F'
	      		UNION ALL
	      		SELECT CDPRODUTO,
	                   QTPRODRECSER AS QTPRODREC, VRPEFATCOCSE AS VRPEFATCOC, VRPEFATCORSE AS VRPEFATCOR,
	                   SGUNIDADE, QTBRUTASEUNR AS QTBRUTAUNR, 
	                   IDPRODBASESE AS IDPRODBASE, IDQTDEFIXSE AS IDQTDEFIX
	      		  FROM RECESERV
	      		 WHERE CDFILAUXPRAT = C_COMP.CDFILAUXPRAT
	      		   AND CDPRATO = C_COMP.CDPRATO
	      		   AND CDFILIAL = C_CARDADIA.CDFILIAL
	      		   AND CDSERVFILI = C_CARDADIA.CDSERVFILI
	      		   AND V_IDTIPORECE = 'S'

	      	) LOOP
					V_SGUNIDADE := C_PRODRECE.SGUNIDADE;
					IF V_SGUNIDADE IS NULL THEN
						SELECT MAX(SGUNIDADE)
						  INTO V_SGUNIDADE
						  FROM PRODUTO
						 WHERE CDPRODUTO = C_PRODRECE.CDPRODUTO;
					END IF;

               V_NRVERRECEPRATOCAR := TO_NUMBER(RETORNA_NOVO_CODIGO('VERRECEPRATOCAR', 1));

					-- Insere receita do prato
					INSERT INTO VERRECEPRATOCAR
	            (NRVERRECEPRATOCAR, NRVERCARDAMES, 
	             CDFILAUXPRAT, CDPRATO,
	             CDPRODUTO, IDTIPORECE,
	             QTPRODREC, VRPEFATCOC, VRPEFATCOR,
	             SGUNIDADE, QTBRUTAUNR, 
	             IDPRODBASE, IDQTDEFIX,
	             NRORG, NRORGINCLUSAO, NRORGULTATU,
			       CDOPERINCLUSAO, CDOPERULTATU,
			       DTINCLUSAO, DTULTATU)
	             VALUES
	             (V_NRVERRECEPRATOCAR, V_NRVERCARDAMES,
					  C_COMP.CDFILAUXPRAT, C_COMP.CDPRATO,
					  C_PRODRECE.CDPRODUTO, V_IDTIPORECE, 
	              C_PRODRECE.QTPRODREC, NVL(C_PRODRECE.VRPEFATCOC, 0), NVL(C_PRODRECE.VRPEFATCOR, 0), 
	              V_SGUNIDADE, C_PRODRECE.QTBRUTAUNR,
	              NVL(C_PRODRECE.IDPRODBASE, 'N'), NVL(C_PRODRECE.IDQTDEFIX, 'N'),
	              P_NRORG, P_NRORG, P_NRORG,
		           P_CDOPERADOR, P_CDOPERADOR,
		           SYSDATE, SYSDATE);	         	

	      	END LOOP;
	      	
			END IF;
			
		END LOOP;		
	END LOOP;		
	-- Percorre cada produto distinto existente no card¿o e registra seu custo na tabela
	FOR C_PROD IN
	(
      SELECT DISTINCT CDPRODUTO
        FROM VERRECEPRATOCAR
       WHERE NRVERCARDAMES = V_NRVERCARDAMES
      UNION
      SELECT DISTINCT CDPRODUTO
        FROM VERCARDADIA VD
             INNER JOIN VERCONSSERV VCS ON VD.NRVERCARDADIA = VCS.NRVERCARDADIA
       WHERE VD.NRVERCARDAMES = V_NRVERCARDAMES
	) LOOP
		V_NRVERCUSTOPRODUTOCAR := TO_NUMBER(RETORNA_NOVO_CODIGO('VERCUSTOPRODUTOCAR', 1));
		V_VRCUSTO := CUSTO_PRODUTO(P_CDFILIAL, C_PROD.CDPRODUTO, TO_NUMBER(P_CDTIPOCUSTO), P_DTREFECUSTO, P_DTREFECUSTO);
		V_VRCUSTO := NVL(V_VRCUSTO, 0);
		
		INSERT INTO VERCUSTOPRODUTOCAR
      (NRVERCUSTOPRODUTOCAR, NRVERCARDAMES, CDPRODUTO, VRCUSTO,
	    NRORG, NRORGINCLUSAO, NRORGULTATU,
		 CDOPERINCLUSAO, CDOPERULTATU,
		 DTINCLUSAO, DTULTATU)
     	VALUES
     	(V_NRVERCUSTOPRODUTOCAR, V_NRVERCARDAMES, C_PROD.CDPRODUTO, V_VRCUSTO,
     	 P_NRORG, P_NRORG, P_NRORG,
		 P_CDOPERADOR, P_CDOPERADOR,
		 SYSDATE, SYSDATE);
	END LOOP;	
END;
/



/******************************************************************************/
/* Sistemas Integrados TECNISA                                                */
/*                                                                            */
/* Compras e Suprimentos                                                      */
/*                                                                            */
/******************************************************************************/
/*                                                                            */
/* Nome: CARREGA_PERIFORN                                                     */
/*                                                                            */
/* Cria¿:                                                                   */
/*    06/05/2003 - Jo¿Fernando dos Reis Corr¿                             */
/*                                                                            */
/* Manuten¿s:                                                               */
/*   /  /   -                                                                 */
/*                                                                            */
/******************************************************************************/

CREATE OR REPLACE FUNCTION CARREGA_PERIFORN_FUN
(
   P_CDFILIAL        IN FILIAL.CDFILIAL%TYPE,
   P_CDFORNECED      IN FORNECEDOR.CDFORNECED%TYPE,
   P_DTPROGENTAF     IN DATE,
   P_IDDESCONSILIMCALCMP  IN PARASUPRI.IDDESCONSILIMCALCMP%TYPE DEFAULT 'N',
   P_CDARVPROD       IN PRODUTO.CDARVPROD%TYPE DEFAULT NULL
)  RETURN DATE
IS
   V_NEW_DTPROGENTAF DATE;
   V_CDPERIENTR      VARCHAR2(2);
   V_IDTIPODIA       VARCHAR2(1);
   V_IDDIANUTIL      VARCHAR2(1);
   V_DIENTREGA       VARCHAR2(3);
   V_DTDIAENTR       VARCHAR2(3);
   V_COUNT           NUMBER;
   V_EXISTE          CHAR(1);
   V_DATA            DATE;
   V_IDUTCALENDCMPGERACAOAF VARCHAR(1);
   V_CALEVAZIA       VARCHAR2(1) := 'N';
   V_DTPROGENTAF     DATE;
   V_IDDNULIMSEG     VARCHAR2(1);
   V_NRLIMISEGU      NUMBER(5);
BEGIN
   SELECT
      MAX(REFORFIL.CDPERIENTR),
      MAX(PERIENTR.IDTIPODIA),
      MAX(PERIENTR.IDDIANUTIL),
      NVL(MAX(REFORFIL.IDUTCALENDCMPGERACAOAF),'N'),
      NVL(MAX(PERIENTR.IDDNULIMSEGP), 'W')   /*Considera dia n¿¿ no c¿ulo de dias de limite de seguran¿na tela de periodicidade*/
   INTO
      V_CDPERIENTR, V_IDTIPODIA, V_IDDIANUTIL, V_IDUTCALENDCMPGERACAOAF, V_IDDNULIMSEG
   FROM
      REFORFIL, PERIENTR
   WHERE
      REFORFIL.CDPERIENTR = PERIENTR.CDPERIENTR AND
      REFORFIL.CDFORNECED = P_CDFORNECED AND
      REFORFIL.CDFILIAL = P_CDFILIAL;

   /*INICIO IMPLEMENTA¿O SOLICITA¿O 185368*/
   IF P_IDDESCONSILIMCALCMP = 'N' THEN
      V_DTPROGENTAF := P_DTPROGENTAF;
   ELSE
      SELECT NVL(MAX(TO_NUMBER(NRLIMISEGU)),0)
        INTO V_NRLIMISEGU
        FROM LIMISEGPROD, PRODUTO
       WHERE LIMISEGPROD.CDPRODUTO = PRODUTO.CDPRODUTO
         AND LIMISEGPROD.CDFILIAL  = P_CDFILIAL
         AND NRLIMISEGU IS NOT NULL
         AND PRODUTO.CDARVPROD     = (SELECT /*+ INDEX (A PK_LIMISEGPROD) INDEX (B PK_PRODUTO) */
                                             MAX(CDARVPROD)
                                        FROM LIMISEGPROD A, PRODUTO B
                                       WHERE A.CDPRODUTO = B.CDPRODUTO
                                         AND A.CDFILIAL  = P_CDFILIAL
                                         AND INSTR(P_CDARVPROD,B.CDARVPROD) = 1);

      IF V_IDDNULIMSEG = 'W' THEN
         /* Se n¿tiver parameriza¿ de periodiciadde busca par¿tro geral*/
         SELECT
            NVL(MAX(PARASUPRI.IDDNULIMSEG), 'N') INTO V_IDDNULIMSEG
         FROM
            PARASUPRI,
            FILIAL
         WHERE
            (FILIAL.CDFILIAL    = P_CDFILIAL) AND
            (PARASUPRI.CDFILIAL = NVL(FILIAL.CDFILCENTCMP, FILIAL.CDFILIAL));
      END IF;
      IF V_IDDNULIMSEG = 'N' THEN
         SELECT NVL(MAX(D.DTDATA), P_DTPROGENTAF)
           INTO V_DTPROGENTAF
           FROM DATA D
          WHERE D.DTDATA <= P_DTPROGENTAF - V_NRLIMISEGU
            AND NOT EXISTS (SELECT 1
                              FROM FERICOMP F
                             WHERE F.CDFILIAL   = P_CDFILIAL
                               AND F.DTFERICOMP = D.DTDATA);
      ELSE
         SELECT NVL(MAX(D.DTDATA), P_DTPROGENTAF)
            INTO V_DTPROGENTAF
            FROM DATA D
           WHERE D.DTDATA <= P_DTPROGENTAF
             AND NOT EXISTS (SELECT 1
                               FROM FERICOMP F
                              WHERE F.CDFILIAL   = P_CDFILIAL
                                AND F.DTFERICOMP = D.DTDATA);
         IF V_NRLIMISEGU > 0 THEN
            SELECT NVL(MAX(D.DTDATA), V_DTPROGENTAF)
              INTO V_DTPROGENTAF
              FROM (SELECT DT.DTDATA, ROWNUM NRLIMISEGU
                      FROM DATA DT
                     WHERE DT.DTDATA < V_DTPROGENTAF
                       AND NOT EXISTS (SELECT 1
                                         FROM FERICOMP F
                                        WHERE F.CDFILIAL   = P_CDFILIAL
                                          AND F.DTFERICOMP = DT.DTDATA)
                                        ORDER BY DT.DTDATA DESC) D
             WHERE D.NRLIMISEGU = V_NRLIMISEGU;
          END IF;
      END IF;
   END IF;
   /*FIM IMPLEMENTA¿O SOLICITA¿O 185368*/

   V_NEW_DTPROGENTAF := V_DTPROGENTAF;
   IF V_IDUTCALENDCMPGERACAOAF = 'S' THEN
      SELECT MAX(C.DTENTREGA)
        INTO V_NEW_DTPROGENTAF
        FROM CALECOMP C
       WHERE C.CDFILIAL    = P_CDFILIAL
         AND C.CDPERIENTR  = V_CDPERIENTR
         AND C.DTENTREGA  <= V_DTPROGENTAF;
      IF V_NEW_DTPROGENTAF IS NULL THEN
         V_CALEVAZIA := 'S';
      END IF;
   END IF;
   IF (V_NEW_DTPROGENTAF IS NULL) OR (V_IDUTCALENDCMPGERACAOAF = 'N') THEN
      IF V_IDTIPODIA = 'S' THEN
         V_DATA := TRUNC(V_DTPROGENTAF);
         WHILE V_EXISTE IS NULL LOOP
            V_EXISTE := NULL;
            BEGIN
               SELECT '1' INTO V_EXISTE
               FROM DIASENTR
               WHERE
                  TO_NUMBER(TO_CHAR(V_DATA, 'D')) = TO_NUMBER(DIASENTR.DIENTREGA)   AND
                  DIASENTR.CDPERIENTR = V_CDPERIENTR AND
                  (TRUNC((TO_NUMBER(TO_CHAR(V_DATA, 'DD')) + 6) / 7) + IDOCOR01 = (2*TO_NUMBER(IDOCOR01)) OR
                   TRUNC((TO_NUMBER(TO_CHAR(V_DATA, 'DD')) + 6) / 7) + IDOCOR02 = (3*TO_NUMBER(IDOCOR02)) OR
                   TRUNC((TO_NUMBER(TO_CHAR(V_DATA, 'DD')) + 6) / 7) + IDOCOR03 = (4*TO_NUMBER(IDOCOR03)) OR
                   TRUNC((TO_NUMBER(TO_CHAR(V_DATA, 'DD')) + 6) / 7) + IDOCOR04 = (5*TO_NUMBER(IDOCOR04)) OR
                   /*CORRECAO GRSA 186787*/
                   ((TRUNC((TO_NUMBER(TO_CHAR((V_DATA), 'DD')) + 6) / 7) + IDOCOR05 = (6*TO_NUMBER(IDOCOR05)))
                    OR ((TRUNC((TO_NUMBER(TO_CHAR((V_DATA), 'DD')) + 6) / 7) + IDOCOR05 = (5*TO_NUMBER(IDOCOR05))) AND (TRUNC((TO_NUMBER(TO_CHAR((V_DATA+7), 'DD')) + 6) / 7) + IDOCOR05 <> (6*TO_NUMBER(IDOCOR05))))) );
            EXCEPTION
               WHEN NO_DATA_FOUND THEN BEGIN
                  V_EXISTE := NULL;
               END;
            END;
            IF V_EXISTE IS NOT NULL THEN
               V_NEW_DTPROGENTAF := V_DATA;
            ELSE
               V_DATA := V_DATA - 1;
            END IF;
            /*CORRECAO GRSA 186787*/
            IF (V_DTPROGENTAF - V_DATA) > 60 THEN
               V_EXISTE := '1';
            END IF;
         END LOOP;
      END IF;
      IF V_IDTIPODIA = 'R' THEN
         SELECT
            MAX(C.DTENTREGA) INTO V_NEW_DTPROGENTAF
         FROM
            CALECOMP C
         WHERE C.CDFILIAL    = P_CDFILIAL
           AND C.CDPERIENTR  = V_CDPERIENTR
           AND C.DTENTREGA  <= V_DTPROGENTAF;

         IF V_NEW_DTPROGENTAF IS NULL THEN
            V_NEW_DTPROGENTAF := V_DTPROGENTAF;
         END IF;
      END IF;
      IF V_IDTIPODIA = 'M' THEN
         SELECT MAX(DIENTREGA) INTO V_DIENTREGA
         FROM
           (SELECT '-'||DIENTREGA DIENTREGA
            FROM DIASENTR
            WHERE CDPERIENTR = V_CDPERIENTR
            UNION ALL
            SELECT DIENTREGA
            FROM DIASENTR
            WHERE CDPERIENTR = V_CDPERIENTR)
         WHERE
            DIENTREGA <= TO_CHAR(V_DTPROGENTAF, 'DD');

         IF SUBSTR(V_DIENTREGA, 1, 1) = '-' THEN
            V_DTDIAENTR := SUBSTR(V_DIENTREGA, 2, 2);
            IF TO_NUMBER(V_DTDIAENTR) > TO_NUMBER(TO_CHAR(LAST_DAY(ADD_MONTHS(LAST_DAY(V_DTPROGENTAF)+1,-2)), 'DD')) THEN
               V_DIENTREGA := '-'||TO_CHAR(LAST_DAY(ADD_MONTHS(LAST_DAY(V_DTPROGENTAF)+1,-2)), 'DD');
            END IF;
            V_NEW_DTPROGENTAF := TO_DATE(SUBSTR(V_DIENTREGA, 2, 2)||TO_CHAR(ADD_MONTHS(V_DTPROGENTAF, -1), 'MMYYYY'), 'DDMMYYYY');
         ELSE
            V_DTDIAENTR := V_DIENTREGA;
            IF TO_NUMBER(V_DTDIAENTR) > TO_NUMBER(TO_CHAR(LAST_DAY(ADD_MONTHS(LAST_DAY(V_DTPROGENTAF)+1,-1)), 'DD')) THEN
               V_DIENTREGA := TO_CHAR(LAST_DAY(ADD_MONTHS(LAST_DAY(V_DTPROGENTAF)+1,-1)), 'DD');
            END IF;
            V_NEW_DTPROGENTAF := TO_DATE(V_DIENTREGA||TO_CHAR(V_DTPROGENTAF, 'MMYYYY'), 'DDMMYYYY');
         END IF;
      END IF;
   END IF;

   IF V_IDDIANUTIL = 'S' THEN
      IF V_CALEVAZIA = 'N' THEN
         SELECT COUNT(*) INTO V_COUNT
         FROM FERICOMP
         WHERE CDFILIAL = P_CDFILIAL AND
               DTFERICOMP = V_NEW_DTPROGENTAF;
         IF V_COUNT > 0 THEN
            CARREGA_PERIFORN(P_CDFILIAL, P_CDFORNECED, V_NEW_DTPROGENTAF - 1, V_NEW_DTPROGENTAF);
         END IF;
      END IF;
   END IF;
   RETURN(V_NEW_DTPROGENTAF);
END;