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);
   V_QTCOMESTISEG FLOAT;
   V_QTCOMESTITER FLOAT;
   V_QTCOMESTIQUA FLOAT;
   V_QTCOMESTIQUI FLOAT;
   V_QTCOMESTISEX FLOAT;
   V_QTCOMESTISAB FLOAT;
   V_QTCOMESTIDOM FLOAT;
   V_QTCOMESTIFER FLOAT;
   
    /*DADOS DO PRATO ORIGEM PARA INSERIR NO DESTINO*/
   V_CDFILAUXPRAT_DEST VARCHAR2(4);
   V_NMPRATO_DEST VARCHAR2(80);
   V_CDPRATO_O          VARCHAR2(10); 
   V_NMPRATO_O          VARCHAR2(40); 
   V_CDNVPRATO_O        VARCHAR2(1);  
   V_SGUNIDADE_O        VARCHAR2(10); 
   V_VRARREDTRANS_O     FLOAT(126);   
   V_CDSEGMER_O         VARCHAR2(5);  
   V_CDEXPRATO_O        VARCHAR2(20); 
   V_CDPRODPRODUCAO_O   VARCHAR2(10); 
   V_IDFREQUENCIA_O     VARCHAR2(1);  
   V_QTTEMPOPRAT_O      NUMBER;       
   V_VRVALIDADE_O       FLOAT(126);   
   V_NRFORMAPREPARO_O   NUMBER;       
   V_CDPRATONIVANTE_O   VARCHAR2(10); 
   V_DTINATIVAUTO_O     DATE;         
   V_NRTIPOPREPAROTCO_O NUMBER;
   /*DADOS DO PRATO ORIGEM PARA INSERIR NO DESTINO*/
   
   
BEGIN
--=========================================================
--=== Validacao 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
      -- Operacao bloqueada. Servico de planejamento informado nao existe na filial de destino.
      RAISE_APPLICATION_ERROR(-20000, MSG('TCOPROC_SERVICOPLAN_N_EXISTE'));
   ELSIF V_IDTIPOSERV <> 'N' THEN
      -- Operacao bloqueada. Servico de planejamento informado nao e 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
       -- Operacao bloqueada. Servico da proposta informado nao e existe ou nao foi calculado.
       RAISE_APPLICATION_ERROR(-20000, MSG('TCOPROC_SERVICOPROP_N_EXISTE_OU_N_CALC'));
    END IF;

   IF V_IDVERSAOPROPCOM <> 'APROVADA' THEN
      -- Operacao bloqueada. Simulacao vinculada ao servico nao esta aprovada.
      RAISE_APPLICATION_ERROR(-20000, MSG('TCOPROC_VERSAO_SERV_N_APROVADA'));
   END IF;

   IF V_IDSERVICOPROPCOM = 'EFETIVADO' THEN
      -- Operacao bloqueada. Servico da proposta ja 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 LAST_DAY(ADD_MONTHS(P_DTINICARD, (NVL(P_NUM_MESES, 1) - 1)));

   IF V_QTDE > 0 THEN
      -- Operacao bloqueada. Servico de planejamento informado ja possui cardapio cadastrado no sistema para data informada.
      RAISE_APPLICATION_ERROR(-20000, MSG('TCOPROC_SERVPLAN_JA_POSSUI_CARD'));
   END IF;

   -- Valida informacoes do cardapio 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 parametro "Verifica custo padrao na Montagem do Cardapio" esta marcado */
   SELECT MAX(IDCARDIAUTIL)
     INTO V_IDCARDIAUTIL
     FROM PARAMPLANEJA
    WHERE CDFILIAL = P_CDFILIAL;   
