/**
 * Consiste o cardápio de trabalho e lista os erros encontrados como produtos com custo zero, dias requeridos sem pratos, 
 *  
 * @param {Number} P_NRCARDAPIOTRAB Número do cardápio de trabalho 
 * @param {Number} P_NRORG Número da organização logada
 * @param {Varchar2} P_CDOPERADOR Código do operador logado
 * @param {Varchar2} P_CDFILIALLOGADA Código da filial logada
 * @param {Number} P_LISTAERROS {saída} Lista de erros. Se preenchido o ROLLBACK é obrigatório
 * revisada
 */
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
   V_QTDE NUMBER;
   V_CDFILIAL VARCHAR2(4);
   V_CDSERVFILI VARCHAR2(5);
   V_NMSERVICO VARCHAR2(100);
   -- 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
   -- Dados do serviço de planejamento para classificação de grupo de pratos
   SELECT MAX(SP.CDFILIAL), MAX(SP.CDSERVFILI), MAX(SP.CDSERVFILI||' - '||NMSERVICO)
     INTO V_CDFILIAL, V_CDSERVFILI, V_NMSERVICO
     FROM DETALHESERVPROPCOM D
          INNER JOIN SERVICOPROPCOM S ON S.NRSERVICOPROPCOM = D.NRSERVICOPROPCOM
          LEFT JOIN SERVICOPROPOSTA SP ON SP.NRSERVICOPROPOSTA = S.NRSERVICOPROPOSTA
          LEFT JOIN SERVICO SPLA ON SPLA.CDFILIAL = SP.CDFILIAL AND
                                    SPLA.CDSERVFILI = SP.CDSERVFILI
     WHERE D.NRCARDAPIOTRAB = P_NRCARDAPIOTRAB;
   -- 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
     ORDER BY D.NRSEMANA, D.NRDIASEMANA) LOOP
      
      -- Se dia não solicitado, continua para próxima validação
      IF (C_COMP.QTCOMENSAIS <= 0) THEN
         CONTINUE;
      END IF;

      -- 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;

      -- Valida classificação no grupo alimentar
      IF(C_COMP.IDCLASSIFICACAO = 'ALIMENTAR') THEN
         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 = C_COMP.CDPRATO AND
                  IT.CDFILAUXPRAT = C_COMP.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', C_COMP.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', C_COMP.NMPRATO, V_NMSERVICO, V_CDFILIAL));
         END IF;
      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
            AND EXISTS(SELECT 1 FROM COMPCARDTRAB CO
                        WHERE CO.NRCARDAPIOTRAB = P_NRCARDAPIOTRAB 
                          AND CO.CDFILAUXPRAT = R.CDFILAUXPRAT
                          AND CO.CDPRATO = R.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;
/