/*

// заголовки и описания параметров некоторых скриптовых функций для обработки табеля
// там где есть функции UserTabelProcess* и UserTabelUpdate* разница между ними в следующем:
//  - первая не должна изменять значения в программе, но может кидать исключения для отмены обработки письма
//  - вторая как раз должна изменять значения и кидать в ней исключения нельзя!

// Если следующие две функции есть - то обработка письма табеля целиком в их ведении, 
// никакие другие функции из тех, что ниже - вызваны не будут

// параметры функций:
//   ID_Combine - внутренний код исполняемой должности (к этому моменту она уже выбрана в TmpCurCombine)
//   xmlNode - xml пришедший из КП (класс XMLDOMNode), в значениях win-кодировка
//   dateStart, dateEnd - даты начала и конца табеля (класс KDate), обычно дата начала и конца месяца

UserTabelProcessData(ID_Combine, xmlNode, dateStart, dateEnd) 
   // эта функция для первоначальных проверок, если не нужно обрабатывать письмо то 
   // выполнить следующий код:
   //                           var err="Текст сообщения"; throw err;
   // возвращает целое число больше 0 если изменения планируются, иначе 0
{

}

UserTabelUpdateData(ID_Combine, xmlNode, dateStart, dateEnd) 
   // в этой функции необходимо записать данные в ЛС
   // бросать здесь исключения нельзя ни в коем случае!!!
   // возвращает целое число больше 0 если изменения были, иначе 0
{


}



// Следующие две функции аналогичны предыдущим двум, только здесь надо разнести РВ
// Если раскомментированы предыдущие 2 функции - то эти вызываться не будут
// Если эти функции раскомментированы - то обработка итоговых данных по РВ (разноска на виды) 
// полностью в их ведении, и функции UserProcessOneRv/UserUpdateOneRv вызваны не будут

UserRVProcessData(ID_Combine, xmlNode, dateStart, dateEnd) 
   // эта функция для первоначальных проверок, если не нужно обрабатывать письмо то 
   // выполнить следующий код:
   //                           var err="Текст сообщения"; throw err;
   // если РВ в xml отличается от РВ в ЛС - взвести соответствующий флаг из Changes
   // в результате функции
{
   // ID_Combine - внутренний код исполняемой должности (к этому моменту она уже выбрана в TmpCurCombine)
   // xmlNode - xml пришедший из КП (класс XMLDOMNode), в значениях win-кодировка
   // dateStart, dateEnd - даты начала и конца табеля (класс KDate), обычно дата начала и конца месяца

   const int vidscnt=8;

   // флаги, комбинацию которых надо вернуть, если значение РВ в ЛС отличается
   // от разносимого
   int Changes[vidscnt + 1];
   Changes[0]=0x0004; // bEvening
   Changes[1]=0x0008; // bNight
   Changes[2]=0x0010; // bOvertime
   Changes[3]=0x0020; // bOvertime
   Changes[4]=0x0040; // bSr
   Changes[5]=0x0080; // bDop
   Changes[6]=0x0100; // bHoliday
   Changes[7]=0x0200; // bIdle
   Changes[8]=0x0400; // bUser - вид не из тэгов xmlTags (описаны ниже), а из тэгов Сумма (xml-схема письма в RSCALT\IntegrationKP.xsd)

   //xml-тэги, из которых брать РВ     
   string xmlTags[vidscnt];
   xmlTags[0]="ВечернееВремя";
   xmlTags[1]="НочноеВремя";
   xmlTags[2]="Сверхурочные1";
   xmlTags[3]="Сверхурочные2";
   xmlTags[4]="ВремяОплачиваемоеПоСреднему";
   xmlTags[5]="ДополнительныйВыход";
   xmlTags[6]="ДополнительныйВыходВПраздничныеДни";
   xmlTags[7]="НецелосменныеПростои";

   //настройка, в которой указан вид, куда нужно разнести РВ из соотв. xml-тэга 
   //0 - не разносить
   string cnfs[vidscnt];
   cnfs[0]="EvVid";
   cnfs[1]="NightVid";
   cnfs[2]="OvertVid";
   cnfs[3]="OvertVid2";
   cnfs[4]="SrVid";
   cnfs[5]="DopVid";
   cnfs[6]="HolidVid";
   cnfs[7]="IdleVid";

   //настройка, где указана сетка для разноски дополнительных видов из тэга Сумма
   string cnfUserSet = "UserVidSet";
  
   int result=0;
   return result;
}

UserRVUpdateData(ID_Combine, xmlNode, dateStart, dateEnd) 
{  // в этой функции необходимо записать данные в ЛС
   // бросать здесь исключения нельзя ни в коем случае!!!
   // если РВ в xml отличается от РВ в ЛС - взвести соответствующий флаг из Changes в результате функции 
   // (см. Changes в предыдущей функции)

   // ID_Combine - внутренний код исполняемой должности (к этому моменту она уже выбрана в TmpCurCombine)
   // xmlNode - xml пришедший из КП (класс XMLDOMNode), в значениях win-кодировка
   // dateStart, dateEnd - даты начала и конца табеля (класс KDate), обычно дата начала и конца месяца

   const int vidscnt=8;

   //xml-тэги, из которых брать РВ     
   string xmlTags[vidscnt];
   xmlTags[0]="ВечернееВремя";
   xmlTags[1]="НочноеВремя";
   xmlTags[2]="Сверхурочные1";
   xmlTags[3]="Сверхурочные2";
   xmlTags[4]="ВремяОплачиваемоеПоСреднему";
   xmlTags[5]="ДополнительныйВыход";
   xmlTags[6]="ДополнительныйВыходВПраздничныеДни";
   xmlTags[7]="НецелосменныеПростои";

   //настройка, в которой указан вид, куда нужно разнести РВ из соотв. xml-тэга 
   //0 - не разносить
   string cnfs[vidscnt];
   cnfs[0]="EvVid";
   cnfs[1]="NightVid";
   cnfs[2]="OvertVid";
   cnfs[3]="OvertVid2";
   cnfs[4]="SrVid";
   cnfs[5]="DopVid";
   cnfs[6]="HolidVid";
   cnfs[7]="IdleVid";

   //настройка, где указана сетка для разноски дополнительных видов из тэга Сумма
   string cnfUserSet = "UserVidSet";

}



// обработка всех символов и часов табеля в письме
// Если следующие две функции раскомментированы - то обработка символьных(и часовых) данных табеля 
// в их ведении, функции UserTabelProcessOneDay/UserTabelUpdateOneDay вызваны не будут
// Если раскомментированы функции UserTabelProcessData/UserTabelUpdateData - то эти вызываться не будут

// параметры функций:
//   ID_Combine - внутренний код исполняемой должности (к этому моменту она уже выбрана в TmpCurCombine)
//   xmlNode - xml пришедший из КП (класс XMLDOMNode), в значениях win-кодировка
//   dateStart, dateEnd - даты начала и конца табеля (класс KDate), обычно дата начала и конца месяца

UserTabelProcessAllDays(ID_Combine, xmlNode, dateStart, dateEnd)
   // эта функция для первоначальных проверок, если не нужно обрабатывать письмо то 
   // выполнить следующий код:
   //                           var err="Текст сообщения"; throw err;
   // возвращает целое число больше 0 если изменения планируются, иначе 0
{

}

UserTabelUpdateAllDays(ID_Combine, xmlNode, dateStart, dateEnd)
   // в этой функции необходимо записать данные в ЛС (в символьный и, если необходимо, в часовой табеля)
   // бросать здесь исключения нельзя ни в коем случае!!!
   // возвращает целое число больше 0 если изменения были, иначе 0
{

}



// следующие две функции отвечают за обработку символа и часов табеля за один день, 
// здесь можно перегрузить запись значений в ячейку символьного/часового табеля
// Если раскомментированы функции UserTabelProcessData/UserTabelUpdateData или 
// UserTabelProcessAllDays/UserTabelUpdateAllDays - то эти функции вызываться не будут
//! кроме того функции не вызываются при интеграции табеля с Гособлаком, когда в письме может быть больше одной 
//! пары "код-часы" в одном дне

// параметры функций:
//   ID_Combine - внутренний код исполняемой должности (к этому моменту она уже выбрана в TmpCurCombine)
//   date - день, по которому разноска (класс KDate)
//   tableCodeKP - код табеля в программе-источнике (КП или Гособолаке), строка в win-кодировке!
//   rv - рабочее время по этому коду (строка в формате hhh:mm)

UserTabelProcessOneDay(ID_Combine, date, tabelCodeKP, rv)
   // эта функция для первоначальных проверок, если не нужно обрабатывать письмо то 
   // выполнить следующий код:
   //                           var err="Текст сообщения"; throw err;
   // возвращает целое число больше 0 если изменения планируются, иначе 0
{

}

UserTabelUpdateOneDay(ID_Combine, date, tabelCodeKP, rv)
   // в этой функции необходимо записать данные в ЛС (в символьный и, если необходимо, в часовой табеля)
   // бросать здесь исключения нельзя ни в коем случае!!!
   // возвращает целое число больше 0 если изменения были, иначе 0
{

}


// следующие две функции отвечают за обработку итоговых данных за период по РВ по одному символу 
// Если раскомментированы функции UserTabelProcessData/UserTabelUpdateData или 
// UserRVProcessData/UserRVUpdateData - то эти функции вызываться не будут

// параметры функций: 
//   ID_Combine - внутренний код исполняемой должности (к этому моменту она уже выбрана в TmpCurCombine)
//   dateStart - дата начала периода табеля в письме (класс KDate), обычно здесь дата начала месяца
//   int intCode - внутренний код вида НУ, на который надо разнести итоговую сумму РВ
//   double rv - сумма рабочего времени (в десятичных долях часа)

UserTabelProcessOneRv(ID_Combine, dateStart, intCode, rv)
   // эта функция для первоначальных проверок, если не нужно обрабатывать письмо то 
   // выполнить следующий код:
   //                           var err="Текст сообщения"; throw err;
   // возвращает целое число больше 0 если изменения планируются, иначе 0
{

}

UserTabelUpdateOneRv(ID_Combine, dateStart, intCode, rv)
   // в этой функции необходимо разнести РВ на вид intCode
   // бросать здесь исключения нельзя ни в коем случае!!!
   // возвращает целое число больше 0 если изменения были, иначе 0
   // если запись rv идет в старую матрицу (функцией PutTime) - надо вызвать toMatrLS!
{

}



// для нового вида письма (из Гособлака, с несколькими наборами "код-часы" в одном дне)
// функция отвечает за выбор кода и часов, которые программа запишет в табель
// Если раскомментированы функции UserTabelProcessData/UserTabelUpdateData или 
// UserTabelProcessAllDays/UserTabelUpdateAllDays или 
// UserTabelProcessOneDay/UserTabelUpdateOneDay- то эта функция вызываться не будет

// параметры функции:
//   ID_Combine - внутренний код исполняемой должности (к этому моменту она уже выбрана в TmpCurCombine)
//   date - день, по которому разноска (класс KDate)
//   string[codeTimesArraySize][2] codeTimesArray - массив с кодами и временами из письма (массив строк), 
//                                                  codeTimesArray[i][0] - код дня табеля из ГО, в win-кодировке
//                                                  codeTimesArray[i][1] - время в формате "hh:mm"
//   codeTimesArraySize - количество "пар" в массиве codeTimesArray 
//                        (первый индекс массива codeTimesArray изменяется в пределах от 0 до codeTimesArraySize-1 включительно)
//   _selectedCode - выходной параметр, ожидается код (один символ, тип char) который будет разнесён в день, в OEM-кодировке!
//   _selectedTime - выходной параметр, ожидается время в формате строки "hh:mm", которое будет разнесено в день

// возвращает целое число больше 0, в случае успешного выбора и необходимости разнести _selectedCode и _selectedTime в табель
// однако в случае если _selectedCode - не изменялся или там нулевой символ - то программа отрабатывает как будто функция вернула 0
// если _selectedTime не менялся, его значением считается "00:00"

UserTabelSelectDayCodeTime(ID_Combine, kDate, codeTimesArray, codeTimesArraySize, &_selectedCode, &_selectedTime)
{

}


*/



