
// Эту функцию надо перенести в какой-либо постоянно загруженный модуль
/*
Receive_TABLBRIG(&AdrMain,&__VarGMain)
{
   UnloadScriptModule("user\\ReceiveBrig");
   LoadScriptModule("user\\ReceiveBrig");
   int rc = Receive_TABLBRIG_body(AdrMain,__VarGMain);
   UnloadScriptModule("user\\ReceiveBrig");
   return rc;
}
*/

// Настройки
int ShbSimple = 1; // шаблон для отдельных ЛС
int Shb501_0  = 2; // шаблон для макета 501 без КТУ
int Shb501_4  = 3; // шаблон для макета 501 с КТУ
int Shb508    = 4; // шаблон для макета 508

//====================================================================
//= Дано: dbf-файл следующей структуры:
//= KSP - код бригады (код структурного подразделения)
//= TN  - табельный номер (если ноль, то строка относится 
//=       к бригаде в целом, если не ноль - к одному ЛС.
//= SPZ - шифр производственных затрат (должен заполнить столбец в таблице
//=       чтобы учесть при разноске
//= SUMWORKE - рабочее время по наряду (не используется)
//= SUM_NAR  - сумма по наряду
//= DE - календарный день (выходной) когда речь идет о наряде выполнявшемся
//=      в рабочий день. Накладывает ограничение на принимаемые ЛС - должны
//=      быть приняты только те, кто в этот выходной работал
//= MAKET, WKTU - два поля, определяющие по сути шаблон бригадной таблицы
//=               например макет 501 и 508 это макет обычного наряда и наряда
//=               выходного дня. WKTU - признак учитывать КТУ (4) или не 
//=               учитывать, т.е. КТУ всегда равен 1 (0).
//=
//= Задачи:
//= 1) по строчкам относящимся к отдельным ЛС, сформировать отдельную таблицу
//=    которая будет разнесена в эти ЛС
//= 2) по строчкам относящимся к бригадам в целом
//=    а) выбрать подходящий шаблон бригадной таблицы (на основе MAKET,WKTU)
//=    б) добавить эту таблицу в список подготовленных
//=    в) принять в добавленную таблицу людей относящихся к этой бригаде
//=    г) заполнить столбец в этой таблице хранящий шифр затрат
//=    д) заполнить таблицу общих сумм у этой таблице суммой полагающейся к
//=       распределению
//=    е) при приеме в "наряд выходного дня" отбросить тех людей, кто не работал
//=       в этот выходной (сделать на уровне функции приема, с условием приема)
//=    ё) рассчитать получившуюся таблицу
//=    ж) разнести(?)
//====================================================================

   Receive_TABLBRIG_body(&AdrMain,&__VarGMain)
