SrOtp(Date,Src)
{
  bool calcBySrc=false;
  if (Str_Cmp(Src," "," ")!=0) //указали источник 
    calcBySrc=true;
  //Дата, на которую считаем резерв
  var DateBeg=CreateObject("KDate");
  DateBeg.SetDate(static_cast_to_string(Date));
  if ( !DateBeg.IsValid() ) return 0.;

  //класс для расчета среднего
  var Sredn = CreateObject("KCalcSredn");
  Sredn.InitOtp(DateBeg,0);    // Инициализация способа расчета "по-среднему"
  var Nastr = Sredn.GetNastr();
  string OTPUSK_CNF_TABLE = "отпуск";
  int flag_rvmes=GetCommonCnfInt("FLAG_RVMES",OTPUSK_CNF_TABLE);
  int tip_koef  =GetCommonCnfInt("TIP_KOEF",OTPUSK_CNF_TABLE);
  Nastr.SetNastr(FLAG_RVMES,flag_rvmes);
  Nastr.SetNastr(TIP_KOEF,tip_koef);
  Nastr.SetNastr(FLAG_SILENT,1);

  Sredn.Calculate(0);   // расчет среднего
  
  if (!calcBySrc)  
    return Sredn.SumSredn();
  else 
  {  
    var Prop = CreateObject("APropBE"); Prop.InitSrc(ExtSrcToInt(Src[0]));
    return Sredn.SumSrednAProp(Prop);
  }  
}
bool bAksColumnTvh=false;
InitRezervParam()
{
  bAksColumnTvh=GetCommonCnfInt("AskColumn","rezerv")>0;
  if(bAksColumnTvh)
  {
   /* char Buf[256];
    CallFuncReceive("СТОЛБЕЦТВХ",Buf,255,0);*/
    char stlb[10];stlb=__ColumnTvhRezerv+1;
    if (ESC==Panel_Zapros("Дополнительные параметры для расчета резерва","",
                    "Cтолбец ТВХ",stlb, 2 
                    )
        )
       return ESC;
    __ColumnTvhRezerv=atoi(stlb)-1;
  }
  
  return 0;
}

