// Форма - 4а ФСС. Отчет по страховым взнсам, добровольно уплачиваемым в фонд социального страхования Российской Федерации отдельными категориями страхователей

var xls,   // объект Excel.Application
    wsh,   // объект WorkSheet
    Tabl,  // объект для работы с таблицей
    File;  // обект для работы с файлом печати

int cPay = 6; // количество выплат в рашифровке (табл.5 - "Расшифровка выплат на цели обязательного государственного страхования")

// константы для строк
int len = 512, // длина строки
      W = 250, // не менее символов
      A = 250, // не более символов
     _w = 25,  // размерность
     _a = 2;   // точность

char str[len],
     arg[len],
      ts[len];

double eps = 0.001,
       tmp = 0.0;


fss4a()
{
  int np = 1;
  var param[np];

  param[0] = 0;

  return fss4a_par(param,np);
}


fss4a_par(&param,np)
{
  File = CreateObject("CurPrnFile");
  File.SetFlagBrowse(0);

  table();

  return 0;
}


table()
{
  Tabl = CreateObject("CurPrnTbl");
  int cr = Tabl.Count_Rcr();  // число рабочих зaписей в таблице   

  FillFld();

  int m2 = atoi(Tabl.Text(fld[idxM2],0)),
      m1 = atoi(Tabl.Text(fld[idxM1],0)),
      m0 = atoi(Tabl.Text(fld[idxM0],0));

  string mn2; MonthName(mn2,m2); 
  string mn1; MonthName(mn1,m1);
  string mn0; MonthName(mn0,m0);

  int NomKvart = atoi(Tabl.Text(fld[idxENDKVL],0));

  string period = "";

  if ( NomKvart == 1 ) period = OemToAnsi("I квартал");
  if ( NomKvart == 2 ) period = OemToAnsi("полугодие");
  if ( NomKvart == 3 ) period = OemToAnsi("9 месяцев");
  if ( NomKvart == 4 ) period = OemToAnsi("год");

  char year[5]; sprintf(str,"%-7.7s",Tabl.Text(fld[idxEDAT],0)); sprintf(year,"%c",str[6]);

  int dper = atoi(Tabl.Text(fld[idxAEDAT],0)) - atoi(Tabl.Text(fld[idxABDAT],0)) + 1;

  double ssc = 0.0; // для среднесписочной численности

  double IncP = 0.0, Inc2 = 0.0, Inc1 = 0.0, Inc0 = 0.0,
         TaxP = 0.0, Tax2 = 0.0, Tax1 = 0.0, Tax0 = 0.0,
         SocP = 0.0, Soc2 = 0.0, Soc1 = 0.0, Soc0 = 0.0;

     int Cnt[cPay], // число случаев
         Dni[cPay]; // число дней
  double Sum[cPay]; // сумма выплат

  for (int i=0; i<cPay; i++) { Cnt[i]=0; Dni[i]=0; Sum[i]=0.0; }


  int Cnts = 0; // по беременности и родам (совместительство)
  int Dnis = 0;
  double Sums = 0.0;
  
  int Cnt9 = 0; // по болезни
  int Dni9 = 0;
  double Sum9 = 0.0;
  
  int Cnt1 = 0;  // до 1.5 лет  1-й ребенок
  int Dni1 = 0;
  double Sum1 = 0.0;

  int Cnt2 = 0; // до 1.5 лет  1-й ребенок
  int Dni2 = 0;
  double Sum2 = 0.0;


  // цикл по записям таблицы
  for ( int zap=0; zap < cr; zap++ )
  {
    // численность
    if ( dper <= 12 ) for ( int i = 0; i < dper; i++ ) ssc += atof(Tabl.Text(fld[idxSCH1+i],zap));

    // доход
    IncP += atof(Tabl.Text(fld[idxINCP],zap));
    Inc2 += atof(Tabl.Text(fld[idxINC2],zap));
    Inc1 += atof(Tabl.Text(fld[idxINC1],zap));
    Inc0 += atof(Tabl.Text(fld[idxINC0],zap));

    // налог
    TaxP += atof(Tabl.Text(fld[idxTAXP],zap));
    Tax2 += atof(Tabl.Text(fld[idxTAX2],zap));
    Tax1 += atof(Tabl.Text(fld[idxTAX1],zap));
    Tax0 += atof(Tabl.Text(fld[idxTAX0],zap));

    // выплаты за счет соцстраха
    SocP += atof(Tabl.Text(fld[idxSOCP],zap));
    Soc2 += atof(Tabl.Text(fld[idxSOC2],zap));
    Soc1 += atof(Tabl.Text(fld[idxSOC1],zap));
    Soc0 += atof(Tabl.Text(fld[idxSOC0],zap));

    // расшифровка выплат на цели соцстраха
    for ( int i = idxDEC1; i < idxDEC1 + cPay; i++ )
    {
      var lst = CreateObject("ParamFuncRW");
      lst.IInitial1(static_cast_to_string(Tabl.Text(fld[i],zap)),",",18);

      Cnt[i-idxDEC1] += atoi(lst.Get(3));
      Dni[i-idxDEC1] += atoi(lst.Get(4));
      Sum[i-idxDEC1] += atof(lst.Get(5));

      if ( i == idxDEC2 ) // по беременности и родам (совместительство)
      {
        Cnts += atoi(lst.Get(9));
        Dnis += atoi(lst.Get(10));
        Sums += atof(lst.Get(11));
      }

      if ( i == idxDEC1 ) // по болезни (совместительство)
      {
        Cnt9 += atoi(lst.Get(9));
        Dni9 += atoi(lst.Get(10));
        Sum9 += atof(lst.Get(11));
      }

      if ( i == idxDEC3 ) // до 1.5 лет
      {
        Cnt1 += atoi(lst.Get(9));  // 1-й ребенок
        Dni1 += atoi(lst.Get(10));
        Sum1 += atof(lst.Get(11));

        Cnt2 += atoi(lst.Get(15)); // 2-й ребенок
        Dni2 += atoi(lst.Get(16));
        Sum2 += atof(lst.Get(17));
      }
    }
  } // конец цикла по записям таблицы

  // данные из справки о предприятии

  char Org[len]; RefEnt("ИМЯП"     ,Org,W); // наименование предприятия
  char Adr[len]; RefEnt("АДРП"     ,Adr,W); // адрес предприятия
  char Grn[len]; RefEnt("ОГРН"     ,Grn,W); // основной государственный регистрационный номер
  char Inn[len]; RefEnt("ИНН"      ,Inn,W); // ИНН
  char Kpp[len]; RefEnt("КОДПОСУЧ" ,Kpp,W); // КПП
  char Cni[len]; RefEnt("КОДНИ"    ,Cni,W); // код налоговой инспекции
  char Ssn[len]; RefEnt("ФССНОМ"   ,Ssn,W); // регистрационный номер в ФСС
  char Ruk[len]; RefEnt("РУКП"     ,Ruk,W); // ФИО руководителя
  char Glb[len]; RefEnt("ГЛБУХ"    ,Glb,W); // ФИО гл.бухгалтера

  KorrAdr(Adr,W);

  xls = CreateObject("Excel.Application");
  try
  {
   
  char Dir[len];
  GetCurrentDirectory(W,Dir);
  string nm="TABLESN\\fss4a_07.xlt";
//  string nm="TABLESN\\fss4a_07.xls";
  var WorkDir = Dir + "\\";
  xls.Caption = OemToAnsi("Отчет по страховым взносам");
  xls.Workbooks.Add(WorkDir+nm);
  string name = xls.Workbooks.Item(1).Name;

  // лист 1
  wsh = xls.Workbooks.Item(name).Worksheets.Item(1);

  WriteToCell("AN29",period);
  WriteToCell("BS29",year);
  WriteToCell("A32" ,Org);
  WriteToCell("H40" ,Adr);
  WriteToCell("CK37",Grn);
  WriteToCell("CK38",Inn);
  WriteToCell("CK39",Cni);
  WriteToCell("CK40",Kpp);
  WriteToCell("A56" ,Ssn);

  WriteToCell("CN55" ,datatek);

  // лист 2
  wsh = xls.Workbooks.Item(name).Worksheets.Item(2);

  // считаем среднесписочную численность
  if ( dper ) ssc /= dper; round(ssc);

  // табл.1
  if ( nabs(ssc) > eps ) DoubleToCell("BX10",ssc);

  WriteToCell("B13",mn2); // печатаем названия месяцев
  WriteToCell("B14",mn1);
  WriteToCell("B15",mn0);

  if ( nabs(IncP) > eps ) DoubleToCell("BX11",IncP);
  if ( nabs(Inc2) > eps ) DoubleToCell("BX13",Inc2);
  if ( nabs(Inc1) > eps ) DoubleToCell("BX14",Inc1);
  if ( nabs(Inc0) > eps ) DoubleToCell("BX15",Inc0);

  // табл.2
  WriteToCell("B25",mn2); // печатаем названия месяцев
  WriteToCell("B26",mn1);
  WriteToCell("B27",mn0);

  tmp = TaxP - (Tax2 + Tax1 + Tax0);
  if ( nabs(tmp)  > eps ) DoubleToCell("AE23",tmp);
  if ( nabs(Tax2) > eps ) DoubleToCell("AE25",Tax2);
  if ( nabs(Tax1) > eps ) DoubleToCell("AE26",Tax1);
  if ( nabs(Tax0) > eps ) DoubleToCell("AE27",Tax0);

  WriteToCell("BF26",mn2); // печатаем названия месяцев
  WriteToCell("BF27",mn1);
  WriteToCell("BF28",mn0);

  tmp = SocP - (Soc2 + Soc1 + Soc0);
  if ( nabs(tmp)  > eps ) DoubleToCell("CI24",tmp);
  if ( nabs(Soc2) > eps ) DoubleToCell("CI26",Soc2);
  if ( nabs(Soc1) > eps ) DoubleToCell("CI27",Soc1);
  if ( nabs(Soc0) > eps ) DoubleToCell("CI28",Soc0);

  int count = 0, // всего случаев по временной нетрудоспособности
       days = 0; // всего дней по временной нетрудоспособности

  for ( int i = 0; i < cPay; i++ ) count += Cnt[i];

  days = Dni[0] + Dni[1];

  if ( nabs(count) > eps ) DoubleToCell("Y43",count);
  if ( nabs(days) > eps ) DoubleToCell("Y44",days);
  tmp = Cnt9 + Cnts; if ( nabs(tmp) > eps ) DoubleToCell("Y46",tmp);
  tmp = Dni9 + Dnis; if ( nabs(tmp) > eps ) DoubleToCell("Y47",tmp);

  DoubleToCell("CX29",Sum9 + Sums);

  // лист 3
  wsh = xls.Workbooks.Item(name).Worksheets.Item(3);

  // табл.3
                            if ( nabs(IncP) > eps ) DoubleToCell("AQ9", IncP);
  tmp = Inc2 + Inc1 + Inc0; if ( nabs(tmp)  > eps ) DoubleToCell("U10", tmp);
                            if ( nabs(TaxP) > eps ) DoubleToCell("CT9", TaxP);
  tmp = Tax2 + Tax1 + Tax0; if ( nabs(tmp)  > eps ) DoubleToCell("BX10",tmp);

  // табл.4
  if ( nabs(SocP) > eps ) DoubleToCell("CT18",SocP);

  // табл.5
  if ( nabs(Cnt[0]) > eps ) DoubleToCell("P29", Cnt[0]); 
  if ( nabs(Dni[0]) > eps ) DoubleToCell("BJ28",Dni[0]); if ( nabs(Sum[0]) > eps ) DoubleToCell("BT28",Sum[0]); //  1 - по болезни
  if ( nabs(Dni[1]) > eps ) DoubleToCell("BJ34",Dni[1]); if ( nabs(Sum[1]) > eps ) DoubleToCell("BT34",Sum[1]); //  3 - по беременности и родам
  if ( nabs(Cnt[2]) > eps ) DoubleToCell("BJ36",Cnt[2]); if ( nabs(Sum[2]) > eps ) DoubleToCell("BT36",Sum[2]); //  5 - до 1.5 лет всего
  if ( nabs(Cnt[3]) > eps ) DoubleToCell("BJ39",Cnt[3]); if ( nabs(Sum[3]) > eps ) DoubleToCell("BT39",Sum[3]); //  8 - при рождении
  if ( nabs(Cnt[4]) > eps ) DoubleToCell("BJ40",Cnt[4]); if ( nabs(Sum[4]) > eps ) DoubleToCell("BT40",Sum[4]); //  9 - ранние сроки беременности
//if ( nabs(Cnt[5]) > eps ) DoubleToCell("BJ41",Cnt[5]); if ( nabs(Sum[5]) > eps ) DoubleToCell("BT41",Sum[5]); // 10 - при усыновлении

  if ( nabs(Cnt9) > eps ) DoubleToCell("V32", Cnt9); 
  if ( nabs(Dni9) > eps ) DoubleToCell("BJ31",Dni9); if ( nabs(Sum9) > eps ) DoubleToCell("BT31",Sum9); // 2 - по болезни (совместительство)
  if ( nabs(Dnis) > eps ) DoubleToCell("BJ35",Dnis); if ( nabs(Sums) > eps ) DoubleToCell("BT35",Sums); // 4 - по беременности и родам (совместительство)
  if ( nabs(Cnt1) > eps ) DoubleToCell("BJ37",Cnt1); if ( nabs(Sum1) > eps ) DoubleToCell("BT37",Sum1); // 6 - до 1.5 лет 1-й ребенок
  if ( nabs(Cnt2) > eps ) DoubleToCell("BJ38",Cnt2); if ( nabs(Sum2) > eps ) DoubleToCell("BT38",Sum2); // 7 - до 1.5 лет 2-й ребенок

  // лист 4
  wsh = xls.Workbooks.Item(name).Worksheets.Item(4);

  WriteToCell("AT21",Ruk);
  WriteToCell("AT24",Glb);

  var mt = CreateObject("KMonth");

  for ( int i = 0, j = 3; j < 10; i++, j++ ) str[i] = datatek[j]; str[7] = 0;

  mt.SetDate(static_cast_to_string(str));
  sprintf(arg,"11,%d",mt.GetAbs()-mtek);
  R_DATA_EX(arg,str,W,A);
  FreeSpaceString(str,3,"");
  WriteToCell("N18",OemToAnsi(str));

  sprintf(str,"%c%c",datatek[0],datatek[1]);
  WriteToCell("H18",str);

  sprintf(str,"%c",datatek[9]);
  WriteToCell("AK18",str);

  }
  catch(object err)
  {
     SayError(err);
  }
  catch(...)
  {
     ;
  }

  xls.Visible = true;
}