--=========================================================
--=== Revisao dos pratos na filial
--=========================================================
   FOR C_PRATOS IN
   (
      SELECT DISTINCT P.CDFILAUXPRAT, P.CDPRATO, P.IDATIVO, P.NMPRATO
        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';
           
      /*se o prato e local na origem, verifica se existe ele local ou padrao no destino*/
      IF C_PRATOS.CDFILAUXPRAT <> 'P' THEN
         V_CDFILAUXPRAT := P_CDFILIAL;
         
         BEGIN
         V_CDFILAUXPRAT_DEST := NULL;
         SELECT CDFILAUXPRAT, NMPRATO
           INTO V_CDFILAUXPRAT_DEST, V_NMPRATO_DEST
           FROM (SELECT CDFILAUXPRAT, NMPRATO
                   FROM PRATO 
                  WHERE (CDPRATO = C_PRATOS.CDPRATO) AND 
                        (CDFILAUXPRAT = V_CDFILAUXPRAT OR CDFILAUXPRAT = 'P')
                 ORDER BY CASE WHEN CDFILAUXPRAT = 'P' THEN 1 ELSE 0 END)
          WHERE ROWNUM = 1;
          EXCEPTION
           WHEN NO_DATA_FOUND THEN
            V_CDFILAUXPRAT_DEST := NULL;
          END;  
         
         /*se nao existe no destino nem como local nem como padrao, insere um novo prato como local no destino*/
         IF V_CDFILAUXPRAT_DEST IS NULL THEN            
			
			/*BUSCA DADOS DO PRATO ORIGEM PARA INSERIR NO DESTINO*/ 
            SELECT CDPRATO, NMPRATO, CDNVPRATO, SGUNIDADE, VRARREDTRANS, CDSEGMER, CDEXPRATO, CDPRODPRODUCAO, CDPRATONIVANTE, IDFREQUENCIA, QTTEMPOPRAT, 
                             VRVALIDADE, NRFORMAPREPARO, DTINATIVAUTO, NRTIPOPREPAROTCO
               INTO V_CDPRATO_O, V_NMPRATO_O, V_CDNVPRATO_O, V_SGUNIDADE_O, V_VRARREDTRANS_O, V_CDSEGMER_O, V_CDEXPRATO_O, V_CDPRODPRODUCAO_O, V_CDPRATONIVANTE_O, V_IDFREQUENCIA_O, V_QTTEMPOPRAT_O, 
                    V_VRVALIDADE_O, V_NRFORMAPREPARO_O, V_DTINATIVAUTO_O, V_NRTIPOPREPAROTCO_O
               FROM PRATO
              WHERE CDPRATO = C_PRATOS.CDPRATO AND CDFILAUXPRAT = C_PRATOS.CDFILAUXPRAT;
			
			/*INSERE DADOS NO PRATO DE DESTINO*/
            INSERT INTO PRATO(CDFILAUXPRAT, CDPRATO, CDFILIAL, NMPRATO, CDNVPRATO, SGUNIDADE, VRARREDTRANS, DTULTATUPRAT, CDSEGMER, CDEXPRATO, DTULTATURECE, CDPRODPRODUCAO, 
                             NRORG, DTINCLUSAO, DTULTATU, NRORGINCLUSAO, CDOPERINCLUSAO, NRORGULTATU, CDOPERULTATU, IDATIVO, CDPRATONIVANTE, IDFREQUENCIA, QTTEMPOPRAT, 
                             VRVALIDADE, NRFORMAPREPARO, DTINATIVAUTO, NRTIPOPREPAROTCO)
            VALUES(P_CDFILIAL, V_CDPRATO_O, P_CDFILIAL, V_NMPRATO_O, V_CDNVPRATO_O, V_SGUNIDADE_O, V_VRARREDTRANS_O, SYSDATE, V_CDSEGMER_O, V_CDEXPRATO_O, SYSDATE, V_CDPRODPRODUCAO_O, 
                             P_NRORG, SYSDATE, SYSDATE, P_NRORG, P_CDOPERADOR, P_NRORG, P_CDOPERADOR, 'S', V_CDPRATONIVANTE_O, V_IDFREQUENCIA_O, V_QTTEMPOPRAT_O, 
                             V_VRVALIDADE_O, V_NRFORMAPREPARO_O, V_DTINATIVAUTO_O, V_NRTIPOPREPAROTCO_O);
			
            
         /*se o prato existe como local ou padrao no destino, entao verifica se tem o mesmo nome, se forem diferentes entao nao sera possivel utiliza-lo, e barra a exportacao*/
         ELSIF TRANSLATE(UPPER(V_NMPRATO_DEST), 'AEIOUAEIOUAEIOUAEEIOEUEAONC', 'AEIOUAEIOUAEIOUAEIOUAONC') <> 
                 TRANSLATE(UPPER(C_PRATOS.NMPRATO), 'AEIOUAEIOUAEIOUAEEIOEUEAONC', 'AEIOUAEIOUAEIOUAEIOUAONC') THEN            
            /*Operacao bloqueada. Prato ja existe com outro nome.*/
            RAISE_APPLICATION_ERROR(-20000, MSG('TCOPROC_PRATO_EXISTE_OUTRO_NOME'));
         /*se o prato existe com o mesmo nome e e padrao, atualiza a variavel v_cdfilauxprat para P*/
         ELSIF V_CDFILAUXPRAT_DEST = 'P' THEN
            V_CDFILAUXPRAT := 'P';     
         END IF;
      END IF;
      
      -- Verifica se : Existe receita na filial destino --- so vai inserir caso nao exista
      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
         V_INSERE_POR_SERVICO := 'S';
         
         /*verifica se existem diferencas na receita da proposta e a receita local, se forem identicas pula de prato, se forem diferentes faz a exportacao por servico*/  
         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 = C_PRATOS.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 ja possui receita, e ela e identica, 
               segue para a inclusao de outro prato*/
            CONTINUE;
         END IF;
      END IF;

      /* Se receita por servico apaga receita atual*/
      IF V_INSERE_POR_SERVICO = 'S' THEN
         DELETE FROM RECESERV WHERE CDFILAUXPRAT = V_CDFILAUXPRAT AND
                                       CDPRATO = C_PRATOS.CDPRATO AND
                                       CDFILIAL = P_CDFILIAL AND
                                       CDSERVFILI = P_CDSERVFILI;
      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 = C_PRATOS.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)
            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);
         ELSE 
            -- Insere receita no servico da filial            
            INSERT INTO RECESERV
            (CDFILAUXPRAT, CDPRATO, 
             CDFILIAL, CDSERVFILI, CDPRODUTO,
             QTPRODRECSER, SGUNIDADE,
             VRPEFATCOCSE, VRPEFATCORSE,
             QTBRUTASEUNR, QTBRUTASE, 
             IDPRODBASESE, IDQTDEFIXSE,
             VRPEFATNUTSE, QTCALCNUTRSE)
            VALUES
            (V_CDFILAUXPRAT, C_PRATOS.CDPRATO,
             P_CDFILIAL, P_CDSERVFILI, 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);
         END IF;
      END LOOP;      
   END LOOP;   