/*

int UserIdleScript_SkipFirstStart=0;

UserIdleScript() 
{
	// функция которая запускается при бездействии пользователя через промежуток 
	// времени указанный в переменной UserScriptRunInterval (в usconst.s)
   // если первый запуск (сразу после старта программы) нужно пропустить, то можно 
   // выше присвоить UserIdleScript_SkipFirstStart=1;

   if (UserIdleScript_SkipFirstStart)
   {
   	UserIdleScript_SkipFirstStart=0; return 0;
   }

   var CMsg = 0;    // Процент выполненной работы

   int bTime = false;   // false-показывать процент,
                        // true-показывать оставшееся время

   CMsg=CreateObject("ProgressBar");
   CMsg.Initial(0,100,1);
   CMsg.SetShowTime(static_cast_to_int(bTime));

   for(int i=0;i<2000;i++)
   {
      if ( CMsg.Msg_Proc(AnsiToOem(" Пример фоновой задачи. "),100.*i/2000)==ESC )
         return 0;

      int n;
      for(int u=0;u<100000;u++)
         n=u*u*i/123+i-u*n;
   }
}
*/




/* Пример пользовательской функции обработки приказа по виду для разноски количества ставок из тэга Процент в поле КЧ "Коэффициент занятости-ставка", 
   работает только для 496вида с заполненным в письме тэгом "Параметры/ОкладПоСетке" 
   
UserIntegrProcessVidNU(typeOrd,doljnAmbaId,AmbaKey,xmlNode)
{
   string oldAmbaKey=AmbaKey;
   var oldDate;
   bool bNewOrder=!VarHasValue(oldAmbaKey) || oldAmbaKey=="";
   if (!bNewOrder) //изменение вида, нужно удалить старое значение из кч
   {
      int row = GetRowForIntCode(oldAmbaKey);
      if (row!=-1)
      {
         oldDate = KDateFromD(GetBegDate(row)); // старая дата начала вида
      }
   }
   string newAmbaKey=SysIntegrProcessVidNU(typeOrd,doljnAmbaId,AmbaKey,xmlNode); // системная функция обработки приказа: разносит/изменяет вид и возвращает код вида 
   if (VarHasValue(newAmbaKey) && newAmbaKey!="")
   {
      string KodKP=GetXmlValue(xmlNode, "Код");
      if (KodKP=="496")
      {
         string OkladSet= IntegrGetSetkaValue(GetXmlValue(xmlNode, "Параметры/ОкладПоСетке"),doljnAmbaId,xmlNode);
         if (OkladSet!="")
         {
            string Procent= GetXmlValue(xmlNode, "Параметры/Процент");
            if (Procent=="") Procent="100"; //если процент не задан то пишем ставку 1
            
            {
               int Id_Combine=0;
               var Param = CreateObject("ParamFuncRW");
               Param.IInitial(doljnAmbaId,",",3);
               if (Param.Count()>1) 
                  Id_Combine=atoi(Param.Get(1));
               var TmpCurCom = CreateObject("TmpCurCombine");
               TmpCurCom.Init(Id_Combine);
               var kdBeg=CreateObject("KDate");
               kdBeg.SetDate(GetXmlValue(xmlNode, "ДНач"));

               if (!bNewOrder && VarHasValue(oldDate)) //изменение вида, нужно удалить старое значение из кч
               {
                  if (!oldDate.IsEq(kdBeg)) // старая дата отличается от новой
                   {
                      // проверим, можно ли удалить старое значение ПКГ из КЧ 
                      // убедимся что нет больше видов с такой же датой начала
                     int rowkod[ROWMAX];
                     var Prop = CreateObject("APropBE");
                     Prop.SetCombine(Id_Combine);
                     int cntrow=poiskosnkodProp(newAmbaKey,rowkod,0,Prop);
                     bool del=true;
                     for (int j=0; j<cntrow; j++)
                     {
                        int r=rowkod[j];
                        var rDate = KDateFromD(GetBegDate(r));
                        if (oldDate.IsEq(rDate)) 
                           del=false;
                     }
                     if (del)  DelKchValue("k_employ",oldDate.GetStr());
                   }
               }
               SetKchValue("k_employ", static_cast_to_string(Procent/100.), kdBeg);
            }
         }
      }
   }
   return newAmbaKey;
}
*/