//=----------------
//= Функция вида Receive_??????(&Adr,&Var) - это скриптовая функция, которая
//= отрабатывает при нажатии F7 (добавление таблицы по шаблону) в разных
//= режимах. ?????? - указывает для какого режима предназначена эта функция
//= Например, TABLBRIG - для бригадных таблиц, TAB_LS - для справок по ЛС 
//= и т.д. (т.е. это имя каталога в поставке, который отвечает за данный режим)
//= Для пользовательских режимов - имя поставочного каталога, от которого
//= пользовательский наследует поведение (т.е. KindCommonDir()).
//= На вход функции подается два параметра:
//= Adr - адрес таблицы, содержащей список подготовленных 
//=       в данном месяце таблиц. Он нужен для инициализации объекта
//=       "VedListMainTable", если мы планируем самостоятельно создавать
//=       новые таблицы в этом списке
//= __VarGMain - переменная, предназначенная для того, чтобы передать
//=       какие-то данные в создаваемые таблицы. Т.е. можно что-то запросить
//=       у пользователя сохранить это в данной переменной и использовать
//=       в функциях приема в таблице. Следует отметить, что у переменной тип
//=       variant. Поэтому, не смотря на то, что она одна, можно в ней сохранить
//=       много данных, например так:
//=       string ars[2];
//=       ars[0] = "НДФЛ";
//=       ars[1] = "ЕСН";
//=       var array[3];
//=       array[0] = 1789.12;
//=       array[1] = ars;
//=       array[2] = CreateObject("Excel.Application");
//=       __VarGMain = array;
//=       В данном примере, в таблицы будет переданных целый массив данных
//=       число, массив строк, объект Excel. То есть в таблице обратившись
//=       __VarGMain[2][0] мы получим доступ к строке "НДФЛ"
//= Функция должна вернуть некоторый код возврата. Если код возврата
//= равен ESC - значит обычный механизм создания таблицы по шаблону
//= запускаться не будет. Иначе отработает еще обычный механизм.
{
   char NameDbf[256];
   Text_Text(NameDbf,"..\\Naryad.dbf",255);
   int Regim = 0; // 0 - из dbf, 1 - обычное создание
   // Выполнить запрос: прием из Dbf-файла 
   // или обычное создание бригадных таблиц. Если из dbf, то еще запрашиваем
   // имя файла
   if ( PanelReceiveTablBrig(NameDbf,Regim)==ESC )
      return ESC;

   // Если не прием из dbf - то запускаем обычный механизм.
   if ( Regim!=0 ) return 0;
   
   // создаем объекты для таблиц
   // таблица для обработки строки относящейся к целой бригаде
   var TablBrig = CreateObject("CurPrnTbl");

   // таблица для накапливания информации по отдельным ЛС, которые
   // затесались в файл
   var TablLS   = CreateObject("CurPrnTbl");
   bool bInitTablLS = false; // признак, что таблица уже была создана

   // Таблица общих сумм для бригадной таблицы
   var TableTopSumm = CreateObject("CurPrnTbl");

   // одна таблица - для dbf-файла, из которого осуществляем прием
   var TablDbf  = CreateObject("CurPrnTbl");
   TablDbf.InitialNameFile(static_cast_to_string(NameDbf));
   // Если у нас получилась всего одна строка да и та пустая
   // (т.е. в файле нет информации), то выходим
   if ( TablDbf.Count_Rcr()<2 &&  TablDbf.Check_Empty_Rcr(0)==-1 )
      return ESC;
   // определим номера столбцов dbf-файла, по их именам
   if ( !InitNumFldDbfBrig(TablDbf) )
      return ESC;

   // таблица со списком подготовленных таблиц
   var MainTable=CreateObject("VedListMainTable");
   MainTable.InitByAdr(AdrMain);

   // для функции, которая добавляет новую таблицу по шаблону необходим
   // параметр "фильтр" по источнику/объекту/подразделению.
   // в нашем случае он будет пустой
   var Filter = CreateObject("APropBE");

   char SaveCnf[11];
   GetCommonCnf("EMPTY_TABL","ЇҐз вм",SaveCnf,10);
   SetCommonCnfInMem("EMPTY_TABL","1","ЇҐз вм",'N',1,0);
   // Начинаем обработку файла построчно
   for ( int RcrDbf=0; RcrDbf<TablDbf.Count_Rcr(); ++RcrDbf )
   {
      // Берем сразу все данные из строки dbf-файла
      long Brig = atol(TablDbf.Text(FldDbf[idxDbfKSP   ],RcrDbf));
      long TN   = atol(TablDbf.Text(FldDbf[idxDbfTN    ],RcrDbf));
      string Shz =      TablDbf.Text(FldDbf[idxDbfSPZ   ],RcrDbf) ;
      double Sum= atof(TablDbf.Text(FldDbf[idxDbfSumm  ],RcrDbf));
      int Day   = atoi(TablDbf.Text(FldDbf[idxDbfCalDay],RcrDbf));
      int Maket = atoi(TablDbf.Text(FldDbf[idxDbfMaket ],RcrDbf));
      int Wktu  = atoi(TablDbf.Text(FldDbf[idxDbfWKTU  ],RcrDbf));

      // по TN, Wktu, Maket определяем номер шаблона для добавляемой
      // таблицы
      int NumShab = DefineNumShabBrig(TN,Maket,Wktu);
      // если с номером шаблона не определились переходим к следующей
      // строке файла
      if ( !NumShab ) continue;

      // Добавляем таблицу по номеру шаблона
      // Если это отдельный пользователь, то надо еще проверить, что таблица
      // не была уже создана
      int NumTable = 0;
      if ( !TN || !bInitTablLS )
      {
         // NumTable = MainTable.Add_Rcr_Work(NumShab, Filter,0,"+("+NameDbf+")");

         NumTable = MainTable.Add_Rcr_Work(NumShab, Filter,0,"+("+datatek+")");
         // такого быть не должно (что таблица не добавилась),
         // но все же анализируем
         if ( !NumTable ) continue;
      }

      if ( TN ) // обрабатываем отдельные ЛС
      {
         // если таблица еще не была проинициализирована
         // (т.е. только что добавлена) инициализируем ее
         bool bNeedAddRcr = true;
         if ( !bInitTablLS )
         {
            int AdrT = MainTable.GetTable(NumTable);
            // такого быть не должно, но вдруг
            if ( !AdrT ) break;

            TablLS.Initial(AdrT);
            TablLS.Clear();
            if ( !InitNumFldLSBrig(TablLS) ) 
               break;
            bInitTablLS = true;
            bNeedAddRcr = false; // т.к. первая строка есть и она пустая
         }
         int CurRcr = TablLS.Count_Rcr()-1;
         // Добавляем, если надо, строку
         if ( bNeedAddRcr && TablLS.Add_Rcr(CurRcr++,1)==-1 ) break;

         TablLS.SText(FldLS[idxLsTN    ],CurRcr,static_cast_to_string(TN));
         TablLS.SText(FldLS[idxLsSPZ   ],CurRcr,Shz);
         TablLS.SText(FldLS[idxLsMaket ],CurRcr,static_cast_to_string(Maket));
         int W = TablLS.Width_Fld(FldLS[idxLsSumm]);
         char Buf[W+1];
         Double_Text(Buf,Sum,TablLS.Accurasy_Fld(FldLS[idxLsSumm]),W);
         TablLS.SText(FldLS[idxLsSumm  ],CurRcr,static_cast_to_string(Buf));

         // переходим к обработке следующей строки файла
         continue;
      }

      int AdrT = MainTable.GetTable(NumTable);
      // такого быть не должно, но вдруг
      if ( !AdrT ) break;
      TablBrig.Initial(AdrT);
      TablBrig.Clear();
      // До приема в глобальную переменную сохраним:
      // код бригады, Шифр затрат, дату выходного дня
      var DopInfo[3];
      DopInfo[0] = Brig;
      DopInfo[1] = Shz;
      char StrDay[11];
      sprintf(StrDay,"%02d.%02d.%04d",Day,Month_Cash,Year_Cash);
      DopInfo[2] = StrDay;
      __VarGMain = DopInfo;
      // прием в таблицу
      // первый параметр - тип приема:
      // 0 - отмеченные ЛС
      // 1 - по коду подразделения
      // 2 - по коду бригады
      // по коду бригады "автоматом" можно принять только в том случае, 
      // если используется стандартное поле в КЧ
      // Если же используется не стандартное поле (из-за того, что
      // код бригады должен быть символьным), то придется прием осуществлять
      // выделяя все ЛС!, и не нужные ЛС отбрасывать путем накладывания условия
      // в бригадной таблице
      int FlagReceive = TablBrig.Audit_Receive();
      // TablBrig.Receive(2,Brig,FlagReceive,4);
      TablBrig.Receive(0,0,FlagReceive,4);
      int AdrTopS = TablBrig.GetAdrTop();
      if ( AdrTopS )
      {
         TableTopSumm.Initial(AdrTopS);
         int W = TableTopSumm.Width_Fld(0);
         char Buf[W+1];
         Double_Text(Buf,Sum,TableTopSumm.Accurasy_Fld(0),W);
         TableTopSumm.SText(0,0,static_cast_to_string(Buf));
         TableTopSumm.Rewrite();
      }
      if ( TablBrig.Count_Rcr()>1 || TablBrig.Check_Empty_Rcr(0)!=-1 )
      {
         // осуществляем расчет таблицы
         TablBrig.Fill_Bottom_Text_2(0);
         // сохраняем изменения 
         TablBrig.Rewrite();
      }
      else // пустые таблицы удаляем
      {
         MainTable.Del_Table(NumTable);
      }
   }
   SetCommonCnfInMem("EMPTY_TABL",SaveCnf,"ЇҐз вм",'N',1,0);
   // если создавалась таблица по отдельным ЛС, то в конце ее сохраняем
   if ( bInitTablLS )
      TablLS.Rewrite();

   // сохраняем изменения в главной таблице
   MainTable.Rewrite();
   return ESC;
}