int __ColumnTvhRezerv=15-1;
var globalBufSumSr;
int globalBufPolnTn=0;
var globalDateBegOtp;
SrOtp2(Date,Src,Combine,tab)
{
 char tn[91], ls1[255];
 sprintf(tn,"%.90s",static_cast_to_string(tab));   FreeSpaceString(tn,3,"");
 double tabn = atof(tn);
 lsname(Find_Full_TN(tabn),ls1);
 lsread(ls1,0);                   // инициализация ТН


  bool calcBySrc=Str_Cmp(Src," "," ")!=0;//указали источник
  bool calcByCombine=Str_Cmp(Combine," "," ")!=0;//указали совместительство
  bool calcByProp=calcBySrc || calcByCombine;

  //Дата, на которую считаем резерв
  var DateBeg=CreateObject("KDate");
  DateBeg.SetDate(to_string(Date));
  if ( !DateBeg.IsValid() ) return 0.;

  //класс для расчета среднего
  var Sredn = CreateObject("KCalcSredn");
  Sredn.InitOtp(DateBeg,0);    // Инициализация способа расчета "по-среднему"
  var Nastr = Sredn.GetNastr();
  string OTPUSK_CNF_TABLE = "отпуск";
  int flag_rvmes=GetCommonCnfInt("FLAG_RVMES",OTPUSK_CNF_TABLE);
  int tip_koef  =GetCommonCnfInt("TIP_KOEF",OTPUSK_CNF_TABLE);
  Nastr.SetNastr(FLAG_RVMES,flag_rvmes);
  Nastr.SetNastr(TIP_KOEF,tip_koef);
  Nastr.SetNastr(FLAG_SILENT,1);
  
  if(bAksColumnTvh)
    Nastr.SetNastr(STOLBEC_SREDN,__ColumnTvhRezerv);
  
  if (!calcByProp)  
  {
    if(!WorkingOnDate(0,DateBeg))//если нет ни одной действующей должности на дату DateBeg - резерв == 0.
      return 0.;
      
    Sredn.Calculate(0);   // расчет среднего
    return Sredn.SumSredn();
  }  
  else 
  {  
    int src=calcBySrc?ExtSrcToInt(Src[0]):CLL_TOTAL_SRC;
    int combine=calcByCombine?ExtCombineToInt(Combine):CLL_TOTAL_COMBINE;
    if(!WorkingOnDate(combine,DateBeg))
      return 0.;
    var Prop = CreateObject("APropBE"); Prop.Init(src,CLL_TOTAL_SUBJECT,CLL_TOTAL_PODR,combine); //инициализируем APropBE вн.кодом совместительства
    if ( Poln_Tn!=globalBufPolnTn || (IsObject(globalDateBegOtp) && !globalDateBegOtp.IsEq(DateBeg)) )
       globalBufSumSr = GetEmpty();
    else if ( IsObject(globalBufSumSr) && globalBufSumSr.IsExist(combine) )
       return globalBufSumSr.GetValue(combine).SumSrednAProp(Prop);
    // Неправильно оставлять только одно свойство, так как неправильно отрабатывает поиск ненулевых периодов.
    // var ListSrc = Nastr.GetListAProp();
    // ListSrc.Clear();
    // ListSrc.Insert(Prop);
    var ListSrc = CreateObject("APropArray");
    ListSrc.GetPropListLS();
    for ( int idx=ListSrc.Size()-1; idx>=0; --idx )
    {
       int curcombine = ListSrc.Get(idx).GetCombine();
       if ( curcombine!=CLL_TOTAL_COMBINE && combine!=CLL_TOTAL_COMBINE && curcombine!=combine )
          ListSrc.DeleteI(idx);
    }
    Nastr.SetListAProp(ListSrc);
    Sredn.Calculate(0);   // расчет среднего
    if ( !IsObject(globalBufSumSr) ) globalBufSumSr = CreateObject("Map");
    globalBufSumSr.Add(combine,Sredn);
    globalBufPolnTn = Poln_Tn;
    globalDateBegOtp = DateBeg;
    return Sredn.SumSrednAProp(Prop);
  }  
}

//если combine==0 - проверяем все должности
WorkingOnDate(combine,date)
{
  var CL=CreateObject("CombineList");//список должностей
  var it = CL.CreateIterator();
  bool isWorking=false;
  for (it.SetBegin();!it.IsEnd();it.Next()) //цикл по должностям (it.CurKey() - внутр.код совместительства )
  { 
    if (combine && it.CurKey()!=combine)
      continue;

    var tc=CreateObject("TmpCurCombine");     // Класс для временной смены а затем и восстановления текущего совместительства      
    tc.Init(it.CurKey());//инициализируем нужным совместительством
    char str[256];  kch_from("data_uv",str);
    var dUv=KDateFromStr(to_string(str));
    if(dUv.IsValid() && dUv.LT(date)) //уволен
      continue;
    isWorking=true;  
  } 
  return isWorking;
}
TarifStrVzn0(Date,StrSimv)
{
   var Dat = CreateObject("KDate");
   Dat.SetDate(static_cast_to_string(Date));
   if ( !Dat.IsValid() ) return 0.;
   
   int len = strlen(StrSimv);
   double Procent = 0.;
   for (int idx=0; idx<len; ++idx)
   {
      char SimvTax = GetCharFromStr(StrSimv,idx);
      double Sum=R_TaxSc2(1,Dat.GetRel(),Dat.GetRel(),SimvTax,12,2);
      double Pr=R_TaxSc2(32,Dat.GetRel(),Dat.GetRel(),SimvTax,12,2);
      Procent += GetFirstProcentTax();
   }
   return Procent;
}

TarifStrVzn1(Date,StrAlg)
{
   var Dat = CreateObject("KDate");
   Dat.SetDate(static_cast_to_string(Date));
   if ( !Dat.IsValid() ) return 0.;

   var Map = CreateObject("MapString");

   var Par=CreateObject("ParamFuncRW");
   Par.IInitial(static_cast_to_string(StrAlg),", ",100);

   double Procent = 0.;
   for (int idx=0; idx<Par.Count(); ++idx)
   {
      int Alg = atoi(Par.Get(idx));
      Map.Clear();
      Procent+=ProcentTaxAlg(Alg,Date,1,Map);
   }
   return Procent;
}

TarifStrVzn(Date,StrAlg)
{
   var Map = CreateObject("MapString");
   var Dat = CreateObject("KDate");
   Dat.SetDate(static_cast_to_string(Date));
   if ( !Dat.IsValid() ) return 0.;

   var Par=CreateObject("ParamFuncRW");
   Par.IInitial(static_cast_to_string(StrAlg),", ",100);
   char Buf[256];
   sprintf(Buf,"TABL_K%-d",CalcKategESN_PF());
   string PseudNastr = Buf;
   GetKchValue("d_inv",Buf,255,Dat);
   if ( GetGroupInv(Buf) )
      PseudNastr="TABL_INV";
   char Arg[256];

   double Procent = 0.;
   for (int idx=0; idx<Par.Count(); ++idx)
   {
      int Alg = atoi(Par.Get(idx));
      Map.Clear();
      if ( Alg!=261 )
      {
         sprintf(Arg,"%d,1,%d,%d,Источник выплаты,*,%d",1,Dat.GetRel(),Dat.GetRel(),Alg);
         R_Tax(Arg,Buf,12,2);
         sprintf(Arg,"option,%s",PseudNastr);
         string NumTables = R_Tax(Arg,Buf,12,0);
         Procent+=ProcentTaxAlg(Alg,Date,atoi(NumTables),Map);
      }
      else
      {
           var Par2=CreateObject("ParamFuncRW");
           Par2.IInitial(Par.Get(idx),"-",2);
           sprintf(Arg,"%d,1,%d,%d,Источник выплаты,*,%d,status3=%d",32,Dat.GetRel(),Dat.GetRel(),Alg,atoi(Par2.Get(1)));
           Procent += R_Tax(Arg,Buf,12,2);
      }
   }
   return Procent;
}

SumStrVzn(Date,StrAlg,Sum)
{
   var Dat = CreateObject("KDate");
   Dat.SetDate(static_cast_to_string(Date));
   if ( !Dat.IsValid() ) return 0.;

   var Par=CreateObject("ParamFuncRW");
   Par.IInitial(static_cast_to_string(StrAlg),", ",100);
   char Arg[256];
   char Buf[256];

   double SumTax = 0.;
   for (int idx=0; idx<Par.Count(); ++idx)
   {
      int Alg = atoi(Par.Get(idx));

      if ( Alg!=261 )
      {
         sprintf(Arg,"7,1,%d,%d,*,*,%d",Dat.GetRel(),Dat.GetRel(),Alg);
         double TaxWithoutDopSum = atof(R_Tax(Arg,Buf,12,2));
         sprintf(Arg,"7,1,%d,%d,*,*,%d,TaxInfo=%f",Dat.GetRel(),Dat.GetRel(),Alg,Sum);
         SumTax += atof(R_Tax(Arg,Buf,12,2))-TaxWithoutDopSum;
      }
      else
      {
           var Par2=CreateObject("ParamFuncRW");
           Par2.IInitial(Par.Get(idx),"-",2);
           sprintf(Arg,"7,1,%d,%d,*,*,%d,status3=%d",Dat.GetRel(),Dat.GetRel(),Alg,atoi(Par2.Get(1)));
           double TaxWithoutDopSum = atof(R_Tax(Arg,Buf,12,2));
           sprintf(Arg,"7,1,%d,%d,*,*,%d,status3=%d|TaxInfo=%f",Dat.GetRel(),Dat.GetRel(),Alg,atoi(Par2.Get(1)),Sum);
           SumTax += atof(R_Tax(Arg,Buf,12,2))-TaxWithoutDopSum;
      }
   }
   return SumTax;
}
