Como calcular recesso de estagiário

Tuning de Banco, Tuning de SQL, Ferramentas de tuning
Responder
RodrigoSB
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 3
Registrado em: Seg, 29 Nov 2021 9:57 pm
Localização: Belém

Bom dia pessoal tenho uma procedure que calcula o recesso de estagiaro, mas atribui valor cheio de 30 dias, e eu gostaria de tornar isso proporcional ao que eles tem direito, ex: 1 ano = 30 dias, 6 meses = 20 dias, 4 meses = 15 dias. Vou enviar a procedure e o que eu fiz :

Selecionar tudo

BEGIN
   select sysdate+15 into vdia from dual;
   insert into rh_job
   (dia,processo)
   values
   (vdia,'insere_feriasdia');
   Select to_char(vdia,'yyyy') into v_anoatual from dual;
   Open CServidores;
   loop
      fetch CServidores into VRegistroServidores;
      exit when CServidores%notfound;
      V_matricula := VRegistroServidores.matricula;
      V_admissao := VRegistroServidores.data_admis;
--      dbms_output.put_line('FETCH'||V_MATRICULA||V_admissao);
      select count(*) into v_existe
      from rh_ferias b
      where b.matricula = V_matricula;
--      dbms_output.put_line('Existe'||V_existe);

      if V_existe = 0
      then
          V_ultimaferias := 0;
--          dbms_output.put_line('Existe if then '||V_existe);

          Select NVL(MAX(SEQUENCIA),0)+1 into V_sequencia 
          from rh_ferias 
          where matricula = V_matricula;
--          dbms_output.put_line('PASSOU PELO COUNT');
          V_admissao := TO_CHAR(V_admissao,'dd/mm/')||TO_CHAR(vdia,'yyyy');
--          dbms_output.put_line('PASSOU ADMISSAO');

          if to_char(VRegistroServidores.data_admis,'yyyy')<TO_CHAR(vdia,'yyyy')
          then
            Begin
              Insert into rh_ferias
               (matricula, sequencia, data_a1, data_a2,estado_ferias)
              VALUES
               (V_matricula,V_sequencia,V_admissao,add_months(V_admissao,12)-1,1); 
            end;
          end if;
--                COMMIT;                    
      else
--          dbms_output.put_line('Existe if else '||V_existe);
          select nvl(max(to_char(b.data_a2,'yyyy')),0) into V_ultimaferias
          from rh_ferias b
          where b.matricula = V_matricula;

            If v_anoatual > V_ultimaferias
              then
                Begin
 --                 dbms_output.put_line('ANTES while'||V_matricula||'  '||V_sequencia||'  '||V_dataIni||'  '||V_datafim);
                  WHILE V_ultimaferias <> v_anoatual
                  Loop

                    Select data_a1,data_a2 into V_dataIni,V_datafim 
                    from rh_ferias
                    where matricula = V_matricula
                      and to_char(data_a2,'yyyy') = V_ultimaferias; 

                    Select max(sequencia) into V_sequencia 
                    from rh_ferias 
                    where matricula = V_matricula;  

                    V_sequencia := V_sequencia +1;
                    V_dataIni := ADD_months(V_dataIni,12);
                    V_datafim := ADD_MONTHS(V_datafim,12);
--                    dbms_output.put_line('while insert'||V_matricula||'  '||V_sequencia||'  '||V_dataIni||'  '||V_datafim);

                    Insert into rh_ferias
                     (matricula, sequencia, data_a1, data_a2,estado_ferias)
                    VALUES
                     (V_matricula,V_sequencia,V_dataIni,V_datafim,1);

                    V_ultimaferias := V_ultimaferias +1;
        --                COMMIT;
                  end loop;--while ultimasferias
                end;

              end if; --end if v_anoatual > V_ultimaferias
      end if; --if existe
      dbms_output.put_line('fetch matricula'||V_matricula);      
--      dbms_output.put_line('ultima ferias:'||V_ultimaferias||' Ano atual:'||v_anoatual);              

   end loop; --loop CServidores
   close CServidores; 
O que eu tinha feito:

Selecionar tudo

                    Insert into rh_ferias
                     (recesso_estagio)
                    VALUES
                     (V_recesso_estag);
                     
                     		  Select NVL(MAX(recesso_estagio),0)+1 into V_recesso_estag
          from rh_ferias 
          where matricula = V_matricula;
--          dbms_output.put_line('PASSOU PELO COUNT');
          V_admissao := TO_CHAR(V_admissao,'dd/mm/')||TO_CHAR(vdia,'yyyy');
--          dbms_output.put_line('PASSOU ADMISSAO');
RodrigoSB
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 3
Registrado em: Seg, 29 Nov 2021 9:57 pm
Localização: Belém