KorrAdr(&str,n)
{
  ts[0]=0;
  int celem=count_elem(str,',');
  for (int i=1; i<=celem; i++)
  {
    char buf[len];
    elem_of_array(str,i,',',buf,W);
    FreeSpaceString(buf,3,"");

    if (strlen(buf) > 0)
    {
      if ( strlen(ts) + strlen(buf) >= strlen(str) ) break;
      ts = ts + buf + ",";
    }
  }
  if ( ts[strlen(ts)-1] == ',' ) ts[strlen(ts)-1] = 0;
  str = ts;
}


RefEnt(name,&str,n)
{
  GetEnterpriseVar(name,str,n);
  FreeSpaceString(str,3,"");
  UpperString(str);
  OemToChar(str,str);
}


WriteToCell(cell,str)
// функция пишет str в ячейку cell листа Excel (в данном случае ссылка на лист должна быть глобальной переменной)
// cell - имя ячейки
// str - значение, которое требуется записать в ячейку Cell рабочего листа wsh
{
  FreeSpaceString(str,3,"");
  wsh.Range(static_cast_to_string(cell)).Value=static_cast_to_string(str);
  return 0;
}


DoubleToCell(cell,num)
{
  wsh.Range(static_cast_to_string(cell)).Value=num;
}

toString(str)
{
  return static_cast_to_string(str);
}


