Выгрузка работников из Бухгалтерии в Документооборот КОРП

Описание реализации выгрузки пользователей из конфигурации Бухгалтерия для Казахстана (ред. 1) в Документооборот для Казахстана КОРП (ред. 2). На стороне источника используется веб-сервис. На стороне приемника внешняя обработка.

На стороне источника (БП) реализован веб-сервис UploadUsers и метод Upload().

Для передачи данных реализован XDTO-пакет следующей структуры:

Написана функция для метода Upload(). Код приведен ниже:

Функция Upload()

УстановитьПривилегированныйРежим(Истина);

Запрос = Новый Запрос;
Запрос.Текст=
"ВЫБРАТЬ РАЗРЕШЕННЫЕ
| РаботникиОрганизацийСрезПоследних.Физлицо,
| МАКСИМУМ(РаботникиОрганизацийСрезПоследних.Период) КАК Период,
| РаботникиОрганизацийСрезПоследних.ПричинаИзмененияСостояния,
| РаботникиОрганизацийСрезПоследних.ПодразделениеОрганизации,
| РаботникиОрганизацийСрезПоследних.Должность
|ПОМЕСТИТЬ втПриемы
|ИЗ
| РегистрСведений.РаботникиОрганизаций.СрезПоследних(
|   &ДатаАктуальности,
|   Организация = &Организация
|    И ПричинаИзмененияСостояния В (&сзСостояния)) КАК РаботникиОрганизацийСрезПоследних
|
|СГРУППИРОВАТЬ ПО
| РаботникиОрганизацийСрезПоследних.Физлицо,
| РаботникиОрганизацийСрезПоследних.ПричинаИзмененияСостояния,
| РаботникиОрганизацийСрезПоследних.ПодразделениеОрганизации,
| РаботникиОрганизацийСрезПоследних.Должность
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ РАЗРЕШЕННЫЕ
| РаботникиОрганизацийСрезПоследних.Физлицо,
| МАКСИМУМ(РаботникиОрганизацийСрезПоследних.Период) КАК Период,
| РаботникиОрганизацийСрезПоследних.ПричинаИзмененияСостояния
|ПОМЕСТИТЬ втУволенные
|ИЗ
| РегистрСведений.РаботникиОрганизаций.СрезПоследних(
|   &ДатаАктуальности,
|   Организация = &Организация
|    И ПричинаИзмененияСостояния = &парамУвольнение) КАК РаботникиОрганизацийСрезПоследних
|
|СГРУППИРОВАТЬ ПО
| РаботникиОрганизацийСрезПоследних.Физлицо,
| РаботникиОрганизацийСрезПоследних.ПричинаИзмененияСостояния
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ РАЗРЕШЕННЫЕ
| втПриемы.Физлицо,
| втПриемы.ПричинаИзмененияСостояния КАК Принят,
| втУволенные.ПричинаИзмененияСостояния КАК Уволен,
| втПриемы.ПодразделениеОрганизации,
| втПриемы.Должность
|ПОМЕСТИТЬ втПредРаботники
|ИЗ
| втПриемы КАК втПриемы
|  ЛЕВОЕ СОЕДИНЕНИЕ втУволенные КАК втУволенные
|  ПО втПриемы.Физлицо = втУволенные.Физлицо
|   И втПриемы.Период < втУволенные.Период
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ РАЗРЕШЕННЫЕ
| втПредРаботники.Физлицо,
| втПредРаботники.ПодразделениеОрганизации,
| втПредРаботники.Должность
|ПОМЕСТИТЬ втРаботающие
|ИЗ
| втПредРаботники КАК втПредРаботники
|ГДЕ
| втПредРаботники.Уволен ЕСТЬ NULL
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| КонтактнаяИнформация.Объект,
| КонтактнаяИнформация.Тип,
| КонтактнаяИнформация.Вид,
| КонтактнаяИнформация.Представление
|ПОМЕСТИТЬ втДоменныеУчетныеЗаписи
|ИЗ
| РегистрСведений.КонтактнаяИнформация КАК КонтактнаяИнформация
|ГДЕ
| КонтактнаяИнформация.Тип = &Тип
| И КонтактнаяИнформация.Вид = &Вид
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ РАЗРЕШЕННЫЕ
| втРаботающие.Физлицо,
| втРаботающие.ПодразделениеОрганизации,
| ЕСТЬNULL(втРаботающие.Должность, """") КАК Должность,
| ЕСТЬNULL(втРаботающие.ПодразделениеОрганизации.Родитель, """") КАК ПодразделениеОрганизацииРодитель,
| ЕСТЬNULL(втДоменныеУчетныеЗаписи.Представление, """") КАК ДомменнаяУчетнаяЗапись
|ИЗ
| втРаботающие КАК втРаботающие
|  ЛЕВОЕ СОЕДИНЕНИЕ втДоменныеУчетныеЗаписи КАК втДоменныеУчетныеЗаписи
|  ПО втРаботающие.Физлицо = втДоменныеУчетныеЗаписи.Объект
|
|УПОРЯДОЧИТЬ ПО
| втРаботающие.Физлицо.Наименование";
Запрос.УстановитьПараметр("Организация", Справочники.Организации.НайтиПоКоду("000000001"));
Запрос.УстановитьПараметр("ДатаАктуальности", ТекущаяДата());
Запрос.УстановитьПараметр("Тип", Перечисления.ТипыКонтактнойИнформации.Другое);
Запрос.УстановитьПараметр("Вид", Справочники.ВидыКонтактнойИнформации.НайтиПоКоду("KR0000007"));


сзСостояния = Новый СписокЗначений;
сзСостояния.Добавить(Перечисления.ПричиныИзмененияСостояния.ПриемНаРаботу);
сзСостояния.Добавить(Перечисления.ПричиныИзмененияСостояния.Перемещение);

Запрос.УстановитьПараметр("сзСостояния", сзСостояния);
Запрос.УстановитьПараметр("парамУвольнение", Перечисления.ПричиныИзмененияСостояния.Увольнение);

тзРез = Запрос.Выполнить().Выгрузить();

Если тзРез.Количество()>0 тогда

МассивПользователейТип = ФабрикаXDTO.Тип("http://www.company.kz/ws/users", "UserList");
ПользовательТип = ФабрикаXDTO.Тип("http://www.company.kz/ws/users", "User");

UserList = ФабрикаXDTO.Создать(МассивПользователейТип);

Для каждого стр из тзРез Цикл

User = ФабрикаXDTO.Создать(ПользовательТип);

User.FIO         = стр.ФизЛицо.Наименование;
User.unit_name   = стр.ПодразделениеОрганизации.Наименование;
User.unit_id     = стр.ПодразделениеОрганизации.Код;
User.upunit_name = стр.ПодразделениеОрганизацииРодитель.Наименование;
User.upunit_id   = стр.ПодразделениеОрганизацииРодитель.Код;
User.user_id     = стр.ФизЛицо.Код;
User.user_post   = стр.Должность.Наименование;
User.dclogin     = стр.ДомменнаяУчетнаяЗапись;

UserList.User.Добавить(User);

КонецЦикла;

Возврат UserList;

КонецЕсли;

УстановитьПривилегированныйРежим(Ложь);

КонецФункции

 

На стороне приемника (ДО) запускается внешняя обработка, которая получает данные от веб-сервиса и создает в ДО подразделения, пользователи, должности. Код обработки приведен ниже:


&НаСервере
Процедура НачатьСинхронизациюНаСервере()
//подключаемся к веб-сервису
всОпред = Новый WSОпределения(Объект.СтрокаПодключенияКВебСервису,Объект.Пользователь,Объект.Пароль,,,);
всПрокси = Новый WSПрокси(всОпред, "http://www.company.kz/ws/users", "UploadUsers", "UploadUsersSoap",,,);
всПрокси.Пользователь=Объект.Пользователь;
всПрокси.Пароль=Объект.Пароль;
//вызываем метод веб-сервиса
Значение = всПрокси.Upload();
//создаем таблицу значений, в которую выгрузим данные
ТЗПользователей = Новый ТаблицаЗначений;
ТЗПользователей.Колонки.Добавить("ФИО");
ТЗПользователей.Колонки.Добавить("ДоменнаяУчетнаяЗапись");
ТЗПользователей.Колонки.Добавить("Подразделение");
ТЗПользователей.Колонки.Добавить("ВышестоящееПодразделение");
ТЗПользователей.Колонки.Добавить("Должность");
ТЗПользователей.Колонки.Добавить("КодСотрудника");
ТЗПользователей.Колонки.Добавить("КодПодразделения");
ТЗПользователей.Колонки.Добавить("КодВышестоящееПодразделение");

Для каждого стр из Значение.User цикл

НоваяСтрока = ТЗПользователей.Добавить();
НоваяСтрока.ФИО                          = стр.FIO;
НоваяСтрока.ДоменнаяУчетнаяЗапись        = стр.dclogin;
НоваяСтрока.Подразделение                = стр.unit_name;
НоваяСтрока.ВышестоящееПодразделение     = стр.upunit_name;
НоваяСтрока.Должность                    = стр.user_post;
НоваяСтрока.КодСотрудника                = стр.user_id;
НоваяСтрока.КодПодразделения             = стр.unit_id;
НоваяСтрока.КодВышестоящееПодразделение  = стр.upunit_id;

КонецЦикла;

Для каждого стрТЗ из ТЗПользователей цикл
//ищем подразделение вместе с вышестоящим
ИскПодразделение = НайтиИлиСоздатьПодразделение(стрТЗ.КодПодразделения,стрТЗ.Подразделение,стрТЗ.КодВышестоящееПодразделение,стрТЗ.ВышестоящееПодразделение);
//ищем пользователя
ИскСотрудник = НайтиПользователя(стрТЗ.КодСотрудника);

Если ИскСотрудник=Неопределено тогда
ОбъектПользователь = Справочники.Пользователи.СоздатьЭлемент();
//заполняем дополнительный реквизит "КодСотрудника" кодом из источника
НовСтрока = ОбъектПользователь.ДополнительныеРеквизиты.Добавить();
НовСтрока.Свойство = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоНаименованию("КодСотрудника");
НовСтрока.Значение = стрТЗ.КодСотрудника;
НовСтрока.ТекстоваяСтрока = стрТЗ.КодСотрудника;

Иначе ОбъектПользователь = ИскСотрудник.ПолучитьОбъект();
КонецЕсли;

ОбъектПользователь.Наименование = стрТЗ.ФИО;
ОбъектПользователь.Подразделение = ИскПодразделение.Ссылка;
ОбъектПользователь.КодЯзыка = "ru";
ОбъектПользователь.ПредставлениеВДокументах = стрТЗ.ФИО;
ОбъектПользователь.ПредставлениеВПереписке = стрТЗ.ФИО;
ОбъектПользователь.ПредставлениеВПерепискеСРангом = стрТЗ.ФИО;

//создаем пользователя информационной базы отправляя структуру параметров через дополнительные свойства
//процедуры сами сделают связь с элементом справочника "Пользователи" и пользователем ИБ через уникальный идентификатор
ОписаниеПользователяИБ = Новый Структура;
ОписаниеПользователяИБ.Вставить("Действие", "Записать");
ОписаниеПользователяИБ.Вставить("Имя", стрТЗ.ФИО);
ОписаниеПользователяИБ.Вставить("ПолноеИмя", стрТЗ.ФИО);
ОписаниеПользователяИБ.Вставить("АутентификацияОС", Истина);
ОписаниеПользователяИБ.Вставить("ПоказыватьВСпискеВыбора", Истина);
ОписаниеПользователяИБ.Вставить("ПользовательОС", стрТЗ.ДоменнаяУчетнаяЗапись);
ОписаниеПользователяИБ.Вставить("АутентификацияСтандартная", Ложь);

ОбъектПользователь.ДополнительныеСвойства.Вставить("ОписаниеПользователяИБ", ОписаниеПользователяИБ);
ОбъектПользователь.Записать();
//записываем доп сведения по пользователю, чтобы в карточке пользователя отображались
НаборЗаписей = РегистрыСведений.СведенияОПользователяхДокументооборот.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Пользователь.Установить(ОбъектПользователь.Ссылка);
НаборЗаписей.Прочитать();
НаборЗаписей.Записать();
Запись = НаборЗаписей.Добавить();
Запись.Пользователь = ОбъектПользователь.Ссылка;
Запись.Подразделение = ИскПодразделение.Ссылка;
Запись.Должность = ?(ПустаяСтрока(стрТЗ.Должность),"", НайтиИлиСоздатьДолжность(стрТЗ.Должность));
Запись.ГрафикРаботы = Справочники.ГрафикиРаботы.НайтиПоНаименованию("Пятидневка");
НаборЗаписей.Записать();

КонецЦикла;

КонецПроцедуры

&НаСервере
Функция НайтиИлиСоздатьДолжность(НаименованиеДолжности)

ИскДолжность = Справочники.Должности.НайтиПоНаименованию(НаименованиеДолжности, Истина);

Если ИскДолжность=Справочники.Должности.ПустаяСсылка() тогда
ДолжноситьОбъект = Справочники.Должности.СоздатьЭлемент();
ДолжноситьОбъект.Наименование = НаименованиеДолжности;
ДолжноситьОбъект.Записать();

ИскДолжносить = ДолжноситьОбъект.Ссылка;
КонецЕсли;

Возврат ИскДолжность.Ссылка;

КонецФункции


&НаСервере
Функция НайтиИлиСоздатьПодразделение(КодПодразделения,Подразделение,КодВышестоящееПодразделение,ВышестоящееПодразделение)

//сперва изем вышестоящее подразделение, если нет то создаем
Запрос = новый Запрос;
Запрос.Текст=
"ВЫБРАТЬ
| СтруктураПредприятияДополнительныеРеквизиты.Ссылка
|ИЗ
| Справочник.СтруктураПредприятия.ДополнительныеРеквизиты КАК СтруктураПредприятияДополнительныеРеквизиты
|ГДЕ
| СтруктураПредприятияДополнительныеРеквизиты.Свойство = &Свойство
| И СтруктураПредприятияДополнительныеРеквизиты.Значение = &Значение";
Запрос.УстановитьПараметр("Свойство", ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоНаименованию("ВнешнийКод"));
Запрос.УстановитьПараметр("Значение", КодВышестоящееПодразделение);

тзВышПод = Запрос.Выполнить().Выгрузить();

Если тзВышПод.Количество()>0 тогда
ВышПод = тзВышПод[0].Ссылка.ПолучитьОбъект();
Иначе ВышПод = Справочники.СтруктураПредприятия.СоздатьЭлемент();
ВышПод.Наименование = ВышестоящееПодразделение;

НовСтрока = ВышПод.ДополнительныеРеквизиты.Добавить();
НовСтрока.Свойство = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоНаименованию("ВнешнийКод");
НовСтрока.Значение = КодВышестоящееПодразделение;
НовСтрока.ТекстоваяСтрока = КодВышестоящееПодразделение;
ВышПод.Записать();

КонецЕсли;

//теперь ищем само подразделение
Запрос = новый Запрос;
Запрос.Текст=
"ВЫБРАТЬ
| СтруктураПредприятияДополнительныеРеквизиты.Ссылка
|ИЗ
| Справочник.СтруктураПредприятия.ДополнительныеРеквизиты КАК СтруктураПредприятияДополнительныеРеквизиты
|ГДЕ
| СтруктураПредприятияДополнительныеРеквизиты.Свойство = &Свойство
| И СтруктураПредприятияДополнительныеРеквизиты.Значение = &Значение";
Запрос.УстановитьПараметр("Свойство", ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоНаименованию("ВнешнийКод"));
Запрос.УстановитьПараметр("Значение", КодПодразделения);

тзПод = Запрос.Выполнить().Выгрузить();

Если тзПод.Количество()>0 тогда
Под = тзПод[0].Ссылка.ПолучитьОбъект();
Иначе Под = Справочники.СтруктураПредприятия.СоздатьЭлемент();
Под.Наименование = Подразделение;

НовСтрока = Под.ДополнительныеРеквизиты.Добавить();
НовСтрока.Свойство = ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоНаименованию("ВнешнийКод");
НовСтрока.Значение = КодПодразделения;
НовСтрока.ТекстоваяСтрока = КодПодразделения;
Под.Записать();

КонецЕсли;

Под.Родитель = ВышПод.Ссылка;

Под.Записать();

Возврат Под.Ссылка;

КонецФункции

&НаСервере
Функция НайтиПользователя(КодСотрудника)

ИскПользователь = Неопределено;

Запрос = Новый Запрос;
Запрос.Текст=
"ВЫБРАТЬ
| ПользователиДополнительныеРеквизиты.Ссылка
|ИЗ
| Справочник.Пользователи.ДополнительныеРеквизиты КАК ПользователиДополнительныеРеквизиты
|ГДЕ
| ПользователиДополнительныеРеквизиты.Свойство = &Свойство
| И ПользователиДополнительныеРеквизиты.Значение = &Значение";
Запрос.УстановитьПараметр("Свойство",ПланыВидовХарактеристик.ДополнительныеРеквизитыИСведения.НайтиПоНаименованию("КодСотрудника"));
Запрос.УстановитьПараметр("Значение",КодСотрудника);

тзРез = Запрос.Выполнить().Выгрузить();

Если тзРез.Количество()>0 тогда
ИскПользователь = тзРез[0].Ссылка;
КонецЕсли;

Возврат ИскПользователь;

КонецФункции


&НаКлиенте
Процедура НачатьСинхронизацию(Команда)
НачатьСинхронизациюНаСервере();
КонецПроцедуры

Можете скачать архив со схемой XDTO-пакета и обработкой "Синхронизация пользователей".

В итоге получаем выстроенную структуру предприятия, пользователей и авторизацию через ОС. Затем, опубликовав базу Документооборот на веб-сервере, получаем работающую систему ДО.

 

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *