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

https://1clancer.ru/task/77362

Конфигурация: 1С:ERP Управление предприятием 2 (2.5.25.56) Платформа: 8.3.27.1719

1. Цель задачи Разработать внешнюю обработку, которая: Удаляет документы, содержащие отрицательные начисления по видам: СУДЕР (Корректировка по результатам KPI (СУ)) СУТОП (Перерасход топлива) (коды видов начисления: СУДЕР, СУТОП) Компенсирует влияние этих сторно, уменьшая суммы других начислений (премий) по приоритетам (от 1 до 5), не трогая начисления с приоритетом 0. При корректировке окладных (ОКЛ, ОКЛЧС) и тарифных (ТРФЧС, ЧСКТУ, ЧОКТУ, УБКТУ и др.) начислений, пересчитывает и корректирует значения реквизитов Оклад или Тарифная ставка (часовая), чтобы сохранялась логика расчёта (Сумма = Оклад / НормаДней * ОтработаноДней или Сумма = Тариф * ОтработаноЧасов). Автоматически открывает и закрывает закрытые месяцы в расчёте зарплаты при необходимости обработки. Обеспечивает сохранение итоговой суммы начисления по сотруднику за месяц (чтобы не изменилась налогооблагаемая база). Обеспечивает безопасность при обновлении конфигурации (рекомендуется создание через расширение, но допускается и создание как внешней обработки в основной конфигурации).

2. Функциональные требования 2.1. Интерфейс обработки Форма с двумя полями ввода: ПериодНачала (тип: Дата, отображение: Месяц, заголовок: "С какого месяца") ПериодОкончания (тип: Дата, отображение: Месяц, заголовок: "По какой месяц") Кнопка с заголовком "Выполнить" и командой, вызывающей основную процедуру обработки. 2.2. Основная логика обработки Проверка периода: Убедиться, что ПериодНачала <= ПериодОкончания. Если нет — выдать сообщение и завершить. Определение закрытых периодов: Собрать все месяцы в диапазоне от НачалоМесяца(ПериодНачала) до КонецМесяца(ПериодОкончания). Проверить статус каждого месяца через РегистрыСведений.СтатусыПериодовРасчетаЗарплаты.ПолучитьСтатусМесяца(Месяц). Если статус Закрыт: Запомнить месяц в список ЗакрытыеМесяцы. Вызвать Обработки.УправлениеЗарплатойИКадрами.ОткрытьПериодРасчетаЗарплаты(Месяц). Вывести сообщение: "Месяц [Месяц] — закрытие отменено." Поиск и обработка отрицательных начислений: Выполнить запрос к базе данных: Источники: Документ.ПеречисленияОплат.Начисления, Документ.РазовыеНачисления.Начисления. Условия: Сумма < 0 ВидНачисления.Код в списке ["СУДЕР", "СУТОП"] ПериодРасчета в диапазоне от НачалоМесяца(ПериодНачала) до КонецМесяца(ПериодОкончания). Для каждой найденной строки: Запомнить Сумма (с положительным знаком), Сотрудник, ПериодРасчета, Документ. Компенсация: Для каждого найденного сотрудника и периода: Найти все положительные начисления (Сумма > 0) за этот период по этому сотруднику из: Документ.НачислениеЗарплатыВзносов.Начисления Документ.РазовыеНачисления.Начисления Фильтровать по видам начислений, которые имеют приоритет (не входят в список с приоритетом 0). Добавить поле Приоритет к каждой строке начисления на основе справочника приоритетов (см. п. 3). Отсортировать положительные начисления по возрастанию Приоритет. Цикл по отсортированным начислениям: Пока остаток отрицательной суммы (СуммаСторно) > 0 и есть начисления для корректировки: Выбрать текущее начисление ТекСумма. Рассчитать НоваяСумма = Макс(0, ТекСумма - ОстатокСторно). Рассчитать Разница = ТекСумма - НоваяСумма. Обновить тариф/оклад (если вид начисления из списка ОКЛ, ОКЛЧС, ТРФЧС, ТРЧСП, УБКТУ, ЧСКТУ, ЧОКТУ и др., см. список в п. 3): Если НоваяСумма = 0: установить Оклад = 0 или ТарифнаяСтавка_Часовая = 0. Иначе: Для ОКЛ: Оклад = НоваяСумма / ОтработаноДней * НормаДней (при ОтработаноДней > 0). Для ОКЛЧС: Оклад = НоваяСумма / ОтработаноЧасов (при ОтработаноЧасов > 0). Для остальных тарифных: ТарифнаяСтавка_Часовая = НоваяСумма / ОтработаноЧасов (при ОтработаноЧасов > 0). Установить Сумма = НоваяСумма в строке документа. Вызвать Документ.Записать() (без указания РежимПроведения, так как это внешняя обработка). Уменьшить ОстатокСторно на Разница. Если после цикла ОстатокСторно > 0: Вывести предупреждение: "Не удалось по