//============================================================================================= // Функции обеспечивающие работу со спец.выплатами ФСС для медиков и соц. //============================================================================================= //============================================================================================= // Поставочные варианты функций для медиков, которые можно переопределить //============================================================================================= SysFssSvRv_M(strDate,strDBeg,strDEnd) // поставочная функция выборки отработанного времени для медиков (в часах) { double rv = 0.; var d = KDateFromStr(strDate); var dBeg = KDateFromStr(strDBeg); var dEnd = KDateFromStr(strDEnd); if ( !dBeg.IsValid() || dBeg.GetAbs()>d.GetAbs() ) return rv; if ( !dEnd.IsValid() || dEnd.GetAbs()9999 ) FssSvNumFileInDay = FssSvGetNumFile(); var Tabl=CreateObject("CurPrnTbl"); Tabl.Initial(AdrTabl); FillFldSv(Tabl); int cntRcr=Tabl.Count_Rcr(); if ( !cntRcr || (cntRcr==1 && Tabl.Check_Empty_Rcr(0)) ) return 0; char Buf[512]; var mngr = KZ().CreateFssSvManager(); var fuf = mngr.CreateRegistrySv(); // Заполняем атрибуты реестра // устарело fuf.software = FssSvStringToXml(AnsiToOem("Контур-Зарплата"),255); // устарело fuf.versionSoftware = FssSvStringToXml("4.5.607",15); // Информация о составителе реестра fuf.author = FssSvStringToXml(SvRegistryAuthor(),120); fuf.phone = FssSvStringToXml(SvRegistryPhone(),30); fuf.email = FssSvStringToXml(SvRegistryEmail(),40); // ИНН GetEnterpriseVar(AnsiToOem("ИНН"), Buf,255); FreeSpaceString(Buf,3,""); int cntZero = 12-strlen(Buf); for ( int i=0; i255 ) { GetEnterpriseVar(AnsiToOem("ИМЯП2"), Buf2,255); if ( Str_Cmp(Buf2," "," ,.") ) Buf = Buf2; } string employer = FssSvStringToXml(Buf,255); fuf.docType = to_string(docType); // 99 - медики, 98 - соц. fuf.dt1 = FssSvDateToXml(KDateFromStr(Tabl.Text(fldDt1,0))); // 1-ое число отчетного месяца для медиков и начало периода для соц. if ( docType==98 ) { fuf.covid = to_string(atoi(Tabl.Text(fldCovid,0))); // признак обнаружения covid в организации fuf.dt2 = FssSvDateToXml(KDateFromStr(Tabl.Text(fldDt2,0))); // не заполняется для медиков и конец периода для соц. } var CMsg = 0; // Процент выполненной работы CMsg=CreateObject("ProgressBar"); CMsg.Initial(0,100,1); CMsg.SetShowTime(0); int batchNo=0; sprintf(Buf,"%s_%04d",FssSvFilename,FssSvNumFileInDay++); string curNameFile = Buf; int maxRecords = GetCommonCnfInt("MaxRec","fsssv"); for (int rcr = 0; rcr < cntRcr; ++rcr) { if ( !Tabl.Flag_Action_1(rcr) ) continue; ++batchNo; if ( maxRecords && batchNo>maxRecords ) // 999 записей на файл { mngr.SerializeFuf(to_string(Path), fuf); // Первый файл формируем с заданным именем, а все остальные с добавкой char NameFile[512]; sprintf(Buf,"%s_%04d",FssSvFilename,FssSvNumFileInDay++); curNameFile = Buf; makepath(NameFile,drive,dir,curNameFile,ext); Path = NameFile; batchNo = 1; fuf.Items.clear(); } var row = fuf.AddNew(); // Блок "Общие сведения о документе" (commonDocInfo) sprintf(Buf,"%s:%03d",curNameFile,batchNo); row.commonDocInfo.batchNo = to_string(Buf); row.commonDocInfo.typeInfo = atoi(Tabl.Text(fldTypeInfo,rcr)); if ( row.commonDocInfo.typeInfo!=0 ) row.commonDocInfo.recalcReasonCode = to_string(atoi(Tabl.Text(fldRecalcReason,rcr))); // Информация об извещении/отказе if ( Str_Cmp(Tabl.Text(fldRespNo,rcr), "", " ") ) { row.commonDocInfo.respNo = FssSvStringToXml(Tabl.Text(fldRespNo,rcr),10); // в описании формата на 26.11.2020 нет спецификации типа if ( Str_Cmp(Tabl.Text(fldRespDate,rcr), "", " ./") ) row.commonDocInfo.respDate = FssSvDateToXml(KDateFromStr(Tabl.Text(fldRespDate,rcr))); } // устарело. Ушло в заголовок row.commonDocInfo.docType = atoi(Tabl.Text(fldDocType,rcr)); // Блок "Данные застрахованного" (insuredData). Отличается от аналогичного блока в списке застрахованных // отсутствием упоминания должности FillInsured(row.insuredData, Tabl, rcr, false); // Блок "Данные работодателя" (employerData) row.employerData.employer = employer; row.employerData.emplRegnum = fuf.emplRegnum; row.employerData.emplParentNum = emplParentNum; row.employerData.emplInn = fuf.emplInn; // Блок "Данные работодателя для расчёта" (calculationData) row.calculationData.calcShifts = FssSvCalcShiftsToXml(Tabl.Text(fldCalcShifts,rcr)); row.calculationData.calcDays = to_string(atoi(Tabl.Text(fldCalcDays,rcr))); row.calculationData.kfReg = FssSvKfRegToXml(Tabl.Text(fldKfReg,rcr)); if ( atoi(Tabl.Text(fldMultiplTerr,rcr)) || atof(Tabl.Text(fldMultipl,rcr))>0.001 ) { row.calculationData.AddMultiplier(); row.calculationData.kfMultiplier.territoryCode = FssSvStringToXml(Tabl.Text(fldMultiplTerr,rcr),4); row.calculationData.kfMultiplier.multiplierValue = FssSvMultiplToXml(Tabl.Text(fldMultipl,rcr)); } row.calculationData.position = FssSvStringToXml(Tabl.Text(fldPosition,rcr),100); row.calculationData.category = atoi(Tabl.Text(fldCateg,rcr)); // устарело. Не надо передавать row.calculationData.fssPayment = FssSvSumToXml(atof(Tabl.Text(fldSum,rcr))); if ( Str_Cmp(Tabl.Text(fldNote,rcr), "", " ") ) row.calculationData.emplNote = FssSvStringToXml(Tabl.Text(fldNote,rcr),300); if ( CMsg.Msg_Proc(Oem(" Подождите немного. Идет выгрузка спец.выплат. "),100.* rcr/cntRcr)==ESC ) return 0; } // Если что-то добавляли в список, то выводим в файл if ( batchNo ) mngr.SerializeFuf(to_string(Path), fuf); FssSvSaveNumFile(FssSvNumFileInDay); } // Унифицированное заполнение информации по одному застрахованному // В справочнике застрахованных эта информация отличается только наличием должности FillInsured(insured, &Tabl, rcr, needPosition) { char Buf[512]; insured.snils = FssSNILSToXml(Tabl.Text(fldSNILS, rcr)); insured.firstName = FssSvStringToXml(Tabl.Text(fldI, rcr), 60); insured.lastName = FssSvStringToXml(Tabl.Text(fldF, rcr), 60); insured.middleName = FssSvStringToXml(Tabl.Text(fldO, rcr), 60); if ( needPosition ) insured.position = FssSvStringToXml(Tabl.Text(fldPosition, rcr), 100); string mir = Tabl.Text(fldMIR, rcr); int paymentType = atoi(mir)? 2 : 1; // перечисление на карту МИР(2) или счет(1) insured.paymentType= paymentType; string bic = Tabl.Text(fldBIC, rcr); if ( paymentType==1 || Str_Cmp(bic,""," ") ) { insured.accountBic = FssSvStringToXml(bic, 9); GetValueClassif("T_GUIDE\\ref_banks.tab",insured.accountBic,Buf,511,"NamePay","BIC"); insured.accountName = FssSvStringToXml(Buf, 80); } string account = Tabl.Text(fldAccount, rcr); if ( paymentType==1 || Str_Cmp(account,""," ") ) insured.account = FssSvStringToXml(account, 20); if ( paymentType==2 ) insured.paycardNum = FssSvStringToXml(mir, 19); insured.birthday = Tabl.Text(fldBirthday, rcr); } // Экспорт специальных выплат для медиков ExportSv_M(AdrTabl, AdrCListTabl, RcrInList) { return ExportSv(AdrTabl, AdrCListTabl, RcrInList, 99); } // Экспорт специальных выплат для соц.работников ExportSv_S(AdrTabl, AdrCListTabl, RcrInList) { return ExportSv(AdrTabl, AdrCListTabl, RcrInList, 98); } //============================================================================================= // Функции обеспечивающие требования формата xml //============================================================================================= FssSNILSToXml(str) // В СНИЛСе оставляем только цифры { char SNILS[256]; SNILS = str; int LenSnils = strlen(SNILS); int NewIdxSnils=0, OldIdxSnils=0; char CurSimv=0; do { CurSimv=SNILS[OldIdxSnils++]; if ( CharIsDigit(CurSimv) ) SNILS[NewIdxSnils++]=CurSimv; } while (CurSimv!=0); SNILS[NewIdxSnils++]=0; return to_string(SNILS); } FssSvDateToXml(date) // Строку чистим от пробелов и выводим с учетом максимального числа символов { char Buf[21]; sprintf(Buf,"%04d-%02d-%02d",date.GetYear(),date.GetMonth(),date.GetDay()); return to_string(Buf); } FssSvStringToXml(str, maxsize) // Строку чистим от пробелов и выводим с учетом максимального числа символов { FreeSpaceString(str,3,""); char Buf[maxsize+1]; sprintf(Buf,"%.*s",maxsize,str); return OemToAnsi(Buf); } FssSvCalcShiftsToXml(strShifts) // Количество смен { char Buf[256]; sprintf(Buf,"%-3.1f", atof(strShifts)); FreeSpaceString(Buf,3,""); return to_string(Buf); } FssSvKfRegToXml(strKfReg) { double kf = atof(strKfReg); if ( nabs(kf) < 1.04 ) return "1"; else if ( nabs(kf) > 1.96 ) return "2"; char Buf[256]; sprintf(Buf,"%-3.2f", atof(strKfReg)); FreeSpaceString(Buf,3,""); return to_string(Buf); } FssSvMultiplToXml(strMult) { /* int kf = atof(strMult); if ( nabs(kf) > 0.9 ) return "1"; */ char Buf[256]; sprintf(Buf,"%-3.1f", atof(strMult)); FreeSpaceString(Buf,3,""); return to_string(Buf); } FssSvSumToXml(strSum) // Итоговая сумма выплаты { char Buf[256]; sprintf(Buf,"%-24.2f", atof(strSum)); FreeSpaceString(Buf,3,""); return to_string(Buf); } SvRegistryAuthor() // Автор реестра { char Buf[512]; Buf = GetCommonCnfStr("SV_FSSA","fsssv"); if ( !Str_Cmp(Buf, "", " ") ) GetEnterpriseVar(AnsiToOem("ПИЛФССАВТ"), Buf,255); return to_string(Buf); } SvRegistryPhone() // Телефон автора реестра { char Buf[512]; Buf = GetCommonCnfStr("SV_FSSP","fsssv"); if ( !Str_Cmp(Buf, "", " ") ) GetEnterpriseVar(AnsiToOem("ПИЛФССТЕЛ"), Buf,255); return to_string(Buf); } SvRegistryEmail() // e-mail автора реестра { char Buf[512]; Buf = GetCommonCnfStr("SV_FSSM","fsssv"); if ( !Str_Cmp(Buf, "", " ") ) GetEnterpriseVar(AnsiToOem("ПИЛФССЭЛП"), Buf,255); return to_string(Buf); } //============================================================================================= // Общие функции выборки в таблицу //============================================================================================= FssSvRk(strDate) // Переопределяемая функция выборки районного коэффициента { return PriorityCall("UserFssSvRk","SysFssSvRk", strDate); } FssSvPosition(strDate) // Переопределяемая функция выборки должности сотрудника { return PriorityCall("UserFssSvPosition","SysFssSvPosition", strDate); } FssSvMultiplTerr(strDate) // Переопределяемая функция выборки кода местности дополнительного повышающего коэффициента (к районному) { return PriorityCall("UserFssSvMultiplTerr","SysFssSvMultiplTerr", strDate); } FssSvMultipl(strDate, cod) // Переопределяемая функция выборки дополнительного повышающего коэффициента (к районному) { return PriorityCall("UserFssSvMultipl","SysFssSvMultipl", strDate, cod); } FssSvCategory(strDate) // Переопределяемая функция выборки кода категории { return PriorityCall("UserFssSvCategory","SysFssSvCategory", strDate); } GetDBeg(date) { char str[21]; var dUnkn = CreateObject("KDate"); var dRb = KDateFromStr(GetKchValue("data_rb",str,20,date)); var dUv = KDateFromStr(GetKchValue("data_uv",str,20,date)); if ( dRb.IsValid() && dRb.GetAbs()==date.GetAbs() && dRb.GT(date) ) date = dRb; if ( dUv.IsValid() && dUv.GetAbs()==date.GetAbs() && dUv.LT(date) ) date = dUnkn; return date.GetStr(); } GetDEnd(date) { char str[21]; var dUnkn = CreateObject("KDate"); var dRb = KDateFromStr(GetKchValue("data_rb",str,20,date)); var dUv = KDateFromStr(GetKchValue("data_uv",str,20,date)); if ( dRb.IsValid() && dRb.GetAbs()==date.GetAbs() && dRb.GT(date) ) date = dUnkn; if ( dUv.IsValid() && dUv.GetAbs()==date.GetAbs() && dUv.LT(date) ) date = dUv; return date.GetStr(); } //============================================================================================= // Функции выборки в таблицу для медиков //============================================================================================= string monthFssSv=""; string dopstNURv=""; AskForMonth() { if (strlen(monthFssSv)==0) { string saveStrDate0=Str_Date_0; string saveStrDate1=Str_Date_1; sprintf(Str_Date_0, "%d.%d", Month_Cash,Year_Cash); sprintf(Str_Date_1, "%d.%d", Month_Cash,Year_Cash); if (AskPeriod(256,AnsiToOem("Введите месяц, за который сформировать отчет"))==ESC) BreakTableReceive(); monthFssSv=Str_Date_0; strcpy(Str_Date_0,saveStrDate0); strcpy(Str_Date_1,saveStrDate1); string strNU = GetCommonCnfStr("LST_NU_RV","fsssv"); if ( Str_Cmp(strNU," "," -,") ) dopstNURv = StrNU2Dopst(strNU); } return monthFssSv; } FssSvRv_M(strDate,strDBeg,strDEnd) // Переопределяемая функция выборки количества отработанного времени для мед.работников (для мед.работников в часах) { return PriorityCall("UserFssSvRv_M","SysFssSvRv_M", strDate,strDBeg,strDEnd); } FssSvSmena1_M(strDate,category) // Переопределяемая функция вычисления количества единиц времени в одной смене для мед.работников (для мед.работников в часах) { return PriorityCall("UserFssSvSmena1_M","SysFssSvSmena1_M", strDate,category); } FssSvCalcShifts_M(strDate,Rv,SmenaHours) // поставочная функция выборки количества смен { return PriorityCall("UserFssSvCalcShifts_M","SysFssSvCalcShifts_M", strDate, Rv,SmenaHours); } FssSvCalcDays_M(strDate,Rv,SmenaHours) // поставочная функция выборки количества дней (для медиков = 0) { return PriorityCall("UserFssSvCalcDays_M","SysFssSvCalcDays_M", strDate, Rv, SmenaHours); } FssSvBaseSum_M(strDate,category) // поставочная функция выборки базовой суммы выплаты для медиков { string fileSetka = GetNameFileSetkaCateg(strDate); char strValue[256]; GetValueClassif(fileSetka,to_string(category),strValue,255,"BaseSum", "Cod"); double baseSum=atof(strValue); round(baseSum); return baseSum; } FssSvPayment_M(strDate,calcShifts,calcDays,kfReg,kfMulti,category,baseSum) // поставочная функция расчета полной суммы выплаты для медиков { // Число смен * РК+доп.коэффициент * базовую сумму double Sum = atof(calcShifts)*(atof(kfReg)+atof(kfMulti))*atof(baseSum); round(Sum); return Sum; } //============================================================================================= // Вспомогательные функции //============================================================================================= BeginReceiveLS_M(__AdrTable) { if ( GetCommonCnfInt("oneComb","fsssv")==1 ) { var Tbl = CreateObject("CurPrnTbl"); Tbl.Initial(__AdrTable); int Fld = Tbl.Find_Name_Fld("ExtComb"); if ( Fld!=-1 ) Tbl.SetAdditionalNastrByPseud(Fld,"Func_Read",""); } return; } BeforeTransfer ( AdrTabl, // адрес передаваемой таблицы AdrCListTabl, // адрес списка таблиц RcrInList, type) { var Tabl = CreateObject("CurPrnTbl"); Tabl.Initial(AdrTabl); int CodOrgTbl = 0; var ArrOrg; if ( Tabl.GetFilterByOrg(ArrOrg) ) CodOrgTbl=ArrOrg[0]; string NumFSS=""; char Str[512]; if ( !CodOrgTbl ) GetEnterpriseVar(Oem("ФССНОМ"), Str, 255),NumFSS=Str; else NumFSS=GetEnterpriseRefValue(CodOrgTbl,Oem("ФССНОМ")); if ( !Str_Cmp(NumFSS," "," 0") ) { AmbaMessageBox(Oem("Незаполнен регистрационный номер в ФСС!"),Oem("Контур-Зарплата. Специальные выплаты ФСС"),0, 0); NumFSS = "0000000000"; } FreeSpaceString(NumFSS,2,""); var OptionsT = CreateObject("TransferOptions"); Str = OptionsT.GetNameFile(); FreeSpaceString(Str,2," "); char drive[80],dir[256],fname[256],ext[256]; splitpath(Str,drive,dir,fname,ext); var Dat = CreateObject("KDate"); Dat.SetDate(static_cast_to_string(datatek)); char Buf[256]; int numfile = FssSvGetNumFile(); if ( type==0 ) sprintf(Buf,"Insured_%s_%04d_%02d_%02d",NumFSS,Dat.GetYear(),Dat.GetMonth(),Dat.GetDay()); else sprintf(Buf,"C_%s_%04d_%02d_%02d",NumFSS,Dat.GetYear(),Dat.GetMonth(),Dat.GetDay()); sprintf(fname,"%s_%04d",Buf,numfile); makepath(Str,drive,dir,fname,"xml"); OptionsT.SetNameFile(static_cast_to_string(Str)); if ( type==0 ) OptionsT.SetUserComment(Oem("список застрахован.")); else OptionsT.SetUserComment(Oem("специальные выплаты")); OptionsT.SetFlagShowParam(3); return 0; } FssSvGetNumFile() { char Buf[21]; int num = atoi(GetCommonDateCnf("FssSvNumF","fsssv",KDateFromStr(datatek).GetStr(),Buf,20)); if ( !num ) num=1; return num; } FssSvSaveNumFile(numfile) { int oldnum = FssSvGetNumFile(); if ( numfile>oldnum ) SetCommonDateCnf("FssSvNumF","fsssv",KDateFromStr(datatek).GetStr(),to_string(numfile)); } BeforeTransferInsured ( AdrTabl, // адрес передаваемой таблицы AdrCListTabl, // адрес списка таблиц RcrInList) { return BeforeTransfer(AdrTabl,AdrCListTabl,RcrInList,0); } BeforeTransferSv_M ( AdrTabl, // адрес передаваемой таблицы AdrCListTabl, // адрес списка таблиц RcrInList) { return BeforeTransfer(AdrTabl,AdrCListTabl,RcrInList,99); } GetNameFileSetkaCateg(strDate) // определение файла сетки для информации о базовых выплатах { int numSet = GetLongFromNastr("NumSetCat","fsssv"); if ( numSet==0 ) numSet = 699; return GetNameFileSetkaFss(strDate, numSet); } GetNameFileSetkaFss(strDate, numSet) { string fileSetka = GetNameFileRefTime(numSet, -1, strDate); RTrim(fileSetka); if (strlen(fileSetka)==0) { var err="Не найдена сетка соответствия " + to_string(numSet) + " (в 'Сетках -> Прочие справочники') для выборки базовых сумм выплаты."; AmbaMessageBox(AnsiToOem(err), AnsiToOem("Контур-Зарплата. Специальные выплаты ФСС"), 0, 0); BreakTableReceive(); } return fileSetka; } GetExportFilePath() { char Path[512]; //полный путь до файла //путь до файла, указанного в запросе var OptionsTR = CreateObject("TransferOptions"); stccpy(Path,OptionsTR.GetNameFile(),256); FreeSpaceString(Path,2," "); var File = CreateObject("FileInfo"); File.Init(static_cast_to_string(Path)); var Directory = CreateObject("DirectoryInfo"); Directory.Init(File.Directory()); if (!Directory.Exists()) { string msg = "Ошибка! Неверно указан путь для создания файла.\nПапка '" + Directory.FullPath + "' не существует"; AmbaMessageBox(AnsiToOem(msg), AnsiToOem("Контур-Зарплата. Специальные выплаты ФСС"), MB_OK|MB_ICONERROR, 0); return ""; } if (0 && File.Exists()) { string msg = "Внимание!\nФайл '" + Path + "' существует. \n\nПерезаписать?"; int res = AmbaMessageBox(AnsiToOem(msg), AnsiToOem("Контур-Зарплата. Специальные выплаты ФСС"), MB_YESNOCANCEL|MB_ICONWARNING|MB_DEFBUTTON2, 0); if (res != IDYES) return ""; } return Path; } int fldTN, fldF, fldI, fldO, fldSNILS, fldPosition, fldBirthday, fldBIC, fldAccount, fldMIR, fldDt1, fldDt2, fldCovid, fldTypeInfo, fldRecalcReason, fldRespNo, fldRespDate, fldDocType, fldCalcShifts, fldCalcDays, fldKfReg, fldMultiplTerr, fldMultipl, fldCateg, fldSum, fldNote, fldDBeg, // дата начала выборки данных из ЛС(!) (не периода отчетности!) fldDEnd; // дата конца выборки данных из ЛС(!) (не периода отчетности!) FillFldSv(&Tabl) { FillFldInsured(Tabl); fldDt1 = Tabl.Find_Name_Fld("dt1"); fldDt2 = Tabl.Find_Name_Fld("dt2"); fldCovid = Tabl.Find_Name_Fld("covid"); fldTypeInfo = Tabl.Find_Name_Fld("typeInfo"); fldRecalcReason = Tabl.Find_Name_Fld("recalReasn"); fldRespNo = Tabl.Find_Name_Fld("respNo"); fldRespDate = Tabl.Find_Name_Fld("respDate"); fldDocType = Tabl.Find_Name_Fld("docType"); fldCalcShifts = Tabl.Find_Name_Fld("calcShifts"); fldCalcDays = Tabl.Find_Name_Fld("calcDays"); fldKfReg = Tabl.Find_Name_Fld("kfReg"); fldMultiplTerr = Tabl.Find_Name_Fld("territoryC"); fldMultipl = Tabl.Find_Name_Fld("kfMultipli"); fldCateg = Tabl.Find_Name_Fld("category"); fldSum = Tabl.Find_Name_Fld("fssPayment"); fldNote = Tabl.Find_Name_Fld("emplNote"); fldDBeg = Tabl.Find_Name_Fld("dateBeg"); fldDEnd = Tabl.Find_Name_Fld("dateEnd"); } FillFldInsured(&Tabl) { fldTN = Tabl.Find_Name_Fld("C_FIO"); fldF = Tabl.Find_Name_Fld("lastName"); fldI = Tabl.Find_Name_Fld("firstName"); fldO = Tabl.Find_Name_Fld("middleName"); fldSNILS = Tabl.Find_Name_Fld("snils"); fldPosition = Tabl.Find_Name_Fld("position"); fldBirthday = Tabl.Find_Name_Fld("birthday"); fldBIC = Tabl.Find_Name_Fld("accountBIC"); fldAccount = Tabl.Find_Name_Fld("account"); fldMIR = Tabl.Find_Name_Fld("paycardNum"); }