// функция, вызываемая после смены подразделения ЛС в результате обработки письма из КП на интеграцию исполняемой должности
// bool isDelete = true - функция вызвалась при отмене в КП приказа на прием/перевод 
//                        (при удалении исполяемой должности/строчки в поле КЧ должность);
//                        иначе функция вызвалась при приеме/переводе (создание исп.должности/строчки в поле КЧ должность)
// int podrOld - старое значение подразделения
// int podrNew - новое значение подразделения
// int idCombineOld - внутренний код "старой" исполняемой должности: с которой произошел перевод, либо которую удалили при отмене 
//                    приказа (может быть 0 в случае приема, либо может уже отсутствовать, так как удаление происходит раньше)
// int idCombineNew - внутренний код "новой" исполняемой должности: на которую произошел прием/перевод, а в случае удаления здесь будет 
//                    либо та же должность (если переводы настроены в КЧ), либо предыдущая исполняемая должность (для удаленной), 
//                    предыдущая исполняемая может быть 0 в случае отмены приема
// KDate dateStart - дата начала должности (в случае удаления - она же, т.е. дата начала удаленной должности)
/*
UserIntegrIspDoljn_LSPodrChanged(isDelete, podrOld, podrNew, idCombineOld, idCombineNew, &dateStart)
{
}
*/

