Здравствуйте, при внедрении ЗУП у меня возникла необходимость переноса данных для расчета больничных листов. Для решения задачи была написана простая внешняя обработка.
Данные записываются в документы Переносы данных с номерами ЗП_СЗО (регистр накопления "ДанныеОНачисленияхДляРасчетаСреднегоЗаработкаОбщий).
Для чего данная обработка может понадобиться: при внедрении ЗУП, если приходится переносить большой объем данных вручную.
Файл JSON должен быть в следующем формате:
{
"Фамилия1 Имя1 Отчество1": {
"Подразделение": "Подразделение 1",
"01.09.2023 0:00:00": "11111,11",
"01.08.2023 0:00:00": "11111,11",
"01.07.2023 0:00:00": "11111,11",
"01.06.2023 0:00:00": "11111,11",
"01.12.2023 0:00:00": "11111,11",
"01.11.2023 0:00:00": "11111,11",
"01.05.2023 0:00:00": "11111,11",
"01.04.2023 0:00:00": "11111,11",
"01.10.2023 0:00:00": "11111,11",
"01.03.2023 0:00:00": "11111,11",
"01.02.2023 0:00:00": "11111,11",
"01.01.2023 0:00:00": "11111,11"
},
"Фамилия2 Имя2 Отчество2": {
"Подразделение": "Подразделение 2",
"01.09.2023 0:00:00": "22222,22",
"01.08.2023 0:00:00": "22222,22",
"01.07.2023 0:00:00": "22222,22",
"01.06.2023 0:00:00": "22222,22",
"01.12.2023 0:00:00": "22222,22",
"01.11.2023 0:00:00": "22222,22",
"01.05.2023 0:00:00": "22222,22",
"01.04.2023 0:00:00": "22222,22",
"01.10.2023 0:00:00": "22222,22",
"01.03.2023 0:00:00": "22222,22",
"01.02.2023 0:00:00": "22222,22",
"01.01.2023 0:00:00": "22222,22"
}
}
Как работает алгоритм заполнения:
1. в цикле происходит перебор всех документов ЗП_СЗО
2. во вложенном цикле перебираются все сотрудники
3. создается временная таблица, куда попадают данные из файла при совпадении даты документа ЗП_СЗО и ключа из файла JSON
4. таблица записывается в регистр
Исходный код обработки:
&НаКлиенте
Процедура ИмяФайлаJSONНачалоВыбора(Элемент, ДанныеВыбора, ВыборДобавлением, СтандартнаяОбработка)
Оповещение = Новый ОписаниеОповещения("ПослеВыбораФайлаJSON", ЭтотОбъект);
Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
Диалог.Заголовок = "Выберите файл JSON с доходами сотрудников";
Диалог.Фильтр = НСтр("ru='json';en='json'") + "(*.json)|*.json";
Диалог.Показать(Оповещение);
КонецПроцедуры
&НаКлиенте
Процедура ПослеВыбораФайлаJSON(ВыбранныеФайлы, Параметры) Экспорт
Если ВыбранныеФайлы = Неопределено Тогда
Сообщить("Не выбран файл json");
Возврат;
КонецЕсли;
ПутьКФайлу = ВыбранныеФайлы[0];
ИмяФайлаJSON = ПутьКФайлу;
КонецПроцедуры
&НаСервере
Функция ПоискДокументовЗП_СЗО()
ЗапросЗПСЗО = Новый Запрос;
ЗапросЗПСЗО.Текст = "
|ВЫБРАТЬ
|ПереносДанных.Ссылка,
|ПереносДанных.ПериодРегистрации
|ИЗ
| Документ.ПереносДанных КАК ПереносДанных
|ГДЕ
| НЕ ПереносДанных.ПометкаУдаления И
| ПереносДанных.Номер = ""ЗП_СЗО""
|УПОРЯДОЧИТЬ ПО ПереносДанных.ПериодРегистрации
|";
РезультатЗапроса = ЗапросЗПСЗО.Выполнить();
Если РезультатЗапроса.Пустой() Тогда
Возврат Неопределено;
КонецЕсли;
ВыборкаЗПСЗО = РезультатЗапроса.Выбрать();
Соответствие1 = Новый Соответствие;
Пока ВыборкаЗПСЗО.Следующий() Цикл
ПериодРегистрации = ВыборкаЗПСЗО.ПериодРегистрации;
Ссылка = ВыборкаЗПСЗО.Ссылка;
Если ПериодРегистрации <> Неопределено И Ссылка <> Неопределено Тогда
Соответствие1.Вставить(ПериодРегистрации,Ссылка);
КонецЕсли;
КонецЦикла;
Возврат Соответствие1;
КонецФункции
&НаКлиенте
Процедура ВыполнитьИмпорт(Команда)
// проверить, что выбрана организация
Если НЕ ЗначениеЗаполнено(ВыборОрганизации) Тогда
Сообщить("Не выбрана организация");
Возврат;
КонецЕсли;
// проверить, что файл выбран
Если НЕ ЗначениеЗаполнено(ИмяФайлаJSON) Тогда
Сообщить("Не выбран файл для импорта");
Возврат;
КонецЕсли;
// десериализация JSON
Попытка
чтениеJSON = Новый ЧтениеJSON();
чтениеJSON.ОткрытьФайл(ИмяФайлаJSON);
Сотрудники = ПрочитатьJSON(чтениеJSON, Истина);
чтениеJSON.Закрыть();
Исключение
Сообщить("Десериализация JSON .......... ОШИБКА");
Возврат;
КонецПопытки;
// поиск документов типа ЗП_СЗО
РезультатПоискаДокументовЗПСЗО = ПоискДокументовЗП_СЗО();
Если РезультатПоискаДокументовЗПСЗО = Неопределено Тогда
Сообщить("Не найдены документы ЗП_СЗО. Продолжение невозможно");
Возврат;
КонецЕсли;
// Передать найденные документы ЗП_СЗО
ПодготовитьТаблицу(РезультатПоискаДокументовЗПСЗО, Сотрудники, ВыборОрганизации);
КонецПроцедуры
&НаСервере
Процедура ПодготовитьТаблицу(РезультатПоискаДокументовЗПСЗО, Сотрудники, ВыбраннаяОрганизация)
МассивОшибок = Новый Массив;
// перебрать все документы ЗП_СЗО
Для Каждого Элемент Из РезультатПоискаДокументовЗПСЗО Цикл
ПериодРегистрации = Дата(Элемент.Ключ);
СсылкаДокументЗПСЗО = Элемент.Значение;
// создать и подготовить таблицу значений
Таблица = Новый ТаблицаЗначений;
Таблица.Колонки.Добавить("Регистратор", Новый ОписаниеТипов("ДокументСсылка.ПереносДанных"));
Таблица.Колонки.Добавить("Активность", Новый ОписаниеТипов("Булево"));
Таблица.Колонки.Добавить("ОблагаетсяЕНВД", Новый ОписаниеТипов("Булево"));
Таблица.Колонки.Добавить("Индексируется", Новый ОписаниеТипов("Булево"));
Таблица.Колонки.Добавить("Период", Новый ОписаниеТипов("Дата"));
Таблица.Колонки.Добавить("Сумма", Новый ОписаниеТипов("Число"));
Таблица.Колонки.Добавить("ФизическоеЛицо", Новый ОписаниеТипов("СправочникСсылка.ФизическиеЛица"));
Таблица.Колонки.Добавить("Сотрудник", Новый ОписаниеТипов("СправочникСсылка.Сотрудники"));
Таблица.Колонки.Добавить("ПорядокРасчета", Новый ОписаниеТипов("ПеречислениеСсылка.ПорядокРасчетаСреднегоЗаработкаОбщий"));
Таблица.Колонки.Добавить("СоставнаяЧасть", Новый ОписаниеТипов("ПеречислениеСсылка.УчетНачисленийВСреднемЗаработкеОбщий"));
Таблица.Колонки.Добавить("Организация", Новый ОписаниеТипов("СправочникСсылка.Организации"));
Таблица.Колонки.Добавить("Сторно", Новый ОписаниеТипов("Булево"));
// необязательные колонки
Таблица.Колонки.Добавить("Год", Новый ОписаниеТипов("Число"));
Таблица.Колонки.Добавить("ДатаНачалаБазовогоПериода", Новый ОписаниеТипов("Дата"));
Таблица.Колонки.Добавить("КоличествоМесяцев", Новый ОписаниеТипов("Число"));
// перебрать всех сотрудников
Для Каждого Сотрудник Из Сотрудники Цикл
ФИО = Сотрудник.Ключ;
Соответствие1 = Сотрудник.Значение; // здесь все доходы по сотруднику
Подразделение = Соответствие1["Подразделение"];
СсылкаНаСотрудника = Неопределено;
ФизическоеЛицо = Неопределено;
Если ФИО=Неопределено ИЛИ Подразделение=Неопределено Тогда
Сообщить("Ошибка в файле JSON: отсутствуют ФИО и(или) подразделение");
Возврат;
КонецЕсли;
// получить ссылку на сотрудника
запросПоискСотрудника = Новый Запрос;
запросПоискСотрудника.Текст = "
|ВЫБРАТЬ
|Сотрудники.Ссылка КАК Сотрудник,
|Сотрудники.ФизическоеЛицо КАК ФизическоеЛицо,
|КадроваяИстория.Подразделение КАК Подразделение
|ИЗ
| Справочник.Сотрудники КАК Сотрудники
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ
| РегистрСведений.КадроваяИсторияСотрудников.СрезПоследних(&Дата) КАК КадроваяИстория
| ПО
| КадроваяИстория.Сотрудник = Сотрудники.Ссылка
|ГДЕ
| НЕ Сотрудники.ПометкаУдаления И
| НЕ Сотрудники.Код Есть NULL И
| НЕ Сотрудники.Код = """" И
| Сотрудник.Наименование = &ФИО И
| КадроваяИстория.Подразделение.Наименование = &Подразделение
|УПОРЯДОЧИТЬ ПО Сотрудник
|";
запросПоискСотрудника.УстановитьПараметр("Дата",ТекущаяДата());
запросПоискСотрудника.УстановитьПараметр("ФИО",ФИО);
запросПоискСотрудника.УстановитьПараметр("Подразделение",Подразделение);
РезультатЗапроса = запросПоискСотрудника.Выполнить();
// если сотрудник найден в базе ЗУП
Если НЕ РезультатЗапроса.Пустой() Тогда
ВыборкаПоискСотрудника = РезультатЗапроса.Выбрать();
Пока ВыборкаПоискСотрудника.Следующий() Цикл
СсылкаНаСотрудника = ВыборкаПоискСотрудника.Сотрудник;
ФизическоеЛицо = ВыборкаПоискСотрудника.ФизическоеЛицо;
КонецЦикла;
// перебрать все итоги по зарплате у сотрудника
Для Каждого Элемент Из Соответствие1 Цикл
Если Элемент.Ключ <> "Подразделение" Тогда
ПериодДохода = Дата(Элемент.Ключ);
СуммаДохода = Число(Элемент.Значение);
// Если дата документа ЗП_СЗО и дата дохода сотрудника совпадают, то записать в таблицу значений
Если ПериодДохода = ПериодРегистрации Тогда
НоваяСтрока = Таблица.Добавить();
НоваяСтрока.Регистратор = СсылкаДокументЗПСЗО;
НоваяСтрока.Активность = Истина;
НоваяСтрока.ОблагаетсяЕНВД = Ложь;
НоваяСтрока.Индексируется = Ложь;
НоваяСтрока.Период = ПериодДохода;
НоваяСтрока.Сумма = СуммаДохода;
НоваяСтрока.ФизическоеЛицо = ФизическоеЛицо;
НоваяСтрока.Сотрудник = СсылкаНаСотрудника;
НоваяСтрока.ПорядокРасчета = Перечисления.ПорядокРасчетаСреднегоЗаработкаОбщий.Постановление2010;
НоваяСтрока.СоставнаяЧасть = Перечисления.УчетНачисленийВСреднемЗаработкеОбщий.ОбщийЗаработок;
НоваяСтрока.Организация = ВыбраннаяОрганизация;
НоваяСтрока.Сторно = Ложь;
// необязательные данные
НоваяСтрока.Год = Год(ПериодРегистрации);
НоваяСтрока.ДатаНачалаБазовогоПериода = ПериодРегистрации;
НоваяСтрока.КоличествоМесяцев = 1;
//Сообщить("Документ:" + Строка(СсылкаДокументСПСЗО) + ", Сотрудник:" + Строка(СсылкаНаСотрудника) + ", Период дохода:" +Строка(ПериодДохода) + ", Сумма дохода:" +Строка(СуммаДохода));
КонецЕсли;
КонецЕсли;
КонецЦикла;
Иначе
Если МассивОшибок.Найти("Сотрудник " + ФИО + " есть в файле выгрузки, но не найден в базе ЗУП") = Неопределено Тогда
//Сообщить("Сотрудник " + ФИО + " есть в файле выгрузки, но не найден в базе ЗУП");
МассивОшибок.Добавить("Сотрудник " + ФИО + " есть в файле выгрузки, но не найден в базе ЗУП");
КонецЕсли;
//Прервать;
КонецЕсли;
КонецЦикла;
// если в таблице есть данные, записать в регистр
Если Таблица.Количество() >0 Тогда
НаборЗаписей = РегистрыНакопления.ДанныеОНачисленияхДляРасчетаСреднегоЗаработкаОбщий.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Сбросить();
НаборЗаписей.Отбор.Регистратор.Установить(СсылкаДокументЗПСЗО);
НаборЗаписей.Загрузить(Таблица);
НаборЗаписей.Записать();
Иначе
Сообщить("Есть документ ЗП_СЗО с периодом " + Строка(ПериодРегистрации) + ", но данных нет");
КонецЕсли;
КонецЦикла;
Для Каждого Ошибка Из МассивОшибок Цикл
Сообщить(Ошибка);
КонецЦикла;
Сообщить("Выполнено");
КонецПроцедуры
Проверено на следующих конфигурациях и релизах:
- Зарплата и управление персоналом, редакция 3.1, релизы 3.1.28.11