MonthName(&name,month)
{
  sprintf(arg,"1,%d",month);
  sprintf(ts,"%-*.*s",W,A,R_DATA_EX(arg,str,W,A));
  FreeSpaceString(ts,3,"");
  OemToChar(ts,ts);
  name=ts;
}


FillFld()
//=============================================================================
// Находим поля в таблице
//=============================================================================
{
  fld[idxBDAT]      = Tabl.Find_Name_Fld("BDAT");
  fld[idxEDAT]      = Tabl.Find_Name_Fld("EDAT");
  fld[idxABDAT]     = Tabl.Find_Name_Fld("ABDAT");
  fld[idxAEDAT]     = Tabl.Find_Name_Fld("AEDAT");
  fld[idxENDOTNTEK] = Tabl.Find_Name_Fld("ENDOTNTEK");
  fld[idxENDKVL]    = Tabl.Find_Name_Fld("ENDKVL");
  fld[idxENDINKV]   = Tabl.Find_Name_Fld("ENDINKV");
  fld[idxM2]        = Tabl.Find_Name_Fld("M2");
  fld[idxM1]        = Tabl.Find_Name_Fld("M1");
  fld[idxM0]        = Tabl.Find_Name_Fld("M0");
  fld[idxINCP]      = Tabl.Find_Name_Fld("INCP");
  fld[idxINC2]      = Tabl.Find_Name_Fld("INC2");
  fld[idxINC1]      = Tabl.Find_Name_Fld("INC1");
  fld[idxINC0]      = Tabl.Find_Name_Fld("INC0");
  fld[idxTAXP]      = Tabl.Find_Name_Fld("TAXP");
  fld[idxTAX2]      = Tabl.Find_Name_Fld("TAX2");
  fld[idxTAX1]      = Tabl.Find_Name_Fld("TAX1");
  fld[idxTAX0]      = Tabl.Find_Name_Fld("TAX0");
  fld[idxSOCP]      = Tabl.Find_Name_Fld("SOCP");
  fld[idxSOC2]      = Tabl.Find_Name_Fld("SOC2");
  fld[idxSOC1]      = Tabl.Find_Name_Fld("SOC1");
  fld[idxSOC0]      = Tabl.Find_Name_Fld("SOC0");
  fld[idxDEC1]      = Tabl.Find_Name_Fld("DEC1");
  fld[idxDEC2]      = Tabl.Find_Name_Fld("DEC2");
  fld[idxDEC3]      = Tabl.Find_Name_Fld("DEC3");
  fld[idxDEC4]      = Tabl.Find_Name_Fld("DEC4");
  fld[idxDEC5]      = Tabl.Find_Name_Fld("DEC5");
  fld[idxDEC6]      = Tabl.Find_Name_Fld("DEC6");
  fld[idxSCH1]      = Tabl.Find_Name_Fld("SCH1");
  fld[idxSCH2]      = Tabl.Find_Name_Fld("SCH2");
  fld[idxSCH3]      = Tabl.Find_Name_Fld("SCH3");
  fld[idxSCH4]      = Tabl.Find_Name_Fld("SCH4");
  fld[idxSCH5]      = Tabl.Find_Name_Fld("SCH5");
  fld[idxSCH6]      = Tabl.Find_Name_Fld("SCH6");
  fld[idxSCH7]      = Tabl.Find_Name_Fld("SCH7");
  fld[idxSCH8]      = Tabl.Find_Name_Fld("SCH8");
  fld[idxSCH9]      = Tabl.Find_Name_Fld("SCH9");
  fld[idxSCH10]     = Tabl.Find_Name_Fld("SCH10");
  fld[idxSCH11]     = Tabl.Find_Name_Fld("SCH11");
  fld[idxSCH12]     = Tabl.Find_Name_Fld("SCH12");
}

