import "useful.dll" import "layer4.dll" import "layer92.dll" import "XMachine.dll" UserSub21a() { return 1; // return SysSub21a(); } int DayOfHalfMonthAvansCalc=15; //аванс всегда считаем с 1 по 15 число int avansRow=-1; UserSub21() { //расчет аванса запускаем только по "основной" должности if (GetCommonProp(CMN_SRC_MASS_LS).GetCombine()!=GetGeneralCombineLS()) return 1; //определим точный внутренний код вида "аванса" по основной должности. double avansCode=TryFindAvansCode(501,GetGeneralCombineLS()); if (avansCode<1) //не нашли вид -добавляем { avansCode=AddNewRowToLs(501,GetGeneralCombineLS()); if (avansCode<1) return ESC; //прерываем расчет аванса } //запоминаем текущее состояние ЛС var ts2 = CreateObject("TempCommonSrc"); ts2.TempCommonSrcInitial(CMN_SRC_INT_LS); // - сохранили текущий источник для расчета за месяц rwlsbuf(1); //очищаем ЛС от ВСЕХ сумм у которых месяц начисления совпадает с указанным (т.к. ндфл настроен по месяцу начисления, то месяц принадлежности смотреть не нужно) //!!!НЕ ПЕРЕМЕЩАТЬ этот код вне блоков rwlsbuf, иначе суммы удалятся безвозвратно. KillAllSummInLs(mrasch); //номер строки надо вычислять после очистки!! иначе массив строк сьезжает. avansRow=GetRowForIntCode(avansCode); bRaschHalfMonth=true; double sumAvans; UserCalcSummAvans(sumAvans); bRaschHalfMonth=false; //восстанавливаем ЛС rwlsbuf(0);//восстановили лс в памяти ts2=0; //восстановили текущий источник для расчета за месяц /*if (razovnum && func[8]==2) //расчет запущен из просмотра ЛС -> рассчитанную сумму не сохраняем ( сохраняем только если расчет запущен из Работа->Аванс) и сумму по 301 виду не обнуляем return 1; */ { //пишем в ЛС сумму рассчитанного аванса /* double r[4]; initcrow(avansRow,r,0); int col=s119(mrasch); PutSumm(avansRow,col,sumAvans); PutCashMonth(avansRow,colc2,r[2]);*/ PutSummByCod(mrasch,mrasch,avansCode, sumAvans); toUseal(1); korrls=2; /* менялись значения для строк Н-У в ЛС */ izls(1,0); /* "ЛС не рассчитан" */ } return 1; } UserSub21b() { return SysSub21b(); } TryFindAvansCode(extCode,combine) { //учитываем ист. и объект , указанный в к.ч. int srcCode =GetSrcFromKch(combine); int subjectCode=GetSubjectFromKch(combine); if (IsSrcEmpty(srcCode)) srcCode=CLL_TOTAL_SRC; if (IsSubjectEmpty(subjectCode)) subjectCode=CLL_TOTAL_SUBJECT; var Prob = CreateObject("APropBE"); Prob.Init(srcCode,subjectCode,CLL_TOTAL_PODR,combine); //инициализируем APropBE вн.кодом совместительства int rowkod[ROWMAX];//массив с номерами строк int cntrow=poiskosnkodProp(Extern_To_Intern(extCode),rowkod,0,Prob);//получаем список строк с кодом==kod if (cntrow) FiltrRowkod(rowkod,cntrow, mrasch,1); //фильтр на недействующие в mrasch строки if (cntrow) return GetCode(rowkod[0]); //возвращаем первый "подходящий" внутренний код вида return -1; //не нашли подходящей строки } AddNewRowToLs(extCode,combine) { //учитываем ист. и объект , указанный в к.ч. int srcCode =GetSrcFromKch(combine); int subjectCode=GetSubjectFromKch(combine); if (IsSrcEmpty(srcCode)) srcCode=CLL_TOTAL_SRC; if (IsSubjectEmpty(subjectCode)) subjectCode=CLL_TOTAL_SUBJECT; //устанавливаем фильтр, чтобы строка создалась на нужном КПС var Prop = CreateObject("APropBE"); Prop.SetCombine(combine); Prop.SetSrc(srcCode); Prop.SetSubject(subjectCode); var ts1 = CreateObject("TempCommonSrc"); ts1.TempCommonSrcInitial(CMN_SRC_C_WORK); SetCommonProp(CMN_SRC_C_WORK,Prop); if(otkrsnu(Extern_To_Intern(extCode),data+0.01,205001.01,0,"",0)!=-1) { return GetCode(countkod-1); } char tmp[256];sprintf(tmp,"в ЛС \"%s\" не удалось добавить строку аванса. Прерываем расчет аванса.",GetFioFromKch()); AmbaMessageBox(to_string(tmp),"Ошибка",1,0); return -1; } KillAllSummInLs(mAbs) { var LS = CreateObject("LS"); LS.GetGlobalLS(); var MatrLS = LS.MatrLS(); bool bSummDeleted=false; //цикл по видам for (int i = 0; i < MatrLS .Size(); i++) { var baseElem = MatrLS.GetBaseElem(i); if (!VarHasValue(baseElem)) continue; //2017.10.26 НЕ обнуляем данные по видам, отмеченным "2,4" в 73 столбце /* int code=baseElem.Code; char simTvh=Sim_For_Intern_Cod(code,73-1); if ( simTvh == '2'|| simTvh == '4' ) continue;*/ var sumVect = baseElem.SumVect; if (!VarHasValue(sumVect)) continue; for(int s = 0; s 0.00001 ) { if (sumVect.DeleteRow(s)) s--; //после удаления элемента уменьшаем индекс, чтобы не пропустить элементы. if (!bSummDeleted) bSummDeleted=true; } } } if (bSummDeleted) { toUseal(1);//Перенос сумм из новой матрицы в <старую> матрицу c1. } } UserCalcSummAvans(&summ) { summ=0.; try //добавим отлов исключений, чтобы гарантированно восстановить ЛС { // инициализируем форму ЛС, если выбрали расчет с корректировкой var LSForm; if ( func[5]+func[6] ) { LSForm=CreateObject("LS_Form"); //для WIN создали окно где будет происходить корректировка сумм char buf[100]; rname0(buf,3, 80); LSForm.SetCaption(OemToAnsi("Расчет аванса")+" "+OemToAnsi(buf)); } //вычисляем сумму аванса ( используется ras_normzar() ) summ=UserCalcSummAvansImpl(); //summ=UserCalcSummAvansImpl_v2(); } catch(interface IErrorInfo err) //todo: убрать тело catch { string s;string ss; err.GetDescription(s); // в s будет описание ошибки, err.GetSource(ss);// место ошибки в коде MsgBox(s,ss,MB_ICONERROR); } catch(object err) { SayError(err); } catch(...) { SayUndefinedScriptError(); } } UserCalcSummAvansImpl() { //Запускаем цикл по должностям var CL=CreateObject("CombineList"); var it = CL.CreateIterator(); int countDolgnUv=0;//кол-во должностей, по которым сотрудник уволен double totalRv=0.; //общее кол-во(по всем должностям) отработанных дней за первую половину месяца for (it.SetBegin();!it.IsEnd();it.Next()) //цикл по должностям (it.CurKey() - внутр.код совместительства ) { var tmpComb=CreateObject("TmpCurCombine");tmpComb.Init(it.CurKey()); //устанавливаем должность текущей //21.02.2017 по уволенным не нужно выполнять расчет аванса //пока не придумал ничего лучше чем обнулить по ним весь табель. if(SotrIsUvolByCurrentDolg()||it.CurKey()!=GetGeneralCombineLS()) { ClearTabel(1,countday); //пишем в табель (за весь месяц) нули countDolgnUv++; continue; } ClearTabel(DayOfHalfMonthAvansCalc+1,countday); //пишем в табель (во вторую половину месяца) нули worktime(avansRow,0,0); /* заполнение рабоч.дней в табеле */ totalRv+=dney_v_tab(rsimv,calm,1,DayOfHalfMonthAvansCalc); //перенес этот блок внутрь алгоритма премии //PutPercentMonthlyPrem(); //в РВ 812 вида пишем процет ежемесячной премии tmpComb=0; } if (countDolgnUv==CL.Size() || totalRv<0.00001) //сотрудник уволен по всем должностям или отработанных дней нет return 0.; double result=0.; var DateDop=CreateObject("KDate"); int stolbec=28; //при вызове ras_normzar() info.b3==6 !!! int flags=2+8+20;//учитывать удержания, не заполнять табель "нормой" перед началом расчета if ( func[5]+func[6] ) flags+=1; //показывать расчет //норм заработок считаем только по основной должности var ts = CreateObject("TempCommonSrc"); ts.TempCommonSrcInitial(CMN_SRC_COUNT_LS); var Src=CreateObject("APropBE"); Src.SetCombine(GetGeneralCombineLS()); SetCommonProp(CMN_SRC_COUNT_LS,Src); ras_normzar(stolbec-1,"1",6,flags,result,DateDop); result*=0.87; //ДОПОЛНЯЕМ сумму аванса до 1000 рублей if (result>0.001) //нулевую сумму аванса дополнять до 1000 не надо round2(result,0,1000,result); return result; } UserCalcSummAvansImpl_v2() { //Запускаем цикл по должностям var CL=CreateObject("CombineList"); var it = CL.CreateIterator(); int countDolgnUv=0;//кол-во должностей, по которым сотрудник уволен double totalRv=0.; //общее кол-во(по всем должностям) отработанных дней за первую половину месяца for (it.SetBegin();!it.IsEnd();it.Next()) //цикл по должностям (it.CurKey() - внутр.код совместительства ) { var tmpComb=CreateObject("TmpCurCombine");tmpComb.Init(it.CurKey()); //устанавливаем должность текущей //21.02.2017 по уволенным не нужно выполнять расчет аванса //пока не придумал ничего лучше чем обнулить по ним весь табель. if(SotrIsUvolByCurrentDolg()||it.CurKey()!=GetGeneralCombineLS()) { ClearTabel(1,countday); //пишем в табель (за весь месяц) нули countDolgnUv++; continue; } //ClearTabel(DayOfHalfMonthAvansCalc+1,countday); //пишем в табель (во вторую половину месяца) нули ShowTabelWarnings(); //заменяем табель на нормативный calm=calmras; worktime(avansRow,0,0); /* заполнение рабоч.дней в табеле */ totalRv+=dney_v_tab(rsimv,calm,1,countday); //перенес этот блок внутрь алгоритма премии //PutPercentMonthlyPrem(); //в РВ 812 вида пишем процет ежемесячной премии tmpComb=0; } if (countDolgnUv==CL.Size() || totalRv<0.00001) //сотрудник уволен по всем должностям или отработанных дней нет return 0.; double result=0.; //при вызове ras_normzar() info.b3==6 !!! int flags=2+8+20;//учитывать удержания, не заполнять табель "нормой" перед началом расчета if ( func[5]+func[6] ) flags+=1; //показывать расчет var DateDop=CreateObject("KDate"); int stolbec=26; //берем только оклады //норм заработок считаем только по основной должности var ts = CreateObject("TempCommonSrc"); ts.TempCommonSrcInitial(CMN_SRC_COUNT_LS); var Src=CreateObject("APropBE"); Src.SetCombine(GetGeneralCombineLS()); SetCommonProp(CMN_SRC_COUNT_LS,Src); ras_normzar(stolbec-1,"1",6,flags,result,DateDop); result*=0.4; //ДОПОЛНЯЕМ сумму аванса до 1000 рублей if (result>0.001) //нулевую сумму аванса дополнять до 1000 не надо round2(result,0,1000,result); return result; } int idxTabelMessage =0, idxTabelMessageCount =1; int bTabelMessageRepeatAgain[idxTabelMessageCount];//флаги для показа MsgBoxCheck ShowTabelWarnings() { if(!bTabelMessageRepeatAgain[idxTabelMessage]) { var MapCharacters = CreateObject("MapString"); var CharacterList=MapFromStr("О,У,Т,Б,К,Д",",");; //список символов табеля, для которых нужна расшифровка string oldSim=""; //предыдущий символ var firstDate =KDateFromInt_WithDay(0,mrasch); //дата начала периода для oldSim var lastDate =KDateFromInt_WithDay(0,mrasch); //дата окончания периода для oldSim //цикл по дням табеля for(int d=0;d0 ) sprintf(value,"%s-%s;",firstDate.GetStr(),lastDate.GetStr()); else value=firstDate.GetStr()+";"; if ( !MapCharacters.IsExist(to_string(key)) ) MapCharacters.Add(to_string(key),to_string(value)); else { string oldValue=MapCharacters.GetValue(to_string(key)); string newValue=oldValue+to_string(value); MapCharacters.Add(to_string(key),newValue); } } SotrIsUvolByCurrentDolg() { char str[256];kch_from("data_uv",str); var dUv=KDateFromStr(to_string(str)); var d1=KDateFromInt_WithDay(1,mrasch); //месяц увольнения меньше, либо равен расчетному месяцу if (dUv.IsValid() && dUv.LEM(d1)) return true; return false; } ClearTabel(d1,d2) { s50(mrasch); for(int i=d1;i<=d2;i++) { calm[i-1]='0'; } s145(s120(mrasch),1); }