ALTER PROCEDURE "dba"."dk_ls_kan"(in a_objnr integer,in a_kuup date,in a_user_code integer,in a_arvepaev smallint, in a_yksusnr integer default 0)
begin
  declare li_sisse integer;
  declare li_exit smallint;
  declare li_kb_back smallint;
  declare ll_maksuid integer;
  declare ll_id_autoviivis integer;
  declare ls_maksukood char(16);
  declare ls_ritm char(1);
  -- arve koostamise kuu esimene paev
  declare ld_firstday date;
  -- arvestuse periood
  declare ld_peralg date;
  declare ld_perlop date;
  -- maksustatava periood
  declare ld_akuup date;
  declare ld_lkuup date;
  -- koguse kuupaev
  declare ld_kogused_kuup date;
  declare ld_taskuup date;
  declare ll_servicenr integer;
  declare ls_otseknr char(30);
  declare ll_panknr integer;
  declare ll_partnr integer;
  declare ll_yksusnr integer;
  declare ll_nr integer;
  declare ll_maksnr integer;
  declare ls_tulnud char(100);
  declare ls_viitnr char(35);
  declare ls_info char(300);
  declare ls_ls_laps_info1 char(100);
  declare ls_taiendus char(200);
  declare ldc_par1 numeric(18,6);
  declare ldc_limiit numeric(10,2);
  declare ldc_par2 numeric(15,3);
  declare ldc_par2koguskoef numeric(15,6);
  declare ldc_par3 numeric(15,3);
  declare ldc_soodpiir decimal(20,6);
  declare ldc_soodprots decimal(20,6);
  declare ldc_summa numeric(15,2);
  declare ldc_summa2 numeric(15,2);
  declare ldc_summa3 numeric(15,2);
  declare ldc_kogus numeric(15,6);
  declare ldc_nait numeric(15,3);
  declare ldc_eelmnait numeric(15,3);
  declare ldc_hind numeric(15,6);
  declare ldc_dhind numeric(15,6);
  declare ldc_makshind numeric(15,6);
  declare ldc_kogushind numeric(15,6);
  declare ldc_pvi1 numeric(15,3);
  declare ldc_pvi2 numeric(15,3);
  declare ll_yhiknr integer;
  declare ll_kbnr integer;
  declare ldc_kb_protsent numeric(15,3);
  declare ls_konto char(7);
  declare ll_asutnr integer;
  declare ll_saajanr integer;
  declare ll_meetnr integer;
  declare ll_kulnr integer;
  declare ll_talnr integer;
  declare ll_artnr integer;
  declare ll_tulnr integer;
  declare ll_objectnr integer;
  declare ll_osaknr integer;
  declare ll_subjectnr integer;
  declare ll_suundnr integer;
  declare ll_taotnr integer;
  declare ll_alliknr integer;
  declare ll_ravonr integer;
  declare li_arveper smallint;
  declare li_nait smallint;
  declare li_eelmnait smallint;
  declare li_par1 smallint;
  declare li_arvedefinfo smallint;
  declare li_arvekogusinfo smallint;
  declare li_taiendus smallint;
  declare li_kodarve smallint;
  declare li_tp_arv_per smallint;
  declare li_kp_arv_per_pta smallint;
  declare li_kogusyks smallint;
  declare ls_kokinfo char(300);
  declare ls_definfo char(200);
  declare ls_kogusinfo char(100);
  declare ldc_qprk numeric(15,10);
  declare ldc_ts numeric(15,6);
  declare ldc_tv numeric(15,6);
  declare ldc_tav numeric(15,6);
  declare ldc_kpa numeric(15,6);
  declare ls_kunde_kood char(30);
  declare ls_arvenr char(30);
  declare err_notfound exception for sqlstate value '02000';
  declare c_maksud dynamic scroll cursor for
    select ls_maksud.id,
           if ls_maksud.info is null then '' else ls_maksud.info endif,
           ls_laps.asutnr,
           ls_laps.saajanr,
           if ls_laps.servicenr is null then asulist_a.servicenr else ls_laps.servicenr endif,
           if ls_laps.otseknr is null or trim(ls_laps.otseknr) = '' then (if li_sisse=1 then asulist_a.otseknr else (if asulist_b.panknr is null then asulist_a.sarve else asulist_b.sarve endif) endif) else ls_laps.otseknr endif,
           if ls_laps.otseknr is null or trim(ls_laps.otseknr) = '' then (if li_sisse=1 then asulist_a.panknr else (if asulist_b.panknr is null then asulist_a.panknr else asulist_b.panknr endif) endif) else ls_laps.panknr endif,
           ls_laps.info1,
           ls_laps.id_autoviivis,
           if ls_kunde.kood is null or Length(Trim(ls_kunde.kood))=0 then trim(convert(char(15),ls_kunde.lapsnr)) else ls_kunde.kood endif,
           ls_maksud.nr,
           ls_makslist.maksnr,
           if ls_makslist.maksukood is null then '' else ls_makslist.maksukood endif,
           if ls_makslist.tekst is null or Length(Trim(ls_makslist.tekst))=0 then ls_makslist.nimi else ls_makslist.tekst endif,
           ls_makslist.kogusyks,
           ls_makslist.ritm,
           ls_makslist.yhiknr,
           ls_makslist.kbnr,
           ls_makslist.kb_back,
           kblist.protsent,
           dateadd(month,ls_makslist.arvestkuu+ls_makslist.arvestper,ld_firstday) as peralg,
           get_perlop(dateadd(month,ls_makslist.arvestkuu,ld_firstday)) as perlop,
           if (ls_makslist.lkuup is null or ls_makslist.lkuup>=perlop or (ls_makslist.lkuup<ls_maksud.akuup)) then (if (ls_maksud.akuup<peralg) then peralg else ls_maksud.akuup endif) else (if (ls_makslist.lkuup<peralg) then peralg else dateadd(day, 1,ls_makslist.lkuup) endif) endif as maksud_akuup,
           if (ls_makslist.akuup is null or ls_makslist.akuup<=peralg or (ls_maksud.lkuup is not null and ls_makslist.akuup>ls_maksud.lkuup)) then (if (ls_maksud.lkuup is null or ls_maksud.lkuup>perlop) then perlop else ls_maksud.lkuup endif) else (if (ls_makslist.akuup>perlop) then perlop else dateadd(day,-1,ls_makslist.akuup) endif) endif as maksud_lkuup,
           ls_makslist.soodpiir,
           ls_makslist.soodprots,
           if ls_yksus.tastaht > 0 then days(a_kuup,ls_yksus.tastaht) else (if asulist_a.tastaht is null then a_kuup else days(a_kuup,asulist_a.tastaht) endif) endif,
           if li_sisse=1 then asulist_a.viitnr_mulle else asulist_a.viitnr_talle endif,
           ls_maksud.par1,
           ls_maksud.par2,
           ls_maksud.par3,
           ls_maksud.makshind,
           ls_maksud.limiit,
           ls_yksus.yksusnr,
           if li_taiendus=1 then ls_yksus.nimi else '' endif,
           coalesce(ls_makslist.konto,ls_yksus.konto),
           coalesce(ls_maksud.meetnr,ls_makslist.meetnr,ls_yksus.meetnr),
           coalesce(ls_maksud.kulnr,ls_makslist.kulnr,ls_yksus.kulnr),
           coalesce(ls_maksud.talnr,ls_makslist.talnr,ls_yksus.talnr),
           coalesce(ls_makslist.artnr,ls_yksus.artnr),
           coalesce(ls_makslist.tulnr,ls_yksus.tulnr),
           coalesce(ls_maksud.objectnr,ls_makslist.objectnr,ls_yksus.objectnr),
           coalesce(ls_maksud.osaknr,ls_makslist.osaknr,ls_yksus.osaknr),
           coalesce(ls_maksud.subjectnr,ls_makslist.subjectnr,ls_yksus.subjectnr),
           coalesce(ls_maksud.suundnr,ls_makslist.suundnr,ls_yksus.suundnr),
           coalesce(ls_maksud.taotnr,ls_makslist.taotnr,ls_yksus.taotnr),
           coalesce(ls_makslist.alliknr,ls_yksus.alliknr),
           coalesce(ls_makslist.ravonr,ls_yksus.ravonr),
           ls_makslist.partnr
      from ls_maksud left outer join ls_makslist on ls_maksud.maksnr = ls_makslist.maksnr
                     left outer join ls_yksus on ls_maksud.yksusnr = ls_yksus.yksusnr
                     left outer join ls_laps on ls_maksud.lapsnr = ls_laps.lapsnr
                     left outer join ls_kunde on ls_maksud.lapsnr = ls_kunde.lapsnr and ls_maksud.yksusnr = ls_kunde.yksusnr
                     left outer join asulist as asulist_a on ls_laps.asutnr = asulist_a.asutnr
                     left outer join asulist as asulist_b on ls_laps.saajanr = asulist_b.asutnr
                     left outer join kblist on ls_makslist.kbnr = kblist.kbnr
      where ls_yksus.dk_objnr = a_objnr and
           (ls_maksud.yksusnr = a_yksusnr or a_yksusnr=0) and
           (ls_kunde.lkuup is null or peralg<ls_kunde.lkuup) and
           maksud_akuup<=maksud_lkuup and
          ((a_arvepaev=0 and ls_yksus.arvepaev=0) or (a_arvepaev=1 and get_kuupaev_paev(ls_yksus.arvepaev,a_kuup) = a_kuup)) and
           (ls_makslist.arvestper = 0 or(ls_makslist.arvestper = -2 and month(perlop) in( 3,6,9,12) ) or(ls_makslist.arvestper = -11 and month(perlop) = 12)) and
           (ls_maksud.akuup<=perlop and(ls_maksud.lkuup is null or ls_maksud.lkuup>=peralg)) and
           (ls_makslist.akuup is null or ls_makslist.akuup>peralg or (ls_makslist.akuup<=peralg and ls_makslist.lkuup is not null and ls_makslist.lkuup<perlop));
  declare c_kogused dynamic scroll cursor for select ls_kogused.kogus,ls_kogused.par2,ls_kogused.kuup,ls_kogused.nait,ls_kogused."info", if ls_kogused.summa is null then 0 else ls_kogused.summa endif from ls_kogused where ls_kogused.maksuid = ll_maksuid and ls_kogused.kuup >= ld_peralg and ls_kogused.kuup <= ld_perlop;
  delete from gl_dk_kanne;
  set ld_firstday=get_peralg(a_kuup);
  select if dk_obj.spank=1 then 0 else 1 endif into li_sisse from dk_obj where dk_obj.objnr=a_objnr;
  select dk_konfm.yld_imp_arveper,dk_konfm.yld_imp_nait,dk_konfm.yld_imp_eelmnait,dk_konfm.yld_imp_par1,dk_konfm.yld_imp_arvedefinfo,dk_konfm.yld_imp_arvekogusinfo,dk_konfm.yld_imp_taiendus,dk_konfm.yld_imp_kodarve into li_arveper,li_nait,li_eelmnait,li_par1,li_arvedefinfo,li_arvekogusinfo,li_taiendus,li_kodarve from dk_konfm where dk_konfm.id = 1;
  select if qprk is null then 0 else qprk endif,if ts is null then 0 else ts endif,if tv is null then 0 else tv endif, if tav is null then 0 else tav endif,if kpa is null then 0 else kpa endif into ldc_qprk,ldc_ts,ldc_tv,ldc_tav,ldc_kpa from ls_konfm where ls_konfm."id"=1;
  open c_maksud;
  maksud_loop: loop
    fetch next c_maksud into ll_maksuid,ls_definfo,ll_asutnr,ll_saajanr,ll_servicenr,ls_otseknr,ll_panknr,ls_ls_laps_info1,ll_id_autoviivis,ls_kunde_kood,ll_nr,ll_maksnr,ls_maksukood,ls_info,li_kogusyks,ls_ritm,ll_yhiknr,ll_kbnr,li_kb_back,ldc_kb_protsent,ld_peralg,ld_perlop,ld_akuup,ld_lkuup,ldc_soodpiir,ldc_soodprots,ld_taskuup,ls_viitnr,ldc_par1,ldc_par2,ldc_par3,ldc_makshind,ldc_limiit,ll_yksusnr,ls_taiendus,ls_konto,ll_meetnr,ll_kulnr,ll_talnr,ll_artnr,ll_tulnr,ll_objectnr,ll_osaknr,ll_subjectnr,ll_suundnr,ll_taotnr,ll_alliknr,ll_ravonr,ll_partnr;
    if sqlstate = err_notfound then
      leave maksud_loop
    end if;
    set ls_tulnud='Arved '+ls_maksukood + ' yksusnr ' + trim(convert(char(20),ll_yksusnr)) + ';';
    set li_exit=0;
    if li_arvedefinfo = 1 and Length(ls_definfo) > 0 then
      set ls_info=ls_info+' '+ls_definfo
    end if;
    if ldc_makshind is null or ldc_makshind=0 then
      set ldc_hind=get_makshind(ll_maksnr,ld_perlop,ll_yksusnr,ll_nr)
    else
      set ldc_hind=ldc_makshind
    end if;
    if li_kodarve=1 then
      set ls_arvenr=convert(char(4),years(ld_perlop)) + '_';
      if month(ld_peralg)=month(ld_perlop) then
        set ls_arvenr=ls_arvenr + Right('00'+trim(convert(char(2),month(ld_perlop))),2)
      else
        case month(ld_perlop) when '3' then
          set ls_arvenr=ls_arvenr+'I' when '6' then
          set ls_arvenr=ls_arvenr+'II' when '9' then
          set ls_arvenr=ls_arvenr+'III' when '12' then
          set ls_arvenr=ls_arvenr+'IV'
        end case;
      end if;
      set ls_arvenr=ls_arvenr+'_'+ls_kunde_kood
    else
      set ls_arvenr = null
    end if;
    set li_tp_arv_per=get_tp_arv_per(ld_peralg,ld_perlop);
    set li_kp_arv_per_pta=get_kp_arv_per_pta(ld_peralg,ld_perlop);
    set ldc_dhind=ldc_hind;
    if ls_ritm='h' or ls_ritm='i' then
      select if qprk is null or qprk=0 then ldc_qprk else qprk endif, if ts is null or ts=0 then ldc_ts else ts endif, if tv is null or tv=0 then ldc_tv else tv endif, if tav is null or tav=0 then ldc_tav else tav endif, if kpa is null or kpa=0 then ldc_kpa else kpa endif into ldc_qprk,ldc_ts,ldc_tv,ldc_tav,ldc_kpa from ls_yksus where ls_yksus.yksusnr=ll_yksusnr;
      if ldc_ts-ldc_tav<>0 then
        if ls_ritm='h' then
          set ldc_hind=((ldc_par1*ldc_qprk*(ldc_ts-ldc_tv))/(ldc_ts-ldc_tav))*24*ldc_hind
        else
          set ldc_hind=((ldc_qprk*(ldc_ts-ldc_tv))/(ldc_ts-ldc_tav))*24*ldc_hind
        end if
      else
        set ldc_hind=0
      end if
    end if;
    -- hind jagatakse toopaevadega
    if ls_ritm in('d','j') then
      set ldc_hind=Round(ldc_hind/li_tp_arv_per,6);
    end if;
    open c_kogused;
    kogused_loop: loop
      set ldc_summa=0;
      set ldc_kogus=0;
      set ldc_par2koguskoef=0;
      set ls_kogusinfo='';
      -- koguse leidmine soltuvalt algoritmist
      case ls_ritm
      when 'a' then
        set ldc_pvi1=(datediff(day,ld_akuup,ld_lkuup)+1);
        set ldc_pvi2=(datediff(day,ld_peralg,ld_perlop)+1);
        if ldc_pvi2=0 or ldc_pvi1=ldc_pvi2 then
          set ldc_kogus=1
        else
          set ldc_kogus=Round(ldc_pvi1/ldc_pvi2,3)
        end if;
        set li_exit=2
      when 'e' then
        set ldc_kogus=ldc_par1;
        set li_exit=2
      else
        fetch next c_kogused into ldc_kogus,ldc_par2koguskoef,ld_kogused_kuup,ldc_nait,ls_kogusinfo,ldc_summa;
        if sqlstate = err_notfound then
          if li_exit = 0 then
            set li_exit=2
          else
            leave kogused_loop
          end if
        end if;
        set li_exit=1
      end case
      ;
      if ldc_kogus is null then
        set ldc_kogus=0
      end if;
      -- automaatne kogus
      if ls_ritm in( 'f','d','g','h','i') and ldc_kogus = 0 then
        if ls_ritm='g' then
          set ldc_kogus=get_kp_arv_per_pta(ld_akuup,ld_lkuup)
        elseif ls_ritm='h' or ls_ritm='i' then
          if ldc_kpa=31 then
            set ldc_kogus=get_kp_arv_per_pta(ld_akuup,ld_lkuup)
          else
            set ldc_kogus=ldc_kpa
          end if
        else
          set ldc_kogus=get_tp_arv_per(ld_akuup,ld_lkuup)
        end if
      end if;
      if ldc_kogus <> 0 then
        set ldc_kogushind=ldc_hind;
        -- koguse koefitsent
        if ldc_par2koguskoef is not null and ldc_par2koguskoef <> 0 then
          set ldc_kogushind=Round(ldc_kogushind*ldc_par2koguskoef,6);
        end if;
        -- summa arvutamine
        if ldc_summa=0 then
          if ls_ritm in('d','j') and ldc_kogus=li_tp_arv_per then
            set ldc_summa=Round(ldc_dhind,2);
          else
            set ldc_summa=Round(ldc_kogus*ldc_kogushind,2);
          end if;
        else
          set ldc_kogushind=Round(ldc_summa/ldc_kogus,6);
          set ldc_dhind=ldc_kogushind;
        end if;
        -- soodustus
        set ldc_summa3=0;
        -- kompensatsioon yle piiri
        if ldc_soodprots is not null and ldc_soodprots>0 then
          if ldc_soodpiir is null then
            set ldc_soodpiir=0
          end if;
          if ldc_kogushind>ldc_soodpiir then
            set ldc_summa3=ldc_summa3+Round(ldc_kogus*((ldc_kogushind-ldc_soodpiir)*ldc_soodprots/100),2)
          end if;
        end if;
        -- soodustuse arvutamine par2 potsendi jargi
        if ldc_par2 is not null and ldc_par2 <> 0 then
          set ldc_summa3=ldc_summa3+Round(ldc_summa*(ldc_par2/100),2)
        end if;
        -- soodustuse arvutamine par3 summa jargi
        if ldc_par3 is not null and ldc_par3 <> 0 then
          if ldc_summa>0 then
            set ldc_summa3=ldc_summa3+ldc_par3
          else
            set ldc_summa3=ldc_summa3-ldc_par3
          end if
        end if;
        -- soodustuse arvutamine limiidi jargi
        if ldc_limiit is not null and ldc_limiit>0 and ldc_summa>0 then
          if ldc_summa-ldc_summa3>ldc_limiit then
            set ldc_summa3=ldc_summa-ldc_limiit
          end if
        end if;
        -- samma vahendamine soodustuse vorra
        if ldc_summa>=0 then
          if ldc_summa3>ldc_summa then
            set ldc_summa3=ldc_summa;
            set ldc_summa=0
          else
            set ldc_summa=ldc_summa-ldc_summa3
          end if;
        else
          if ldc_summa3<ldc_summa then
            set ldc_summa3=ldc_summa;
            set ldc_summa=0
          else
            set ldc_summa=ldc_summa-ldc_summa3
          end if;
        end if;
        -- koormuse korral koguseks on ruutmeetrid
        if ls_ritm='h' or ls_ritm='i' then
          set ldc_kogus=ldc_par1;
          set ldc_kogushind=Round((ldc_summa+ldc_summa3)/ldc_kogus,6)
        end if;
        if ldc_summa <> 0 or ldc_summa3 <> 0 then
          if ll_kbnr is not null and ldc_kb_protsent is not null then
            if li_kb_back=1 then
              set ldc_summa2=Round(ldc_summa*(ldc_kb_protsent/(100+ldc_kb_protsent)),2);
              set ldc_summa=ldc_summa-ldc_summa2;
              set ldc_kogushind=Round((ldc_summa+ldc_summa3)/ldc_kogus,6);
            else
              set ldc_summa2=Round(ldc_summa*ldc_kb_protsent/100,2);
            end if
          else
            set ldc_summa2=0;
          end if;
          set ls_kokinfo=ls_info;
          if li_arvekogusinfo = 1 and Length(ls_kogusinfo) > 0 then
            set ls_kokinfo=ls_kokinfo+' '+ls_kogusinfo
          end if;
          if li_arveper = 1 then
            set ls_kokinfo=ls_kokinfo+' '+dateformat(ld_akuup,'dd.mm.yyyy')+' - '+dateformat(ld_lkuup,'dd.mm.yyyy')
          end if;
          if ls_ritm='c' and li_nait=1 then
            if ldc_nait > 0 then
              if li_eelmnait=1 then
                set ldc_eelmnait=get_eelmnait(ll_maksuid,ld_kogused_kuup);
                set ls_kokinfo = ls_kokinfo+' Näit:'+trim(convert(char(15),ldc_eelmnait))+' - '+trim(convert(char(15),ldc_nait))
              else
                set ls_kokinfo = ls_kokinfo+' Näit:'+trim(convert(char(15),ldc_nait))
              end if;
            end if;
            set ldc_nait=ldc_nait-ldc_eelmnait;
            if li_par1=1 and ldc_par1 is not null and ldc_par1<>0 then
              set ls_kokinfo = ls_kokinfo+' Kogus:'+trim(convert(char(15),ldc_par1))
            end if;
          end if;
          if li_kogusyks=1 then
            set ldc_kogus=1;
            set ldc_kogushind=ldc_summa+ldc_summa3;
          end if;
          insert into gl_dk_kanne( objnr,tulnud,sisse,kuup,summa,"info",konto,asutnr,kulnr,artnr,tulnr,objectnr,user_code,arvekuup,arvenr,taskuup,viitnr,sarve,panknr,kogus,yhiknr,hind,kbnr,summa2,saajanr,osaknr,subjectnr,suundnr,talnr,alliknr,ravonr,partnr,summa3,taiendus,id_maks,meetnr,taotnr,id_autoviivis,servicenr,ls_laps_info1)
                   values( a_objnr,ls_tulnud,li_sisse,if month(ld_perlop) = month(a_kuup) and years(ld_perlop) = years(a_kuup) then a_kuup else ld_perlop endif,ldc_summa,Left(ls_kokinfo,200),ls_konto,ll_asutnr,ll_kulnr,ll_artnr,ll_tulnr,ll_objectnr,a_user_code,a_kuup,ls_arvenr,ld_taskuup,ls_viitnr,ls_otseknr,ll_panknr,ldc_kogus,ll_yhiknr,Round(ldc_kogushind,6),ll_kbnr,ldc_summa2,ll_saajanr,ll_osaknr,ll_subjectnr,ll_suundnr,ll_talnr,ll_alliknr,ll_ravonr,ll_partnr,ldc_summa3,ls_taiendus,ll_maksuid,ll_meetnr,ll_taotnr,ll_id_autoviivis,ll_servicenr,ls_ls_laps_info1)
        end if
      end if;
      if li_exit = 2 then
        leave kogused_loop
      end if
    end loop kogused_loop;
    close c_kogused
  end loop maksud_loop;
  close c_maksud;
-- kustuta kehtetud e-arve avaldused
  update gl_dk_kanne left outer join otsek_service on gl_dk_kanne.servicenr=otsek_service.servicenr set gl_dk_kanne.servicenr=null where otsek_service.akuup>a_kuup or (otsek_service.lkuup is not null and otsek_service.lkuup<a_kuup)
end