int idxBDAT     =  0, // месяц начала периода (относительный)
    idxEDAT     =  1, // месяц конца периода (ММ.ГГГГ)
    idxABDAT    =  2, // месяц начала периода (абсолютный)
    idxAEDAT    =  3, // месяц конца периода (абсолютный)
    idxENDOTNTEK=  4, // месяц конца периода (относительный)
    idxENDKVL   =  5, // квартал месяца конца периода (1,2,3 или 4)
    idxENDINKV  =  6, // номер месяца конца периода в квартале (1,2 или 3)
    idxM2       =  7, // первый месяц квартала (относительный)
    idxM1       =  8, // второй месяц квартала (относительный)
    idxM0       =  9, // третий месяц квартала (относительный)
    idxINCP     = 10, // доход за период
    idxINC2     = 11, // доход за первый месяц квартала
    idxINC1     = 12, // доход за второй месяц квартала
    idxINC0     = 13, // доход за третий месяц квартала
    idxTAXP     = 14, // налог за период
    idxTAX2     = 15, // налог за первый месяц квартала
    idxTAX1     = 16, // налог за второй месяц квартала
    idxTAX0     = 17, // налог за третий месяц квартала
    idxSOCP     = 18, // выплаты за счет соцстраха за период
    idxSOC2     = 19, // выплаты за счет соцстраха за первый месяц квартала
    idxSOC1     = 20, // выплаты за счет соцстраха за второй месяц квартала
    idxSOC0     = 21, // выплаты за счет соцстраха за третий месяц квартала
    idxDEC1     = 22, // пособия по временной нетрудоспособности
    idxDEC2     = 23, // по беременности и родам
    idxDEC3     = 24, // по уходу за ребенком до 1.5 лет
    idxDEC4     = 25, // при рождении ребенка
    idxDEC5     = 26, // пособие женщинам, вставшим на учет в ранние сроки беременности
    idxDEC6     = 27, // при усыновлении ребенка
    idxSCH1     = 28, // среднесписочная численность с 1 по 12 месяц от начала периода
    idxSCH2     = 29, //
    idxSCH3     = 30, //
    idxSCH4     = 31, //
    idxSCH5     = 32, //
    idxSCH6     = 33, //
    idxSCH7     = 34, //
    idxSCH8     = 35, //
    idxSCH9     = 36, //
    idxSCH10    = 37, //
    idxSCH11    = 38, //
    idxSCH12    = 39, //

    CountIdx    = 40;          

int fld[CountIdx]; // массив номеров полей таблицы