int idxLsTN     =0,
    idxLsSPZ    =1,
    idxLsSumm   =2,
    idxLsMaket  =3,
    CountIdxLS  =4;

int FldLS[CountIdxLS];

InitNumFldLSBrig(&TablLS)
{
   FldLS[idxLsTN    ]=TablLS.Find_Name_Fld("TN");
   FldLS[idxLsSPZ   ]=TablLS.Find_Name_Fld("SPZ");
   FldLS[idxLsSumm  ]=TablLS.Find_Name_Fld("SUM_NAR");
   FldLS[idxLsMaket ]=TablLS.Find_Name_Fld("MAKET");
   for ( int idx=0; idx<CountIdxLS; ++idx )
      if ( FldLS[idx]==-1 )
      {
         AmbaMessageBox("ЌҐв ­Ґ®Ўе®¤Ё¬ле Ї®«Ґ© ў в Ў«ЁжҐ ¤«п ®в¤Ґ«м­ле ‹‘!","ЋиЁЎЄ !!!",MB_OK|MB_ICONERROR,0);
         return false;
      }
   return true;
}

int idxDbfKSP   =0,
    idxDbfTN    =1,
    idxDbfSPZ   =2,
    idxDbfSumm  =3,
    idxDbfCalDay=4,
    idxDbfMaket =5,
    idxDbfWKTU  =6,
    CountIdxDbf =7;