/*
// пример функции предварительной обработки письма синхронизации при интеграции с КП
// если из функции будет выброшено исключение - письмо обработано не будет, в качестве ошибки будет записана строка исключения
UserPreProcessSyncLetter(processParams)
{
   // processParams - структура параметров обработки письма интеграции (см. структуру IntegrProcessParams в script\idl\useful.idl)
   // если письмо обрабатывать не надо, функция должна кинуть исключение с тектом ошибки (в Win-кодировке):
   //    var err="Текст сообщения"; throw err;

   // следующий пример запрещает автоматическую обработку писем синхронизации Статуса для доп.взносов, если статус очищается
   // в случае обработки из проблемных пользователю выдается запрос на обработку

   if (processParams.AOType == otStatus3)
   {
      string spisok = GetXmlValue(processParams.XmlNode, "НомерСписка");
      string klass = GetXmlValue(processParams.XmlNode, "КлассУсловийТруда");
      if (spisok == "" && klass == "") //значит это строка о закрытии особых условий труда
      { 
        if (processParams.ProcessingMode == 2)

        {
           var v = CreateObject("TmpDisableDebugMode");
           var err = "Внимание. Строка о закрытии особых условий труда. Возможна только ручная обработка"; 
           throw err;
        }
        else
        {
           string dateBegin = GetXmlValue(processParams.XmlNode, "ДНач");
           if (IDYES != MsgBox("Внимание! Строка о закрытии особых условий труда с даты " + dateBegin +
                               "\nПродолжить обработку письма?", "Контур-Зарплата. Интеграция", 
                                MB_YESNOCANCEL|MB_ICONWARNING))
           {
              var v = CreateObject("TmpDisableDebugMode");
              var err = "Строка о закрытии особых условий труда. Пользователь отказался от обработки"; 
              throw err;
           }
        }
      }
   }
}
*/