Bom dia pessoal estou precisando de ajuda para tornar o recesso dos estagiários proporcional, eles tiram 30 dias cheios, mas agora vou tornar isso proporcional, ex: estagiário de 1 ano = 30 dias, 6 meses = 20 dias, 4 meses = 10 dias ou 15 dias. Alguém pode me ajudar por favor, só tenho 6 meses de experiência e to apanhando para fazer isso

Procedure:

Selecionar tudo

BEGIN
   select sysdate+15 into vdia from dual;
   insert into rh_job
   (dia,processo)
   values
   (vdia,'insere_feriasdia');
   Select to_char(vdia,'yyyy') into v_anoatual from dual;
   Open CServidores;
   loop
      fetch CServidores into VRegistroServidores;
      exit when CServidores%notfound;
      V_matricula := VRegistroServidores.matricula;
      V_admissao := VRegistroServidores.data_admis;
--      dbms_output.put_line('FETCH'||V_MATRICULA||V_admissao);
      select count(*) into v_existe
      from rh_ferias b
      where b.matricula = V_matricula;
--      dbms_output.put_line('Existe'||V_existe);

      if V_existe = 0
      then
          V_ultimaferias := 0;
--          dbms_output.put_line('Existe if then '||V_existe);

          Select NVL(MAX(SEQUENCIA),0)+1 into V_sequencia 
          from rh_ferias 
          where matricula = V_matricula;
--          dbms_output.put_line('PASSOU PELO COUNT');
          V_admissao := TO_CHAR(V_admissao,'dd/mm/')||TO_CHAR(vdia,'yyyy');
--          dbms_output.put_line('PASSOU ADMISSAO');

          if to_char(VRegistroServidores.data_admis,'yyyy')<TO_CHAR(vdia,'yyyy')
          then
            Begin
              Insert into rh_ferias
               (matricula, sequencia, data_a1, data_a2,estado_ferias)
              VALUES
               (V_matricula,V_sequencia,V_admissao,add_months(V_admissao,12)-1,1); 
            end;
          end if;
--                COMMIT;                    
      else
--          dbms_output.put_line('Existe if else '||V_existe);
          select nvl(max(to_char(b.data_a2,'yyyy')),0) into V_ultimaferias
          from rh_ferias b
          where b.matricula = V_matricula;

            If v_anoatual > V_ultimaferias
              then
                Begin
 --                 dbms_output.put_line('ANTES while'||V_matricula||'  '||V_sequencia||'  '||V_dataIni||'  '||V_datafim);
                  WHILE V_ultimaferias <> v_anoatual
                  Loop

                    Select data_a1,data_a2 into V_dataIni,V_datafim 
                    from rh_ferias
                    where matricula = V_matricula
                      and to_char(data_a2,'yyyy') = V_ultimaferias; 

                    Select max(sequencia) into V_sequencia 
                    from rh_ferias 
                    where matricula = V_matricula;  

                    V_sequencia := V_sequencia +1;
                    V_dataIni := ADD_months(V_dataIni,12);
                    V_datafim := ADD_MONTHS(V_datafim,12);
--                    dbms_output.put_line('while insert'||V_matricula||'  '||V_sequencia||'  '||V_dataIni||'  '||V_datafim);

                    Insert into rh_ferias
                     (matricula, sequencia, data_a1, data_a2,estado_ferias)
                    VALUES
                     (V_matricula,V_sequencia,V_dataIni,V_datafim,1);

                    V_ultimaferias := V_ultimaferias +1;
        --                COMMIT;
                  end loop;--while ultimasferias
                end;

              end if; --end if v_anoatual > V_ultimaferias
      end if; --if existe
      dbms_output.put_line('fetch matricula'||V_matricula);      
--      dbms_output.put_line('ultima ferias:'||V_ultimaferias||' Ano atual:'||v_anoatual);              

   end loop; --loop CServidores
   close CServidores; 
Minhas tentativas:

Selecionar tudo

---------- atualizacao tentativa 01
		  Select NVL(MAX(recesso_estagio),0)+1 into V_recesso_estag
          from rh_ferias 
          where matricula = V_matricula;
--          dbms_output.put_line('PASSOU PELO COUNT');
          V_admissao := TO_CHAR(V_admissao,'dd/mm/')||TO_CHAR(vdia,'yyyy');
--          dbms_output.put_line('PASSOU ADMISSAO');

