При работе с программной загрузкой данных в 1С Зарплата и Управление Персоналом (ЗУП) через внешние сервисы, например, веб-сервисы, мы часто сталкиваемся с необходимостью корректного заполнения полей документов. Одной из распространённых проблем является программная установка ПланируемаяДатаВыплаты в документе Простой, отстранение от работы, когда система переопределяет установленное значение на некорректное.
Рассмотрим ситуацию, когда при загрузке документа Простой из веб-сервиса, поле ПланируемаяДатаВыплаты устанавливается в текущий месяц, хотя должно соответствовать месяцу начала простоя. Это вызывает вопросы о том, как правильно управлять логикой заполнения документов в ЗУП при программном взаимодействии.
Автор столкнулся с тем, что, несмотря на попытки программно установить ПланируемаяДатаВыплаты с помощью функции РасчетЗарплатыРасширенныйКлиентСервер.ПланируемаяДатаВыплатыЗарплаты, дата в документе всё равно устанавливается в текущий месяц (или некорректно относительно ДатаНачала простоя).
Вот фрагмент кода, который использовал автор:
ПоискДокументаПростоя.ПорядокВыплаты = Перечисления.ХарактерВыплатыЗарплаты.Зарплата;
мДата = Месяц(ОбщаяИнформация.Получить("ДатаНачала"));
ПоискДокументаПростоя.ПланируемаяДатаВыплаты = РасчетЗарплатыРасширенныйКлиентСервер.ПланируемаяДатаВыплатыЗарплаты(Организация, мДата);
Здесь ДатаНачала простоя — 29.07.2023. Ожидалось, что ПланируемаяДатаВыплаты будет соответствовать июлю или августу 2023 года, в зависимости от настроек выплаты зарплаты в организации, но фактически устанавливается дата, относящаяся к текущему месяцу (например, если загрузка происходит в сентябре, дата могла установиться на сентябрь).
Внутренняя логика документа "Простой": В 1С, особенно в комплексных конфигурациях вроде ЗУП, многие документы имеют сложную логику заполнения и пересчёта полей, которая срабатывает не только при интерактивной работе пользователя на форме, но и при программном изменении данных. Эта логика может быть реализована в обработчиках событий объекта (например, ПриЗаписи, ОбработкаЗаполнения, ПриИзменении полей) или в общих модулях, которые вызываются из этих обработчиков.
Как верно заметил участник форума в сообщении (7), «ИМХО, мешает процедура заполнения в док-те». Это очень распространённая ситуация, когда стандартные процедуры, предназначенные для автоматического заполнения полей или расчёта зависимых значений, переопределяют программно установленные данные.
Особенности работы функций формы и сервера: Некоторые функции заполнения могут быть реализованы исключительно на клиентской стороне или с использованием серверных вызовов, которые требуют определённого контекста (например, открытой формы документа). При программном создании документа напрямую через объект (без использования формы) эти процедуры могут не вызываться вовсе или вызываться не в той последовательности.
Зависимость от других полей: ПланируемаяДатаВыплаты часто зависит от других полей документа, таких как Организация, ДатаДокумента, ДатаНачала / ДатаОкончания простоя, а также от настроек графиков выплат в Организации и Настройках расчета зарплаты. Если эти поля устанавливаются в некорректной последовательности или одно из них вызывает перерасчёт, это может привести к нежелательному результату.
Мы видим, что ПоискДокументаПростоя.ДатаНачала и ПоискДокументаПростоя.ДатаОкончания устанавливаются из ОбщаяИнформация.Получить("ДатаНачала") и ОбщаяИнформация.Получить("ДатаОкончания"), что является правильным подходом.
Автоматический перенос даты выплаты: Как указано в дополнительной информации, начиная с версии 3.1.29.78, 1С ЗУП автоматически переносит планируемую дату выплаты с выходного на рабочий день. Хотя это и полезная функция, она может добавить сложностей при попытке жёстко установить конкретную дату, если она попадает на выходной день.
Для эффективного решения подобных задач мы должны мыслить как система, пытаясь воспроизвести последовательность действий, которую выполняет сама 1С при интерактивном заполнении документа, или найти способ "отключить" автоматическое переопределение.
Рассмотрим несколько подходов, которые могут помочь в этой ситуации:
Прежде всего, нам необходимо убедиться, что входные данные для функции РасчетЗарплатыРасширенныйКлиентСервер.ПланируемаяДатаВыплатыЗарплаты являются корректными. Для этого используем отладчик.
Проверка входных параметров: Убедимся, что мДата содержит ожидаемый месяц. Если ДатаНачала простоя 29.07.2023, то мДата должно быть 7 (Июль). Проблема, упомянутая автором, "В расширении не работает :( " (сообщение 2), затрудняет этот процесс, но нам критически важно обеспечить условия для отладки. Возможно, потребуется временная доработка, чтобы выводить значения в журнал регистрации или возвращать их в веб-сервис для анализа.
Пример отладочного вывода (если доступен):
Сообщить("ДатаНачала: " + ОбщаяИнформация.Получить("ДатаНачала"));
мДата = Месяц(ОбщаяИнформация.Получить("ДатаНачала"));
Сообщить("Месяц для расчета: " + мДата);
ПланируемаяДата = РасчетЗарплатыРасширенныйКлиентСервер.ПланируемаяДатаВыплатыЗарплаты(Организация, мДата);
Сообщить("Рассчитанная планируемая дата: " + ПланируемаяДата);
ПоискДокументаПростоя.ПланируемаяДатаВыплаты = ПланируемаяДата;
Последовательность установки полей: Иногда порядок установки полей имеет значение. Убедитесь, что все необходимые для расчета даты поля (такие как Организация, ДатаНачала, ДатаОкончания, ВидПростоя и т.д.) установлены ДО попытки установить ПланируемаяДатаВыплаты. Внутренняя логика документа может срабатывать на изменение одного из этих полей и пересчитывать дату выплаты.
Если прямое присвоение и вызов стандартной функции не дают результата, вероятнее всего, нашими установленными значениями управляет какая-то внутренняя процедура документа. Нам нужно её найти и либо вызвать в нужный момент, либо, если это возможно и безопасно, временно отключить или обойти.
Изучение кода типовой конфигурации: Это самый надёжный способ. Откройте конфигуратор, найдите документ Простой, отстранение от работы и изучите его модули:
ОбработкаЗаполнения, ПриЗаписи, ПередЗаписью, ПриУстановкеНовогоЗначения для поля ПланируемаяДатаВыплаты или других полей, которые могли бы на неё влиять.Цель — найти функцию или процедуру, которая отвечает за установку ПланируемаяДатаВыплаты при интерактивном вводе данных. Возможно, эту функцию можно вызвать программно после того, как все остальные поля документа будут заполнены.
Принудительный вызов процедур заполнения: В некоторых случаях после установки основных полей, мы можем попытаться вызвать процедуру, которая имитирует заполнение. Например, если в типовой конфигурации есть метод Заполнить или Рассчитать на объекте документа, попробуйте его вызвать.
// Предполагаем, что ПоискДокументаПростоя - это ссылка на объект документа
ПоискДокументаПростоя.ДатаНачала = ОбщаяИнформация.Получить("ДатаНачала");
ПоискДокументаПростоя.ДатаОкончания = ОбщаяИнформация.Получить("ДатаОкончания");
// ... другие поля
// Попробуем вызвать стандартное заполнение, если такое есть
// Это может быть ОбновитьДанные(), Пересчитать(), Заполнить() и т.п.
// Нужно искать в модуле объекта документа "Простой"
// Например: ПоискДокументаПростоя.ОбновитьДанныеРасчета();
// или
// ПоискДокументаПростоя.ЗаполнитьНачисления();
// После этого, возможно, дата выплаты уже будет корректной,
// или её можно будет установить повторно.
мДата = Месяц(ОбщаяИнформация.Получить("ДатаНачала"));
ПоискДокументаПростоя.ПланируемаяДатаВыплаты = РасчетЗарплатыРасширенныйКлиентСервер.ПланируемаяДатаВыплатыЗарплаты(Организация, мДата);
Важный момент: Если такую процедуру вызвать не удаётся или она не помогает, возможно, придется найти конкретную функцию в общем модуле, которая рассчитывает эту дату, и вызвать её с нужными параметрами.
Автор пробовал такой подход (сообщения 8 и 9), и он не сработал. Однако, иногда дело в нюансах.
Запись без проведения: Попробуйте сначала записать документ без проведения (ПоискДокументаПростоя.Записать(РежимЗаписиДокумента.Запись)). Это может вызвать срабатывание обработчиков ПередЗаписью и ПриЗаписи.
Повторное чтение объекта: После записи, если документ не проводился, его можно перечитать (ПоискДокументаПростоя.Прочитать()), затем попытаться установить дату, а затем снова записать. Это может быть полезно, если какие-то фоновые процессы или зависимости обновляются только после первой записи.
Применение стандартного механизма заполнения (если есть): Иногда для документов есть метод ЗаполнитьНастройки или аналогичный, который можно вызвать после первичного заполнения полей, и он вызовет всю необходимую логику расчета.
Автор отмечает в сообщении (10), что в документе "Разовое начисление" изменение месяца приводит к изменению даты выплаты, а в "Простое" — нет. Это ключевой момент, который подтверждает наличие специфической логики в "Простое".
Различия в механизмах расчета: Документ "Простой" может иметь более сложный механизм определения даты выплаты, который не так прямолинейно связан с "месяцем начисления" как в "Разовом начислении". Например, дата может зависеть от даты фактического окончания простоя, даты расчета зарплаты за месяц, в котором простой произошел, или от правил выплаты межрасчетных начислений.
Проверка настроек организации: Убедимся, что в Настройках расчета зарплаты организации корректно определены даты выплаты аванса и зарплаты, а также порядок выплаты межрасчетных начислений. Функция РасчетЗарплатыРасширенныйКлиентСервер.ПланируемаяДатаВыплатыЗарплаты опирается именно на эти настройки.
Поскольку проблема возникает при программной загрузке, нам необходимо отлаживать код на сервере. Если "В расширении не работает", это может означать, что отладчик не цепляется к коду в расширении или к коду, вызываемому из веб-сервиса.
Вам следует убедиться, что отладка на сервере настроена и работает корректно. Возможно, потребуется:
Временно внести изменения в основной конфигурации (если это тестовая база и есть такая возможность) для отладки.
Использовать ЗаписьЖурналаРегистрации или Сообщить (в серверном контексте это будет писать в журнал событий), чтобы отслеживать значения переменных и ход выполнения кода.
Мы должны установить точки останова в следующих местах:
Непосредственно перед вызовом РасчетЗарплатыРасширенныйКлиентСервер.ПланируемаяДатаВыплатыЗарплаты, чтобы проверить значения Организация и мДата.
После присвоения ПоискДокументаПростоя.ПланируемаяДатаВыплаты, чтобы убедиться, что значение установлено.
В обработчиках событий объекта документа Простой (ПриЗаписи, ОбработкаЗаполнения, ПриУстановкеНовогоЗначения для поля ПланируемаяДатаВыплаты), чтобы отследить, какая именно логика переопределяет наше значение.
При программном создании и изменении документов в ЗУП через веб-сервисы или другие интеграционные механизмы, всегда помните о следующих принципах:
Используйте методы объекта: По возможности, старайтесь использовать методы объекта документа, которые имитируют действия пользователя или запускают внутреннюю логику (например, Заполнить, Рассчитать, Пересчитать). Эти методы обычно учитывают все зависимости и настройки.
Устанавливайте поля в правильной последовательности: Заполняйте сначала те поля, от которых зависят другие, а затем зависимые поля. Например, сначала Организация, Сотрудник, Период, затем ДатаВыплаты и Сумма.
Тестируйте в отладчике: Отладчик — ваш лучший друг. Работайте в тестовой базе, чтобы безопасно экспериментировать и понимать, как ведёт себя типовая конфигурация.
Изучайте типовой код: Если возникают необъяснимые переопределения, единственный надёжный способ — погрузиться в типовой код и понять, где и почему происходит изменение значения.
Будьте осторожны с расширениями: Если проблема возникает в расширении, убедитесь, что расширение не конфликтует с основной логикой документа или не переопределяет критически важные обработчики событий.
В заключение, проблема с ПланируемаяДатаВыплаты в документе "Простой" в ЗУП при программной загрузке — это классический пример того, как внутренняя бизнес-логика 1С может работать неочевидным образом при попытке прямого программного вмешательства. Нам предстоит проанализировать стандартный код, понять его логику и либо имитировать её, либо найти точку, где мы можем безопасно и эффективно установить нужное значение.