CREATE OR REPLACE PROCEDURE DADOS_RECEITA_PRODUCAO
(
P_CDFILIAL IN VARCHAR2,
P_CDRECEITA IN VARCHAR2,
P_DTPRODUCAO IN DATE,
P_CDOPERADOR IN VARCHAR2,
P_NRORG IN NUMBER,
P_TIPOCONTEXTO_MSGERRO IN VARCHAR2, /* R  Receita, M subgrupo do menu na data*/
P_CONTEXTO_MSGERRO IN VARCHAR2, /* Obrigatorio se o tipocontexto <> 'R'*/
P_NRLISTAERROS IN OUT VARCHAR2, /* Nao e obrigatorio fornecer valor*/
P_NRORDEMERROS IN OUT NUMBER, /* Nao e obrigatorio fornecer valor*/
P_CODRECEITA OUT VARCHAR2,
P_DSRECEITA OUT VARCHAR2,
P_IDRECFLEXIVEL OUT VARCHAR2,
P_NRVARIACAOREC OUT NUMBER,
P_QTRENDIMENTOREC OUT FLOAT,
P_NRSEQUTILRECFLEX OUT NUMBER
)
AS
   V_CDARVPROD VARCHAR2(20);
   V_CODRECEITA VARCHAR2(20);
   V_DSRECEITA VARCHAR2(500);
   V_IDATIVO VARCHAR2(1);
   V_IDRECFLEXIVEL VARCHAR2(1);
   V_NRVARIACAOREC NUMBER;
   V_QTRENDIMENTOREC FLOAT;
   V_NROPCOES FLOAT;
   V_QTCOMPOSICAO NUMBER;
   V_NUM_OPCOES NUMBER;
   V_CODERRO VARCHAR2(10);
   V_NRSEQUTILRECFLEX NUMBER;
