ALTER PROCEDURE "dba"."pl_resdef"( in a_resdefnr integer, in a_perlop date )
BEGIN
  declare ld_kups date;
  declare ld_kuup1 date;
  declare ld_kuup2 date;
  declare ld_kuup2orig date;
  declare ld_peralg date;
  declare ld_perlop date;
  declare li_lepnr integer;
  declare li_peatnr integer;
  declare ldc_kestvus decimal(15,3);
  declare ldc_paevi decimal(15,3);
  declare li_pvi integer;
  declare li_peatatud integer;
  declare ldc_arvestatud decimal(15,3);
  declare ldc_saadud decimal(15,3);
  declare ldc_algjaak decimal(15,3);
  declare li_aasta numeric(4);
  declare li_last_aasta numeric(4);
  declare li_aegub_tun smallint;
  declare li_aegub_arv smallint;
  declare err_notfound exception for sqlstate value '02000';
  declare c_gl_pl_resdef dynamic scroll cursor for select aasta,days(perlop,1),arvestatud-saadud from gl_pl_resdef order by aasta;
  delete from gl_pl_resdef;
-- andmete lugemine
  select yld_aegub_tun,yld_aegub_arv into li_aegub_tun,li_aegub_arv from pl_konfm where id=1;
  if li_aegub_tun is null or li_aegub_tun=0 then
    set li_aegub_tun=1
  end if;
  if li_aegub_arv is null or li_aegub_arv<0 then
    set li_aegub_arv=1
  end if;
  select if pl_resdef.kuup1 is null then pa_leping.kuup1 else pl_resdef.kuup1 endif,if pl_resdef.kuup2 is null then pa_leping.kuup2 else pl_resdef.kuup2 endif,pl_resdef.lepnr,pl_resdef.peatnr,pl_resdef.kestvus,if pl_resdef.aegub_tun is null or pl_resdef.aegub_tun=0 then li_aegub_tun else pl_resdef.aegub_tun endif,if pl_resdef.aegub_tun is null or pl_resdef.aegub_tun=0 or pl_resdef.aegub_arv is null or pl_resdef.aegub_arv<0 then li_aegub_arv else pl_resdef.aegub_arv endif, if pl_resdef.algjaak is null then 0 else pl_resdef.algjaak endif
    into ld_kuup1,ld_kuup2,li_lepnr,li_peatnr,ldc_kestvus,li_aegub_tun,li_aegub_arv,ldc_algjaak
    from pl_resdef left outer join pa_leping on pl_resdef.lepnr=pa_leping.lepnr
    where pl_resdef.resdefnr=a_resdefnr;
  set ld_kuup2orig=ld_kuup2;
  if ld_kuup2 is null or ld_kuup2>a_perlop then
    set ld_kuup2=a_perlop
  end if;
-- tsykkel yle kogu perioodi aastate loikes
  set ld_kups=ld_kuup1;
  aastad_loop: while ld_kups <= ld_kuup2 loop
-- alamperioodi (aasta) algus ja lopp
    set ld_peralg=ld_kups;
    if years(ld_kups)<years(ld_kuup2) then
      set ld_perlop=ymd(years(ld_kups),12,31)
    else
      set ld_perlop=ld_kuup2
    end if;
-- alamperioodi paevade arv
    set ldc_paevi=datediff(day,ld_peralg,ld_perlop)+1;
-- alamperioodi paevade arv, mille eest ei arvestata puhkust
    select sum(get_kp_arv_per_pta(if akuup<ld_peralg then ld_peralg else akuup endif,if lkuup>ld_perlop then ld_perlop else lkuup endif)) into li_peatatud from pa_tgraaf left outer join peatlist on pa_tgraaf.peatnr = peatlist.peatnr
      where pa_tgraaf.lepnr=li_lepnr and pa_tgraaf.akuup <= ld_perlop and pa_tgraaf.lkuup >= ld_peralg and peatlist.emta=1;
    if li_peatatud is null then
      set li_peatatud=0
    end if;
-- aasta paevade arv
    set li_pvi=get_kp_arv_per_pta(ymd(years(ld_peralg),1,1),ymd(years(ld_peralg),12,31));
-- puhkuse paevade arvestamine
    if li_pvi=ldc_paevi-li_peatatud then
      set ldc_arvestatud=ldc_kestvus
    else
      set ldc_arvestatud=Round(ldc_kestvus/li_pvi*(ldc_paevi-li_peatatud),3)
    end if;
