create or alter procedure ZPLT_CALCSLVBL ( SIID integer) returns ( SUMMA double precision, BDATE timestamp, EDATE timestamp, ISUMMA double precision, SUMMA1 double precision, ALLDAYS double precision, WRKDAYS integer, HLDDAYS integer, WKNDAYS integer, FCTDAYS double precision, CLCDAYS integer, ALLDAYWITHOUTPAY double precision, ALLBLDAYS integer) as declare variable ID integer; declare variable BLDATE date; declare variable ELDATE date; declare variable MONTHCNT integer; declare variable SLVID integer; declare variable PRSNID integer; declare variable INP_DATE date; declare variable OUT_DATE date; declare variable DAYWTIME double precision; declare variable WTIMEALL double precision; declare variable BLPROC double precision; declare variable MCNT integer; declare variable XDATE date; declare variable DAYOFWEEK integer; declare variable XDAYS integer; declare variable MROUND integer; declare variable CDATE timestamp; declare variable DATE1 timestamp; declare variable DATE2 timestamp; declare variable CALCTYPE integer; declare variable MONTH__SUMMA double precision; declare variable MONTH_DAYS double precision; declare variable MONTH_HLDDAYS integer; declare variable MONTH_WKNDAYS integer; declare variable MONTH_FCTDAYS integer; declare variable WTIME double precision; declare variable MONTH_BLDAYS integer; declare variable DAYWITHOUTPAY double precision; declare variable BCDATE timestamp; declare variable ECDATE timestamp; declare variable BLDAYS integer; declare variable SUBTYP integer; begin Summa = 0.0; SubTyp=0;--вариант расчета суммы дохода при неотработанном полном календарном месяце и больничном во втором месяце работы на предприятии Select CI.ID, CI.blDate, CI.elDate, CI.MonthCnt, CI.SlvID, CI.Proc, CoalEsce(CI.MRound, 0), M.DAT_ from ZpltCalcIncr CI join ZpltCalcSlv S on S.ID=CI.SlvID join ZpltCalcMst M on M.ID=S.MstID where CI.ID=:SIID into :ID, :BLDATE, :ELDATE, :MonthCnt, :SlvID, :BLProc, :MRound, :cDate; CalcType = 0; if (:cDate >= '01.06.2015') then CalcType = 1; if (:ID is Null) then begin Suspend; Exit; end Select PrsnID from ZpltCalcSlv where ID=:SlvID into :PrsnID; Select Inp_Date, DayWTime from Personal where ID = :PrsnID into :Inp_Date, :DayWTime; Select Result from F_ElapsedDays(:blDate,:elDate) into :BLDays; BLDays = :BLDays + 1; --Начальная дата при наличии нескольких переходящих неприрывных больничных out_date = :blDate; while (out_date is not null) do begin eDate = :out_date; /* начальная дата больничного */ out_date = (select first 1 CI.blDate from ZpltCalcSlv S join ZpltCalcIncr CI on CI.SlvID=S.ID and CI.blDate is not Null and CI.elDate is not Null join ZpltIncr I on I.ID=CI.IncrID and I.System_Flag in (3, 8, 9) where S.PrsnID=:PrsnID and CI.elDate=:out_date-1.0 order by 1); end Out_date= :edate; /* первый день месяца */ Select xDate from f_MonthFirstDay(:eDate) into :eDate; /* последний день предыдущего месяца */ eDate = :eDate - 1.0; /* Начало периода */ mCnt = -:MonthCnt+1; Select xDate from F_AddMonth(:eDate, :mCnt) into :bDate; Select xDate from F_MonthFirstDay(:bDate) into :bDate; --Определяем дату начала периода для случаев: if (CalcType=1) then begin --сотрудник работает менее 12 месяцев if (bDateDate2) then begin bDate=:Inp_Date; --для случаев меньше календарного месяца берем период от последнего дня неприрывных больничных eDate=:out_date-1; end end end AllDays = 0; /* выходные и рабочие дни */ WrkDays = 0; HldDays = 0; WknDays = 0; iSumma = 0; AllDayWithOutPay=0.0; AllBlDays=0.0; WTimeAll=0.0; /*Суммированние данных расчет помесячной поцедуры расчета больничных*/ for select f.bdate, f.edate from F_MONTHS_DATASET(:bDate, :eDate) f into :bcdate, :ecdate do begin --Для случаев, когда сотрудник отработал меньше месяца if (:bcdate<:bdate) then bcdate=:bdate; --Только для случаев когда не выбран расчет по минимальной зп SubTyp<>3 и сотрудник получил больничный во втором месяце трудовых отношений if ((extract(month from :ecdate)-extract(month from :edate)=0)and (:ecdate>:edate)) then begin ecdate=:edate; if ((extract(month from :edate)-extract(month from :bdate)=1) and (SubTyp<>3)) then SubTyp=2; end select Mbl.month__summa, mbl.month_days, mbl.month_hlddays, mbl.month_wkndays, mbl.month_fctdays, mbl.daywithoutpay, mbl.wtime, mbl.month_bldays from ZPLT_CALCSLVBL1(:prsnid, :bcdate, :ecdate, :bldate, :subtyp) MBl into :month__summa, :month_days, :month_hlddays, :month_wkndays, :month_fctdays, :daywithoutpay, :wtime, :month_bldays; AllDays = :AllDays + :Month_Days; /* выходные и рабочие дни */ WrkDays = :WrkDays +(:Month_Days-:Month_HldDays-:Month_WknDays); HldDays = :HldDays + :Month_HldDays; WknDays = :WknDays + :Month_WknDays; iSumma = :iSumma + :month__summa; WTimeAll = :WTimeAll + :WTime; AllBlDays = :AllBldays + :Month_BlDays; AllDayWithOutPay = :AllDayWithOutPay+:DayWithOutPay; end /* расчетные дни для начисления */ xDate = :blDate; ClcDays = 0; while (:xDate <= :elDate) do begin ClcDays = ClcDays + 1; Select Result from F_DayOfWeek(:xDate) into :DayOfWeek; if (:DayOfWeek in (5,6)) then ClcDays = ClcDays - 1; xDate = :xDate + 1; end select Days from Zplt_HldDays(:blDate, :elDate) into :xDays; ClcDays = :ClcDays - :xDays; if (:DayWTime=0 or :DayWTime is Null) then DayWTime = 8; FctDays = :WTimeAll / :DayWTime; -- Среднедневная зарплата Summa1 = :iSumma / (:WTimeAll / :DayWTime); /*Расчет больничного после 2015 года*/ if (:CalcType=1) then begin FctDays = :alldays-:alldaywithoutpay-:Allbldays; ClcDays = :BlDays; end Summa1 = :iSumma / :FctDays; -- Приводим к целым копейкам if (:MRound = 1) then Summa1 = Cast((Summa1 * 100.00) as integer) / 100.00; -- Сумма больничных Summa = :Summa1 * :ClcDays / 100.00 * :BLProc; -- Приводим к целым копейкам Summa = Cast(Cast((Summa * 100.0) as Integer) as double precision) / 100.0; Suspend; end