import "layer92.dll" UserAlgorithmCalc(&info,&r) { // инициализация локальных переменных int RetFlag = code_Break, crow = info.crow, b3 = info.b3, ikod = info.ikod, kod_alg = info.kod_alg, pos = info.pos, mkat = info.mkat, krabot = info.krabot, tip_s9600 = info.tip_s9600, flag_propusk0 = info.flag_propusk0, z1 = info.z1, z2 = info.z2; double h[4]; double kod = info.kod, n1 = info.n1, d1 = info.d1, d2 = info.d2, bz = info.bz; h[0] = info.h[0], h[1] = info.h[1], h[2] = info.h[2], h[3] = info.h[3]; int rowkod[ROWMAX],i,m,m1,b1,b2,mvrem; char t[20],str[81],str1[81]; double n2,n3,n4,n5,n6,n7,n8,n9,n10,r8,r9,k; /*-----------------------------------------------------*/ /* tip_s9600=0 - функция обработки СУММЫ по строке */ /* (s9600) - обнуляет РВ, если СУММА==0. */ /* tip_s9600=1 - не обнуляет (в спец.случаях) */ /*-----------------------------------------------------*/ /*-----------------------------------------------------*/ /* Если flag_propusk0=1, то расчет данного вида по его */ /* алгоритму производится только через режимы "Расчет */ /* произвольного вида", "Доп.расчеты" и при расчете от-*/ /* дельной строки в "Просмотре, корректировке ЛС". */ /* flag_propusk0=3, то же, что =1, только в этом случае*/ /* программа работает со строкой вида даже если у нее */ /* вышли даты действия (например, для квартал.дотаций).*/ /* В остальных режимах - если есть СУММА, то подается */ /* на корректировку, иначе - вид пропускается в расчете*/ /*-----------------------------------------------------*/ int c=-4096; switch(kod_alg) { // Сюда можно вставлять вызов собственных алгоритмов расчета. // Примеры функций с алгоритмами находятся // в файле SCRIPT\ALGSYS.S // начало описания алгоритмов пользователя // конец описания алгоритмов пользователя // Пример вызова алгоритма пользователя. case 897: return UserAlg897(info,r); //case 4: // return UserAlg4(info,r); // case 712: // return UserAlg712(info,r); default: RetFlag=0; break; } if ( RetFlag ) { info.crow = crow, info.b3 = b3, info.kod = kod, info.ikod = ikod, info.kod_alg = kod_alg, info.n1 = n1, info.d1 = d1, info.d2 = d2, info.pos = pos, info.mkat = mkat, info.krabot = krabot, info.tip_s9600 = tip_s9600, info.flag_propusk0 = flag_propusk0, info.z1 = z1, info.z2 = z2, info.h[0] = h[0], info.h[1] = h[1], info.h[2] = h[2], info.h[3] = h[3], info.bz = bz; if (c<=-4096) c=1; info.c = c; } return RetFlag; } UserAlg897 ( &info, &r ) /* Доплата до МРОТ */ { bool bCalendDays=true; double Epsilon = 0.00001; struct Struct_Alg Work; //значения параметров по умолчанию: 19,86,0,0,0,0 Get_AlgWithParamEx(Work, info.ikod, "19,86,0,0,0,0"); //-- параметр 1 - столбец таблицы входимости (по умолчанию 25) int stolbec =19; int param=atoi(reinterpret_cast_to_string(Work.List_Par[0])); if ( param>0 && param<=99 ) stolbec=param; //-- параметр 2 - Номер сетки для МРОТ (по умолчанию 86) int numberSet=86; param=atoi(reinterpret_cast_to_string(Work.List_Par[1])); if ( param>0 ) numberSet = param; //-- параметр 3 - Номер строки в сетке (по умолчанию 0) int rowSet=0; param=atoi(reinterpret_cast_to_string(Work.List_Par[2])); if ( param > 0 && param <= 999) rowSet=param; //-- параметр 4 - Тип ФРВ: // 0 - в часах (по умолчанию) // 1 - в днях bool bHours= atoi(reinterpret_cast_to_string(Work.List_Par[3]))==0; int idxNorm = bHours?2:1; //-- параметр 5 - Увеличить МРОТ на РК и Северные (постановление КС от 07.12.2017 № 38-П) // 0 - доплата до "чистого МРОТ" (по умолчанию) // 1 - доплата до "МРОТ*(РК + Северные)" bool bUseRk=atoi(reinterpret_cast_to_string(Work.List_Par[4]))!=0; //-- параметр 6 - Особенности расчета доплаты (флаги): // 0x01 - не рассчитывать доплату, если ФРВ/НРВ<1 // 0x02 - Ограничить ФРВ/НРВ единицей // 0x04 - вычислять ФРВ/НРВ через s98() // 0x08 - не заполнять табель (заводят вид "навсегда" и не хотят чтобы у уволенных делался расчет) // 0x10 - не заполнять РВ в виде (мешается в сводах и выборках) int Flag=atoi(reinterpret_cast_to_string(Work.List_Par[5])); bool calcOnlyFullMonth=(Flag & 0x01)!=0; bool limitFrv =(Flag & 0x02)!=0; bool useS98 =(Flag & 0x04)!=0; bool fillTabel =(Flag & 0x08)==0; bool fillRv =(Flag & 0x10)==0; double frv_nrv=1.; if(fillTabel) worktime(info.crow,info.b3,0); /* заполнение рабоч.дней в табеле */ //ФРВ if (useS98) s98(0,frv_nrv); else { if (nkalend==knorm) { if(bCalendDays) { r[2]=info.z2-info.z1+1; } else { if (!bHours) r[2]=dney_v_tab(rsimv,calm,info.z1,info.z2); else skoljko(r[2],data,info.z1,info.z2,rsimv,calm,cht); } } char t[20]; if(fillRv && (info.c=korrv(r,t,0,info.h,flagrow,jf)) != 1) return code_ReturnCode; frv_nrv=r[2]/norm(idxNorm); if(bCalendDays) frv_nrv=r[2]/countday; } // До 04.2018 было окргуление коэффициента. Убрали его только с 04.2018 // чтобы у людей не полез пересчет за прошлые месяцы на копейки. if ( mrasch<364 ) roundd(frv_nrv, 2, frv_nrv); if ( limitFrv && frv_nrv>1+Epsilon ) frv_nrv=1.; //сумма выборки double summ=0.; s100("н",0,stolbec-1,summ); //сумма выборки не может быть отрицательной if(summ<-Epsilon) summ=0.; // Коэффициент занятости из КЧ double k_employ=1.; char strTemp[11]; var D = KDateFromInt_WithDay(countday,mrasch); GetKchValue("k_employ",strTemp,10,D); if (Str_Cmp(strTemp," "," ")!=0) k_employ=atof(strTemp); //"чистый" МРОТ double mrot=0.; int CodOrg = GetOrgForPodr(GetPodrOfCod(info.kod)); if (Value_For_Table_CodO(numberSet, CodOrg, rowSet, data, mrot) == EOF) mrot=info.bz; // Определяемся с районными и северными надбавками double rk_sev = 0.; if( bUseRk ) { rk_sev= DefineRkFull(data+countday/100.,false); //2018.03.20 - процент северных определяем только в том случае, если в ЛС нашли действующую строку вида "северной надбавки" //вид является "северной надбавкой", если у его алгоритм один из: "96,97,186,187" if (FindSevNu(mrasch)) rk_sev += DefineSev(mrasch,0.,0.); } //МРОТ для расчета double mrot_frv_nrv=mrot*k_employ*frv_nrv*(1 + rk_sev); roundd(mrot_frv_nrv, 2, mrot_frv_nrv); info.n1 = ( summ>mrot_frv_nrv || calcOnlyFullMonth && frv_nrv+Epsilon<1. ) ? 0. : mrot_frv_nrv-summ; if( FL_V_ALG && uprc!=NO_SCREEN ) { if( !useS98 ) { infolist.add_record("ФРВ",r[2]); infolist.add_record("НРВ",bCalendDays?countday:norm(idxNorm)); } if ( limitFrv ) infolist.add_record("ФРВ/НРВ не больше 1", "да"); infolist.add_record("ФРВ/НРВ",frv_nrv); infolist.add_record("Столбец выборки",stolbec); infolist.add_record("Сумма выборки",summ); infolist.add_record("-----------------------","------------------------------"); infolist.add_record("Номер сетки для МРОТ",numberSet); infolist.add_record("Номер строки в сетке",rowSet); infolist.add_record("МРОТ",mrot); infolist.add_record("Коэфф.занятости",k_employ); if (bUseRk) infolist.add_record("% РК и Северных", rk_sev*100.); infolist.add_record("МРОТ для расчета",mrot_frv_nrv); infolist.add_record("-----------------------","------------------------------"); if (calcOnlyFullMonth && frv_nrv+Epsilon<1. ) infolist.add_record("Доплата не нужна", "ФРВ/НРВ<1"); infolist.add_record("Доплата",info.n1); } if (!fillRv) r[2] = 0; return code_Break; } UserAlg4(&info,&r) { return SysAlg4(info,r); } UserAlg712(&info,&r) { struct Struct_Alg Work; var mes1=0; var mes2=0; var stolbec=ST_MPREM+1; // символы для выборки // по умолчанию - по всем ненулевым char StrSimv[51]; sprintf(StrSimv,"*"); Get_AlgWithParam(Work,info.ikod); // 31.01.1995 // Work.Count_Par - число паpаметpов для кода алгоpитма //-- параметр 1 - столбец таблицы входимости if(Work.Count_Par > 0) { var i=atoi(reinterpret_cast_to_string(Work.List_Par[0])); if( i > 0 && i <= 99 ) stolbec=i; } //-- параметр 2 - месяц начала выборки (относительно расчетного) // (по умолчанию берется за один текущий месяц) if(Work.Count_Par > 1) { var i=atoi(reinterpret_cast_to_string(Work.List_Par[1])); if( i >= (- PMES) && i <= BMES ) mes1=mes2=i; } //-- параметр 3 - месяц конца выборки (относительно расчетного) // (по умолчанию берется за один месяц, указанный параметром 2) if(Work.Count_Par > 2) { var i=atoi(reinterpret_cast_to_string(Work.List_Par[2])); if( i >= mes1 && i <= BMES ) mes2=i; } //-- параметр 4 - символы выборки if(Work.Count_Par > 3) sprintf(StrSimv,"%.50s",reinterpret_cast_to_string(Work.List_Par[3])); var n5=0.; for(var m=mes1; m<=mes2; m++) { double r9; s1001simv(StrSimv,"*",info.d1,info.d2,m,stolbec-1,r9,4,0); n5+=r9; } // Заполним таблицу уже найденными значениями if(FL_V_ALG && uprc != NO_SCREEN) { infolist.add_record("Месяц начала выборки",mes1); infolist.add_record("Месяц окончания выборки",mes2); infolist.add_record("Столбец выборки",stolbec); infolist.add_record("Символы выборки",StrSimv); infolist.add_record("Сумма выборки",n5); } // А теперь пройдемся по полю кадровой части "procPREM" // И возьмем оттуда все значения процентов, действовавшие // в рассчитываемом месяце info.n1=0.; // обнулили итоговую сумму // Дата конца действия очередного значения процента // В самом начале она равна последнему дню месяца. var DateEnd = CreateObject("KDate"); DateEnd.SetDateII(countday,mrasch); // Найдем дату начала действия очередного значения процента char StrD[21]; GetKchDate("procPREM",StrD,10,DateEnd); var Date=CreateObject("KDate"); Date.SetDate(static_cast_to_string(StrD)); // Если вдруг дата начала пустая или выходит за рамки расчетного // месяца, то установим ее равной первому числу расчетного месяца if ( Date.IsEqI(INVALID_DATE_VALUE) || Date.GetAbs()