-- valja voetud puhkuse paevad
    select sum(get_kp_arv_per(if (eest_aasta is null or eest_aasta<=2000) and akuup<ld_peralg then ld_peralg else akuup endif,if (eest_aasta is null or eest_aasta<=2000) and lkuup>ld_perlop then ld_perlop else lkuup endif))
      into ldc_saadud
      from pa_tgraaf
      where pa_tgraaf.lepnr=li_lepnr and
            pa_tgraaf.peatnr=li_peatnr and
         (((pa_tgraaf.eest_aasta is null or pa_tgraaf.eest_aasta<=2000) and pa_tgraaf.akuup <= ld_perlop and pa_tgraaf.lkuup >= ld_peralg) or
           (pa_tgraaf.eest_aasta is not null and pa_tgraaf.eest_aasta=years(ld_peralg) and pa_tgraaf.akuup <= a_perlop));
    if ldc_saadud is null then
      set ldc_saadud=0
    end if;
-- ajutise kande lisamine
    insert into gl_pl_resdef(aasta,peralg,perlop,paevi,peatatud,arvestatud,saadud) values (years(ld_peralg),ld_peralg,ld_perlop,ldc_paevi,li_peatatud,ldc_arvestatud+ldc_algjaak,ldc_saadud);
    set ldc_algjaak=0;
    set ld_kups=days(ld_perlop,1)
  end loop aastad_loop;
-- aegunud
  set ldc_saadud=0;
  open c_gl_pl_resdef;
  resdef_loop: loop
    fetch next c_gl_pl_resdef into li_aasta,ld_peralg,ldc_paevi;
    if sqlstate = err_notfound then
      leave resdef_loop
    end if;
-- saamata või ette saadud paevade summeerimine
    set ldc_saadud=ldc_saadud+ldc_paevi;
-- kui on saamata päevi
    if ldc_saadud>0 then
-- fiks aegumise perioodi arvutamine
      if li_aegub_tun=2 then
        set ld_perlop=days(ld_peralg,li_aegub_arv);
      else
        set ld_perlop=years(ld_peralg,li_aegub_arv);
      end if;
      set ld_perlop=days(ld_perlop,-1);
-- kas on aegumise pikendamise paevi fiks perioodis
      select sum(get_kp_arv_per_pta(if akuup<ld_peralg then ld_peralg else akuup endif,if lkuup>ld_perlop then ld_perlop else lkuup endif)) into li_peatatud from pa_tgraaf left outer join peatlist on pa_tgraaf.peatnr = peatlist.peatnr
        where pa_tgraaf.lepnr=li_lepnr and pa_tgraaf.akuup<=ld_perlop and pa_tgraaf.lkuup>=ld_peralg and peatlist.aegub=1;
      if li_peatatud is null then
        set li_peatatud=0
      end if;
-- tsykkel kuni pikendamise perioodis on veel aegumise pikendamise paevi
      per_loop: while li_peatatud>0 loop
-- uus aegumise pikendamise periood
        set ld_peralg=days(ld_perlop,1);
        set ld_perlop=days(ld_peralg,li_peatatud);
        set ld_perlop=days(ld_perlop,-1);
-- kas on aegumise pikendamise paevi pikendamise perioodis
        select sum(get_kp_arv_per_pta(if akuup<ld_peralg then ld_peralg else akuup endif,if lkuup>ld_perlop then ld_perlop else lkuup endif)) into li_peatatud from pa_tgraaf left outer join peatlist on pa_tgraaf.peatnr=peatlist.peatnr
          where pa_tgraaf.lepnr=li_lepnr and pa_tgraaf.akuup<=ld_perlop and pa_tgraaf.lkuup>=ld_peralg and peatlist.aegub=1;
        if li_peatatud is null then
          set li_peatatud=0
        end if;
      end loop per_loop;
-- kui aegumise kuupaev on väiksem, kui etteantud kuupaev, siis salvestada aegunud paevad
      if ld_perlop<a_perlop then
        update gl_pl_resdef set aegunud=ldc_saadud, aegunudkuup=days(ld_perlop,1) where aasta=li_aasta;
        set ldc_saadud=0
      end if;
    end if;
    set li_last_aasta=li_aasta;
  end loop resdef_loop;
  close c_gl_pl_resdef;
-- kui tootaja on lahkunud, siis nullitakse paevad
  if ld_kuup2orig is not null and a_perlop>ld_kuup2orig then
    update gl_pl_resdef set aegunud=aegunud+ldc_saadud, aegunudkuup=days(ld_kuup2orig,1) where aasta=li_last_aasta;
  end if;
END