--=========================================================
--=== Substituicao da configuracao do servico de destino
--=========================================================    
    -- Apaga restricoes de embalagem por tipo de prato
    DELETE FROM ITRESTEMBTPPRAT I
     WHERE EXISTS (
                    SELECT 1
                      FROM RESTEMBTPPRAT R
                     WHERE R.CDFILIAL = P_CDFILIAL
                       AND R.CDSERVFILI = P_CDSERVFILI
                       AND R.NRRESTEMBTPPRAT = I.NRRESTEMBTPPRAT);
    
    -- Apaga restricoes de embalagem por tipo de prato
    DELETE FROM RESTEMBTPPRAT
     WHERE CDFILIAL = P_CDFILIAL
       AND CDSERVFILI = P_CDSERVFILI;
    
    -- Apaga configuracoes de embalagem por ponto de entrega
    DELETE FROM CNFDISTEMBSERV
     WHERE CDFILIAL = P_CDFILIAL
       AND CDSERVFILI = P_CDSERVFILI;

   -- Apagar configuracao atual
   DELETE FROM CONFCARD WHERE CDFILIAL = P_CDFILIAL AND
                              CDSERVFILI = P_CDSERVFILI;
   -- Inserir configuracao do servico
   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)
      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);

      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;

--=========================================================
--=== Informacoes no servico de planejamento
--=========================================================
   --Determina o numero de comensais dia
   V_QTCOMESTIDOM := NULL;
   V_QTCOMESTISEG := NULL;
   V_QTCOMESTITER := NULL;
   V_QTCOMESTIQUA := NULL;
   V_QTCOMESTIQUI := NULL;
   V_QTCOMESTISEX := NULL;
   V_QTCOMESTISAB := NULL;
   V_QTCOMESTIFER := NULL;
   FOR C_COMENSAIS IN
   (
      SELECT NRDIASEMANA, MAX(QTCOMENSAIS) AS QTCOMENSAIS
        FROM DIACARDTRAB
       WHERE NRCARDAPIOTRAB = V_NRCARDAPIOTRAB
       GROUP BY NRDIASEMANA
   ) LOOP
      IF C_COMENSAIS.NRDIASEMANA = 1 THEN
         V_QTCOMESTIDOM := C_COMENSAIS.QTCOMENSAIS;
         V_QTCOMESTIFER := V_QTCOMESTIDOM;
      ELSIF C_COMENSAIS.NRDIASEMANA = 2 THEN
         V_QTCOMESTISEG := C_COMENSAIS.QTCOMENSAIS;
      ELSIF C_COMENSAIS.NRDIASEMANA = 3 THEN
         V_QTCOMESTITER := C_COMENSAIS.QTCOMENSAIS;
      ELSIF C_COMENSAIS.NRDIASEMANA = 4 THEN
         V_QTCOMESTIQUA := C_COMENSAIS.QTCOMENSAIS;
      ELSIF C_COMENSAIS.NRDIASEMANA = 5 THEN
         V_QTCOMESTIQUI := C_COMENSAIS.QTCOMENSAIS;
      ELSIF C_COMENSAIS.NRDIASEMANA = 6 THEN
      V_QTCOMESTISEX := C_COMENSAIS.QTCOMENSAIS;
      ELSIF C_COMENSAIS.NRDIASEMANA = 7 THEN
         V_QTCOMESTISAB := C_COMENSAIS.QTCOMENSAIS;
      END IF;
   END LOOP;

   UPDATE SERVICO
      SET NRTIPOCONTRATO = V_NRTIPOCONTRATO,
          NRTIPOPUBLICO = V_NRTIPOPUBLICO,
          NRPADRAOQUALIDADE = V_NRPADRAOQUALIDADE,
          NRSERVICOPROPCOM = P_NRSERVICOPROPCOM,
          QTCOMESTIDOM = V_QTCOMESTIDOM,
          QTCLIESTIDOM = V_QTCOMESTIDOM,
          QTCOMESTISEG = V_QTCOMESTISEG,
          QTCLIESTISEG = V_QTCOMESTISEG,
          QTCOMESTITER = V_QTCOMESTITER,
          QTCLIESTITER = V_QTCOMESTITER,
          QTCOMESTIQUA = V_QTCOMESTIQUA,
          QTCLIESTIQUA = V_QTCOMESTIQUA,
          QTCOMESTIQUI = V_QTCOMESTIQUI,
          QTCLIESTIQUI = V_QTCOMESTIQUI,
          QTCOMESTISEX = V_QTCOMESTISEX,
          QTCLIESTISEX = V_QTCOMESTISEX,
          QTCOMESTISAB = V_QTCOMESTISAB,
          QTCLIESTISAB = V_QTCOMESTISAB,
          QTCOMESTIFER = V_QTCOMESTIFER,
          QTCLIESTIFER = V_QTCOMESTIFER
    WHERE CDFILIAL = P_CDFILIAL
      AND CDSERVFILI = P_CDSERVFILI;   