-------atualizacao  tentativa 02
					Select max(recesso_estagio) into V_recesso_estag 
                    from rh_ferias 
                    where matricula = V_matricula;  
					
					V_recesso_estag := V_recesso_estag +1;
                    V_dataIni := ADD_months(V_dataIni,12);
                    V_datafim := ADD_MONTHS(V_datafim,12);[


-------- atualizacao  tentativa 03 (mais provavel)
                   if to_char(V_admissao.data_admis,'yyyy')<TO_CHAR(vdia,'yyyy')
                --    if V_admissao := TO_CHAR(V_admissao,'dd/mm/')||TO_CHAR(vdia,'yyyy') >= vdia and <= -4 V_datafim
                    then
                    Begin
                      if count(recesso_estagio) >to_char(V_admissao.data_admis,'yyyy'+4) <ADD_MONTHS(V_datafim,12) -- +4  meses
                    V_recesso_estag := V_recesso_estag +1;
                    end if;
                      if count(recesso_estagio) >to_char(V_admissao.data_admis,'yyyy'+4) <ADD_MONTHS(V_datafim,12) -- +4  meses
                    V_recesso_estag := V_recesso_estag +1; --V_ultimaferias := V_ultimaferias +1;
                    end if;
             -- Insert into rh_ferias
              -- (recesso_estagio)
            --  VALUES
            --   (V_recesso_estag,add_months(V_admissao,12)-1,1); 
            end;
          end if;
-----------------------------------------/code]
Avatar do usuário
dr_gori
Moderador
Moderador
Mensagens: 5023
Registrado em: Seg, 03 Mai 2004 3:08 pm
Localização: Portland, OR USA
Contato:
Thomas F. G

Você já respondeu a dúvida de alguém hoje?
https://glufke.net/oracle/search.php?search_id=unanswered

Acho que a questão é calcular a quantidade de meses entre as duas datas. Com base nisso, calcular a quantidade de dias.

Algo assim:

Selecionar tudo

with tab as
(select to_date('15-jan-2021') dataini, to_date('30-jun-2021') datafim from dual union all
 select to_date('10-jan-2021') dataini, to_date('20-may-2021') datafim from dual union all
 select to_date('20-jan-2021') dataini, to_date('15-dec-2021') datafim from dual union all
 select to_date('20-jan-2021') dataini, to_date('15-mar-2021') datafim from dual union all 
 select to_date('15-jan-2020') dataini, to_date('30-jun-2021') datafim from dual 
)
--select comeca aqui.
select 
  x.*
, case when x.qtd_meses >=12                    then 30
       when x.qtd_meses >=6 and x.qtd_meses <12 then 20
       when x.qtd_meses >=4 and x.qtd_meses <6  then 15
  end qtd_dias
from (
  select 
    dataini
  , datafim
  , months_between(datafim, dataini) qtd_meses
  from tab
  ) x

Selecionar tudo

DATAINI     DATAFIM      QTD_MESES   QTD_DIAS
----------- ----------- ---------- ----------
15-Jan-21   30-Jun-21   5.48387096         15
10-Jan-21   20-May-21   4.32258064         15
20-Jan-21   15-Dec-21   10.8387096         20
20-Jan-21   15-Mar-21   1.83870967 
15-Jan-20   30-Jun-21   17.4838709         30

SQL> 
Mas eu acho que existem muito mais regras "ocultas".
* Essa quantidade de dias é por ANO ?
* Se o estagiário já tirou alguns dias, deve considerar apenas a diferença ?
* Se não tirar férias em um ano, os dias passam para o próximo ano ?

Em outras palavras: é bem mais complicado que o SQL acima.
Pra fazer esse programa você vai precisar definir exatamente cada situação citada acima e também varias outras.
RodrigoSB
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 3
Registrado em: Seg, 29 Nov 2021 9:57 pm
Localização: Belém

* Essa quantidade de dias é por ANO ?
No caso é por mês, a cada 4 meses, pode tirar a cada 4 meses = 10 dias, 6 meses = 20 dias e 1 ano = 30 dias.

* Se o estagiário já tirou alguns dias, deve considerar apenas a diferença ?

sim se ele tirou 10 dias, tem que sair a diferença do total que ele ainda tem direito no contrato com base nas variaveis de data inicio e fim de contrato

* Se não tirar férias em um ano, os dias passam para o próximo ano ?

Sim
Avatar do usuário
dr_gori
Moderador
Moderador
Mensagens: 5023
Registrado em: Seg, 03 Mai 2004 3:08 pm
Localização: Portland, OR USA
Contato:
Thomas F. G

Você já respondeu a dúvida de alguém hoje?
https://glufke.net/oracle/search.php?search_id=unanswered

Em resumo, você vai ter que tratar cada uma dessas condições.
Vai ter que criar regras pra cada uma dessas opções.
Algo do tipo:
* Calcular quantos dias ele tem direito baseado na quantidade de meses. (Digamos que tem 10 dias).
* Verificar se já foi tirado algum dia. Se sim, subtratir.
* Verificar se tem férias vindo do ano anterior e somar aos dias.

E pode ser que tenha bem mais regras. :-(
Responder
  • Informação
  • Quem está online

    Usuários navegando neste fórum: Nenhum usuário registrado e 1 visitante