int FldDbf[CountIdxDbf];

InitNumFldDbfBrig(&TablDbf)
{
   FldDbf[idxDbfKSP   ]=TablDbf.Find_Name_Fld("KSP");
   FldDbf[idxDbfTN    ]=TablDbf.Find_Name_Fld("TN");
   FldDbf[idxDbfSPZ   ]=TablDbf.Find_Name_Fld("SPZ");
   FldDbf[idxDbfSumm  ]=TablDbf.Find_Name_Fld("SUM_NAR");
   FldDbf[idxDbfCalDay]=TablDbf.Find_Name_Fld("DE");
   FldDbf[idxDbfMaket ]=TablDbf.Find_Name_Fld("MAKET");
   FldDbf[idxDbfWKTU  ]=TablDbf.Find_Name_Fld("WKTU");
   for ( int idx=0; idx<CountIdxDbf; ++idx )
      if ( FldDbf[idx]==-1 )
      {
         AmbaMessageBox("ЌҐв ­Ґ®Ўе®¤Ё¬ле Ї®«Ґ© ў dbf-д ©«Ґ!","ЋиЁЎЄ !!!",MB_OK|MB_ICONERROR,0);
         return false;
      }
   return true;
}

DefineNumShabBrig(TN,Maket,Wktu)
{
   if ( TN!=0 ) return ShbSimple;
   if ( Maket==501 ) return (Wktu==0)?Shb501_0:Shb501_4;
   if ( Maket==508 ) return Shb508;
   return 0;
}

PanelReceiveTablBrig(&NameDbf,&Regim)
{
   char Insert01[2];
   char Access01[2];
   for ( int i = 0;i<2;++i )
      Insert01[i]=Access01[i]=' ';
   string Text01[2];
   Text01[0]="Ё§ dbf-д ©« ",
   Text01[1]="Ё§ ‹‘",
   Insert01[Regim]='\0';

   var Elem[2];
   for ( int i=0; i<2; ++i)
      Elem[i]=CreateObject("KControlElement");
      // Тип приема
   Elem[0].Initial(19,2,13,1,17,2,0,0,0,E_AUTO_SELECT,2,1,
                   "Before_S","Control_S","",Text01, Insert01, Access01);
   var Head[1];
   for ( int i=0; i<1; ++i )
      Head[i]=CreateObject("KControlHeading");
   Head[0].Initial("‘®§¤ ­ЁҐ в Ў«Ёж:",2,2,17,2,1);

   char Insert02[1];
   char Access02[1];
   var Text02[1];
   MakeReferenceVar(Text02[0],NameDbf);
   Insert02[0]=Access02[0]=' ';
   Elem[1].Initial(40,2,255,1,30,1,0,0,0,E_EDIT_AREA,1,1,"Before_S",
                   "Check_File_Exist","  ",Text02,Insert02, Access02);
   if ( Panel(Elem,2,Head,1,2,6,78,13,' ',5,"CtrlPanelBrig",0,"‘®§¤ ­ЁҐ ЎаЁЈ ¤­ле в Ў«Ёж") == ESC )
      return ESC;
   Regim = strlen(Insert01);
}

CtrlPanelBrig(&Elem,&Head,Field)
{
   bool bContinue = false;
   Field=Field;

   int Regim = strlen(Elem[0].Insert);
   Elem[1].Flag_Out=!Regim?1:0;
   return(0);
}

IsSimvTabelWorkBrig(&Dat1)
{
   var Dat = CreateObject("KDate");
   double d = GetDateFromFuncRWScript(Dat1); // получаем дату в виде ГГГГММ.ДД
   Dat.SetDateD(d);
   if ( Dat.IsEqI(INVALID_DATE_VALUE) ) return 0;
   int mraschtmp = mrasch;
   if ( Dat.GetAbs()!=mrasch ) s50(Dat.GetAbs());
   int z = Dat.GetDay()-1;
   char c = calm[z];
   if ( mraschtmp!=mrasch )
      s50(mraschtmp);
   string simv = simv_nr+rsimv;
   if ( !reinterpret_cast_to_long(strrchr(simv,c)) )
      return 0;
   return 1;
}