--=========================================================
--=== Criacao do cardapio do servico (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));
      -- Obtem numero de dias do mes
      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'));

    --=========================================================
    --=== Definicao do custo padrao
    --=========================================================
         
      -- Apaga custo existente para o mes
      DELETE FROM CUSTPADR
       WHERE CDFILIAL = P_CDFILIAL
         AND CDSERVFILI = P_CDSERVFILI
         AND DTREFCUSPADR = V_DATA;         
      

      -- Insere o custo percapita do cardapio de trabalho para o mes atual
      INSERT INTO CUSTPADR
      (CDFILIAL, CDSERVFILI, DTREFCUSPADR,
       VRCUSTPADR)
      VALUES
      (P_CDFILIAL, P_CDSERVFILI, V_DATA,
       V_VRCUSTO);

      -- Insere o custo per capita por tipo de prato
      DELETE FROM CUSTPADRTP
       WHERE CDFILIAL = P_CDFILIAL
         AND CDSERVFILI = P_CDSERVFILI
         AND DTREFCUSPADR = V_DATA;


      FOR C_TIPOPRAT IN
      (
            SELECT C.CDTIPOPRAT, SUM( CUSTO_PERC_COL_CARDTRAB (C.NRCARDAPIOTRAB, C.NRCONFIGCARDTRAB) ) AS VRCUSTO
              FROM CONFIGCARDTRAB C
             WHERE NRCARDAPIOTRAB = V_NRCARDAPIOTRAB
             GROUP BY C.CDTIPOPRAT
             ORDER BY C.CDTIPOPRAT
      ) LOOP
        INSERT INTO CUSTPADRTP
        (CDFILIAL, CDSERVFILI, CDTIPOPRAT, 
         VRCUSTPADRTP, DTREFCUSPADR)
        VALUES
        (P_CDFILIAL, P_CDSERVFILI, C_TIPOPRAT.CDTIPOPRAT, 
         C_TIPOPRAT.VRCUSTO, V_DATA);
      END LOOP;

    --=========================================================
    --=== Cabecalho do Cardapio
    --=========================================================
      SELECT COUNT(1)
        INTO V_QTDE
        FROM CARDAMES
       WHERE CDFILIAL = P_CDFILIAL
         AND CDSERVFILI = P_CDSERVFILI
         AND DTMESCARDAPIO = V_DATA;

      IF V_QTDE = 0 THEN
         -- Insere CARDAMES
         INSERT INTO CARDAMES
         (CDFILIAL, CDSERVFILI, DTMESCARDAPIO,
          DTREFECUSTMES)
         VALUES
         (P_CDFILIAL, P_CDSERVFILI, V_DATA,
          V_DTCUSTO);
      ELSE
         UPDATE CARDAMES
            SET DTREFECUSTMES = V_DTCUSTO
          WHERE CDFILIAL = P_CDFILIAL
            AND CDSERVFILI = P_CDSERVFILI
            AND DTMESCARDAPIO = V_DATA;
      END IF;
      
      -- Insere configuracao do cardapio
      V_SEQ := 1;
      V_PAG := 1;

      DELETE FROM CNFCAMES 
       WHERE CDFILIAL = P_CDFILIAL
         AND CDSERVFILI = P_CDSERVFILI
         AND DTREFECNFMES = V_DATA;
      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)
         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));

         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 cardapio se o dia posuir comensais e
         nao restringe cardapios a dia util ou restringe e e um dia util*/
         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)
            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);

            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
               
               V_CDFILAUXPRAT := C_COMPOSICAO.CDFILAUXPRAT;
                
               IF C_COMPOSICAO.CDFILAUXPRAT <> 'P' THEN
                    V_CDFILAUXPRAT := P_CDFILIAL;
               END IF;               
               
               IF C_COMPOSICAO.CDPRATO IS NOT NULL THEN
                  INSERT INTO COMPCARD 
                  (CDFILIAL, NRCARDAPIO, NRSEQPRATCAR, CDFILAUXPRAT, CDPRATO,
                   VRPECONSCARD, CDTIPOPRAT, NRORDPRATCAR)
                  VALUES
                  (P_CDFILIAL, V_NRCARDAPIO, C_COMPOSICAO.NRSEQCNFMES, V_CDFILAUXPRAT, C_COMPOSICAO.CDPRATO,
                   C_COMPOSICAO.VRPECONSCARDTRAB, C_COMPOSICAO.CDTIPOPRAT, C_COMPOSICAO.NRSEQCNFMES);
               END IF;
            END LOOP;
         END IF;        
         
         -- Controle ciclico para o cardapio 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 mes preenchido
         V_NUM_DIAS_MES := V_NUM_DIAS_MES - 1;         
      END LOOP;
      
   END LOOP;
--=========================================================
--=== Indica efetivacao do servico da proposta
--=========================================================
   UPDATE SERVICOPROPCOM
      SET IDSERVICOPROPCOM = 'EFETIVADO',
          NRORGULTATU = P_NRORG,
          CDOPERULTATU = P_CDOPERADOR,
          DTULTATU = SYSDATE
    WHERE NRSERVICOPROPCOM = P_NRSERVICOPROPCOM;
END;
/