BEGIN
   /*Busca informacoes do cadastro da receita*/
   SELECT MAX(CDARVPROD), MAX(DSRECEITA), MAX(IDATIVO), MAX(IDRECFLEXIVEL)
     INTO V_CDARVPROD, V_DSRECEITA, V_IDATIVO, V_IDRECFLEXIVEL
     FROM RECEITAM
    WHERE CDRECEITA = P_CDRECEITA;

   V_CODRECEITA := NVL(V_CDARVPROD, P_CDRECEITA);

   /*Se a receita for inativa emite mensagem de erro*/
   IF NVL(V_IDATIVO, 'N') = 'N' THEN
      
      IF P_TIPOCONTEXTO_MSGERRO = 'R' THEN
         /*Receita [CDRECEITA] - [DSRECEITA] esta inativa*/
         V_CODERRO := 'APP-00092';
      ELSE
         /*Receita [CDRECEITA] - [DSRECEITA] esta inativa e esta em uso no ciclo [IDCICLO] do subgrupo [SUBGRUPO] do servico [SERVICO] da classe [CLASSE] do menu grid [CODMENU] - [MENU] da companhia [COMPANHIA] na data [DATA]*/
         V_CODERRO := 'APP-00093';      
      END IF;
      
      INSERE_LISTA_ERROS(P_CDFILIAL,
                         'APPERRMSGSTR' || V_CODERRO || '$$' ||
                         V_CODRECEITA || '$$' ||
                         V_DSRECEITA || '$$' ||
                         P_CONTEXTO_MSGERRO 
                         || 'APPERRMSGEND',
                      P_CDOPERADOR, P_NRORG, P_NRLISTAERROS, P_NRORDEMERROS);
      P_NRORDEMERROS := P_NRORDEMERROS + 1;                     
   END IF;

   SELECT MAX(V.NRVARIACAOREC), MAX(V.QTRENDIMENTOREC), MAX(V.NROPCOES)
     INTO V_NRVARIACAOREC, V_QTRENDIMENTOREC, V_NROPCOES
     FROM FILIRECEITA F
          INNER JOIN VARIACAOREC V ON V.CDRECEITA = F.CDRECEITA AND
                                      V.NRVARIACAOREC = F.NRVARIACAOREC
    WHERE F.CDRECEITA = P_CDRECEITA
      AND F.CDFILIAL = P_CDFILIAL;

   /*Se a receita nao possuir variacao para a filial emite mensagem de erro*/
   IF V_NRVARIACAOREC IS NULL THEN

      IF P_TIPOCONTEXTO_MSGERRO = 'R' THEN
         /*Receita [CDRECEITA] - [DSRECEITA] nao possui variacao para a unidade*/
         V_CODERRO := 'APP-00094';
      ELSE
         /*Receita [CDRECEITA] - [DSRECEITA] nao possui variacao para a unidade e esta em uso no ciclo [IDCICLO] do subgrupo [SUBGRUPO] do servico [SERVICO] da classe [CLASSE] do menu grid [CODMENU] - [MENU] da companhia [COMPANHIA] na data [DATA]*/
         V_CODERRO := 'APP-00095';      
      END IF;

      INSERE_LISTA_ERROS(P_CDFILIAL,
                         'APPERRMSGSTR' || V_CODERRO || '$$' ||
                         V_CODRECEITA || '$$' ||
                         V_DSRECEITA || '$$' ||
                         P_CONTEXTO_MSGERRO 
                         || 'APPERRMSGEND',
                      P_CDOPERADOR, P_NRORG, P_NRLISTAERROS, P_NRORDEMERROS);
      P_NRORDEMERROS := P_NRORDEMERROS + 1;

   ELSE

      /*Se a receita nao possuir rendimento informado*/
      IF NVL(V_QTRENDIMENTOREC, 0) = 0 THEN

         IF P_TIPOCONTEXTO_MSGERRO = 'R' THEN
            /*Receita [CDRECEITA] - [DSRECEITA] nao possui rendimento informado na variacao dessa unidade*/
            V_CODERRO := 'APP-00096';
         ELSE
            /*Receita [CDRECEITA] - [DSRECEITA] nao possui rendimento informado na variacao dessa unidade e esta em uso no ciclo [IDCICLO] do subgrupo [SUBGRUPO] do servico [SERVICO] da classe [CLASSE] do menu grid [CODMENU] - [MENU] da companhia [COMPANHIA] na data [DATA]*/
            V_CODERRO := 'APP-00097';      
         END IF;

         INSERE_LISTA_ERROS(P_CDFILIAL,
                            'APPERRMSGSTR' || V_CODERRO || '$$' ||
                            V_CODRECEITA || '$$' ||
                            V_DSRECEITA || '$$' ||
                            P_CONTEXTO_MSGERRO 
                            || 'APPERRMSGEND',
                         P_CDOPERADOR, P_NRORG, P_NRLISTAERROS, P_NRORDEMERROS);
         P_NRORDEMERROS := P_NRORDEMERROS + 1;
                                    
      END IF;
      

      /*Busca utilizacao da receita flex*/
      IF V_IDRECFLEXIVEL <> 'N' THEN

         /*Se a receita e tipo flex e nao tem indicado o numero de opcoes ou o numero de opcoes e nulo*/
         IF NVL(V_NROPCOES, 0) = 0 THEN

            IF P_TIPOCONTEXTO_MSGERRO = 'R' THEN
               /*Receita flex [CDRECEITA] - [DSRECEITA] nao possui numero de opcoes definido na variacao dessa unidade*/
               V_CODERRO := 'APP-00098';
            ELSE
               /*Receita flex [CDRECEITA] - [DSRECEITA] nao possui numero de opcoes definido na variacao dessa unidade e esta em uso no ciclo [IDCICLO] do subgrupo [SUBGRUPO] do servico [SERVICO] da classe [CLASSE] do menu grid [CODMENU] - [MENU] da companhia [COMPANHIA] na data [DATA]*/
               V_CODERRO := 'APP-00099';
            END IF;

            INSERE_LISTA_ERROS(P_CDFILIAL,
                               'APPERRMSGSTR' || V_CODERRO || '$$' ||
                               V_CODRECEITA || '$$' ||
                               V_DSRECEITA || '$$' ||
                               P_CONTEXTO_MSGERRO 
                               || 'APPERRMSGEND',
                            P_CDOPERADOR, P_NRORG, P_NRLISTAERROS, P_NRORDEMERROS);
            P_NRORDEMERROS := P_NRORDEMERROS + 1;
         END IF;     

         SELECT MAX(NRSEQUTILRECFLEX) 
           INTO V_NRSEQUTILRECFLEX
           FROM UTILRECFLEX
          WHERE CDFILIAL = P_CDFILIAL
            AND CDRECEITA = P_CDRECEITA
            AND P_DTPRODUCAO BETWEEN DTINIVIGENCIA AND DTFIMVIGENCIA;
      END IF;

      V_QTCOMPOSICAO := 0;
      V_NUM_OPCOES := 0;

      /*Consiste produtos da receita*/
      FOR CUR_PROD IN
      (
      SELECT PO.CDPRODUTO, PO.CDARVPROD, PO.NMPRODUTO, PO.IDPRODATIVPR, NVL(PR.QTPRODREC, 0) AS QUANTIDADE,
             PR.IDPREFERENCIA,
             COMPOSICAO_EM_PRODUCAO(P_CDFILIAL, P_CDRECEITA, P_NRORG, V_NRSEQUTILRECFLEX, PR.CDPRODUTO, 'P') AS IDPRODUZIR
        FROM PRORECEITAM PR
             INNER JOIN PRODUTO PO ON PO.CDPRODUTO = PR.CDPRODUTO
       WHERE PR.CDRECEITA = P_CDRECEITA
         AND PR.NRVARIACAOREC = V_NRVARIACAOREC            
      ) LOOP
         V_QTCOMPOSICAO := V_QTCOMPOSICAO + 1;
         /*Se a receita e normal, ou e uma receita flex e o produto foi indicado a producao ou nao tem indicacao de producao e ele e a preferencia*/
         IF (V_IDRECFLEXIVEL = 'N') 
            OR (CUR_PROD.IDPRODUZIR = 'S') 
            OR (V_NRSEQUTILRECFLEX IS NULL AND CUR_PROD.IDPREFERENCIA = 'S') THEN
            
            V_NUM_OPCOES := V_NUM_OPCOES + 1;

            /*Se o produto esta inativo*/
            IF NVL(CUR_PROD.IDPRODATIVPR, 'N') = 'N' THEN
               IF P_TIPOCONTEXTO_MSGERRO = 'R' THEN
                  /*Produto [CDARVPROD] - [NMPRODUTO] esta inativo e e utilizado na receita [CDRECEITA] - [DSRECEITA] na variacao dessa unidade*/
                  V_CODERRO := 'APP-00100';
               ELSE
                  /*Produto [CDARVPROD] - [NMPRODUTO] esta inativo e e utilizado na receita [CDRECEITA] - [DSRECEITA] na variacao dessa unidade e esta em uso no ciclo [IDCICLO] do subgrupo [SUBGRUPO] do servico [SERVICO] da classe [CLASSE] do menu grid [CODMENU] - [MENU] da companhia [COMPANHIA] na data [DATA]*/
                  V_CODERRO := 'APP-00101';      
               END IF;

               INSERE_LISTA_ERROS(P_CDFILIAL,
                                  'APPERRMSGSTR' || V_CODERRO || '$$' ||
                                  CUR_PROD.CDARVPROD || '$$' ||
                                  CUR_PROD.NMPRODUTO || '$$' ||
                                  V_CODRECEITA || '$$' ||
                                  V_DSRECEITA || '$$' ||
                                  P_CONTEXTO_MSGERRO 
                                  || 'APPERRMSGEND',
                               P_CDOPERADOR, P_NRORG, P_NRLISTAERROS, P_NRORDEMERROS);
               P_NRORDEMERROS := P_NRORDEMERROS + 1;
            END IF;

            /*Se o produto esta sem quantidade*/
            IF CUR_PROD.QUANTIDADE = 0 THEN
               IF P_TIPOCONTEXTO_MSGERRO = 'R' THEN
                  /*Produto [CDARVPROD] - [NMPRODUTO] esta sem quantidade na receita [CDRECEITA] - [DSRECEITA] na variacao dessa unidade*/
                  V_CODERRO := 'APP-00102';
               ELSE
                  /*Produto [CDARVPROD] - [NMPRODUTO] esta sem quantidade na receita [CDRECEITA] - [DSRECEITA] na variacao dessa unidade e esta em uso no ciclo [IDCICLO] do subgrupo [SUBGRUPO] do servico [SERVICO] da classe [CLASSE] do menu grid [CODMENU] - [MENU] da companhia [COMPANHIA] na data [DATA]*/
                  V_CODERRO := 'APP-00103';      
               END IF;

               INSERE_LISTA_ERROS(P_CDFILIAL,
                                  'APPERRMSGSTR' || V_CODERRO || '$$' ||
                                  CUR_PROD.CDARVPROD || '$$' ||
                                  CUR_PROD.NMPRODUTO || '$$' ||
                                  V_CODRECEITA || '$$' ||
                                  V_DSRECEITA || '$$' ||
                                  P_CONTEXTO_MSGERRO 
                                  || 'APPERRMSGEND',
                               P_CDOPERADOR, P_NRORG, P_NRLISTAERROS, P_NRORDEMERROS);
               P_NRORDEMERROS := P_NRORDEMERROS + 1;
            END IF;

         END IF;
      END LOOP;

      /*Consiste subreceitas da receita*/
      FOR CUR_SUB IN
      (
      SELECT SR.CDSUBRECEITA, NVL(R.CDARVPROD, R.CDRECEITA) AS CODRECEITA, R.DSRECEITA, R.IDATIVO, NVL(SR.QTRENDSUBREC,0) AS QUANTIDADE,
             SR.IDPREFERENCIA,
             COMPOSICAO_EM_PRODUCAO(P_CDFILIAL, P_CDRECEITA, P_NRORG, V_NRSEQUTILRECFLEX, SR.CDSUBRECEITA, 'S') AS IDPRODUZIR
        FROM SUBRECEITAM SR
             INNER JOIN RECEITAM R ON R.CDRECEITA = SR.CDSUBRECEITA
       WHERE SR.CDRECEITA      = P_CDRECEITA
         AND SR.NRVARIACAOREC  = V_NRVARIACAOREC            
      ) LOOP
         V_QTCOMPOSICAO := V_QTCOMPOSICAO + 1;

         /*Se a receita e normal, ou e uma receita flex e o produto foi indicado a producao ou nao tem indicacao de producao e ele e a preferencia*/
         IF (V_IDRECFLEXIVEL = 'N') 
            OR (CUR_SUB.IDPRODUZIR = 'S') 
            OR (V_NRSEQUTILRECFLEX IS NULL AND CUR_SUB.IDPREFERENCIA = 'S') THEN
            
            V_NUM_OPCOES := V_NUM_OPCOES + 1;

            /*Se a subreceita esta inativa*/
            IF NVL(CUR_SUB.IDATIVO, 'N') = 'N' THEN
               IF P_TIPOCONTEXTO_MSGERRO = 'R' THEN
                  /*Subreceita [CODRECEITA] - [DSRECEITA] esta inativa e e utilizada na receita [CDRECEITA] - [DSRECEITA] na variacao dessa unidade*/
                  V_CODERRO := 'APP-00104';
               ELSE
                  /*Subreceita [CODRECEITA] - [DSRECEITA] esta inativa e e utilizada na receita [CDRECEITA] - [DSRECEITA] na variacao dessa unidade e esta em uso no ciclo [IDCICLO] do subgrupo [SUBGRUPO] do servico [SERVICO] da classe [CLASSE] do menu grid [CODMENU] - [MENU] da companhia [COMPANHIA] na data [DATA]*/
                  V_CODERRO := 'APP-00105';      
               END IF;

               INSERE_LISTA_ERROS(P_CDFILIAL,
                                  'APPERRMSGSTR' || V_CODERRO || '$$' ||
                                  CUR_SUB.CODRECEITA || '$$' ||
                                  CUR_SUB.DSRECEITA || '$$' ||
                                  V_CODRECEITA || '$$' ||
                                  V_DSRECEITA || '$$' ||
                                  P_CONTEXTO_MSGERRO 
                                  || 'APPERRMSGEND',
                               P_CDOPERADOR, P_NRORG, P_NRLISTAERROS, P_NRORDEMERROS);
               P_NRORDEMERROS := P_NRORDEMERROS + 1;
            END IF;

            /*Se a subreceita esta sem quantidade*/
            IF CUR_SUB.QUANTIDADE = 0 THEN
               IF P_TIPOCONTEXTO_MSGERRO = 'R' THEN
                  /*Subreceita [CODRECEITA] - [DSRECEITA] esta sem quantidade na receita [CDRECEITA] - [DSRECEITA] na variacao dessa unidade*/
                  V_CODERRO := 'APP-00106';
               ELSE
                  /*Subreceita [CODRECEITA] - [DSRECEITA] esta sem quantidade na receita [CDRECEITA] - [DSRECEITA] na variacao dessa unidade e esta em uso no ciclo [IDCICLO] do subgrupo [SUBGRUPO] do servico [SERVICO] da classe [CLASSE] do menu grid [CODMENU] - [MENU] da companhia [COMPANHIA] na data [DATA]*/
                  V_CODERRO := 'APP-00107';      
               END IF;

               INSERE_LISTA_ERROS(P_CDFILIAL,
                                  'APPERRMSGSTR' || V_CODERRO || '$$' ||
                                  CUR_SUB.CODRECEITA || '$$' ||
                                  CUR_SUB.DSRECEITA || '$$' ||
                                  V_CODRECEITA || '$$' ||
                                  V_DSRECEITA || '$$' ||
                                  P_CONTEXTO_MSGERRO 
                                  || 'APPERRMSGEND',
                               P_CDOPERADOR, P_NRORG, P_NRLISTAERROS, P_NRORDEMERROS);
               P_NRORDEMERROS := P_NRORDEMERROS + 1;
            END IF;

         END IF;
      END LOOP;

      /*Se receita esta sem composicao*/
      IF V_QTCOMPOSICAO = 0 THEN
         IF P_TIPOCONTEXTO_MSGERRO = 'R' THEN
            /*Receita [CDRECEITA] - [DSRECEITA] nao possui composicao na variacao dessa unidade*/
            V_CODERRO := 'APP-00108';
         ELSE
            /*Receita [CDRECEITA] - [DSRECEITA] nao possui composicao na variacao dessa unidade e esta em uso no ciclo [IDCICLO] do subgrupo [SUBGRUPO] do servico [SERVICO] da classe [CLASSE] do menu grid [CODMENU] - [MENU] da companhia [COMPANHIA] na data [DATA]*/
            V_CODERRO := 'APP-00109';      
         END IF;

         INSERE_LISTA_ERROS(P_CDFILIAL,
                            'APPERRMSGSTR' || V_CODERRO || '$$' ||
                            V_CODRECEITA || '$$' ||
                            V_DSRECEITA || '$$' ||
                            P_CONTEXTO_MSGERRO 
                            || 'APPERRMSGEND',
                         P_CDOPERADOR, P_NRORG, P_NRLISTAERROS, P_NRORDEMERROS);
         P_NRORDEMERROS := P_NRORDEMERROS + 1;
      END IF;

      /*Receita flex*/
      IF V_IDRECFLEXIVEL <> 'N' THEN
         IF NVL(V_NROPCOES, 0) > 0 THEN
            /*Se o numero de opcoes a produzir e menor que o numero necessario*/
            IF V_NUM_OPCOES < V_NROPCOES THEN
               IF P_TIPOCONTEXTO_MSGERRO = 'R' THEN
                  /*Receita flex [CDRECEITA] - [DSRECEITA] possui quantidade de opcoes a produzir inferior a quantidade de opcoes indicada na variacao dessa unidade*/
                  V_CODERRO := 'APP-00110';
               ELSE
                  /*Receita flex [CDRECEITA] - [DSRECEITA] possui quantidade de opcoes a produzir inferior a quantidade de opcoes indicada na variacao dessa unidade e esta em uso no ciclo [IDCICLO] do subgrupo [SUBGRUPO] do servico [SERVICO] da classe [CLASSE] do menu grid [CODMENU] - [MENU] da companhia [COMPANHIA] na data [DATA]*/
                  V_CODERRO := 'APP-00111';      
               END IF;

               INSERE_LISTA_ERROS(P_CDFILIAL,
                                  'APPERRMSGSTR' || V_CODERRO || '$$' ||
                                  V_CODRECEITA || '$$' ||
                                  V_DSRECEITA || '$$' ||
                                  P_CONTEXTO_MSGERRO 
                                  || 'APPERRMSGEND',
                               P_CDOPERADOR, P_NRORG, P_NRLISTAERROS, P_NRORDEMERROS);
               P_NRORDEMERROS := P_NRORDEMERROS + 1;
            END IF;

            /*Se o numero de opcoes a produzir e maior que o numero necessario*/
            IF V_NUM_OPCOES > V_NROPCOES THEN
               IF P_TIPOCONTEXTO_MSGERRO = 'R' THEN
                  /*Receita flex [CDRECEITA] - [DSRECEITA] possui quantidade de opcoes a produzir superior a quantidade de opcoes indicada na variacao dessa unidade*/
                  V_CODERRO := 'APP-00112';
               ELSE
                  /*Receita flex [CDRECEITA] - [DSRECEITA] possui quantidade de opcoes a produzir superior a quantidade de opcoes indicada na variacao dessa unidade e esta em uso no ciclo [IDCICLO] do subgrupo [SUBGRUPO] do servico [SERVICO] da classe [CLASSE] do menu grid [CODMENU] - [MENU] da companhia [COMPANHIA] na data [DATA]*/
                  V_CODERRO := 'APP-00113';      
               END IF;

               INSERE_LISTA_ERROS(P_CDFILIAL,
                                  'APPERRMSGSTR' || V_CODERRO || '$$' ||
                                  V_CODRECEITA || '$$' ||
                                  V_DSRECEITA || '$$' ||
                                  P_CONTEXTO_MSGERRO 
                                  || 'APPERRMSGEND',
                               P_CDOPERADOR, P_NRORG, P_NRLISTAERROS, P_NRORDEMERROS);
               P_NRORDEMERROS := P_NRORDEMERROS + 1;
            END IF;
            
         END IF;
      END IF;      

   END IF;

   P_CODRECEITA := V_CODRECEITA;
   P_DSRECEITA := V_DSRECEITA;
   P_NRVARIACAOREC := V_NRVARIACAOREC;
   P_IDRECFLEXIVEL := V_IDRECFLEXIVEL;
   P_QTRENDIMENTOREC := NVL(V_QTRENDIMENTOREC, 0.0);
   P_NRSEQUTILRECFLEX := V_NRSEQUTILRECFLEX;
   
END;
/