Ситуация, когда система 1С:УПП 1.3 (Управление производственным предприятием) перестает контролировать число дней задолженности для одного или нескольких контрагентов, является классической проблемой для администраторов и программистов. При этом настройки договора могут быть идентичны тем, по которым контроль работает корректно, а отчеты по дебиторской задолженности подтверждают наличие просрочки. Разберем детально, как устроен этот механизм «под капотом», и выясним, почему он может давать сбои.
Прежде чем приступать к анализу программного кода, нам необходимо исключить влияние человеческого фактора и стандартных настроек прав. Рассмотрим основные моменты, которые могут влиять на поведение системы:
Разрешить проведение документа без контроля взаиморасчетов. Если у пользователя, проводящего документ, стоит эта галочка, система может игнорировать любые ограничения по задолженности.ПолныеПрава часто позволяет обходить проверки, зашитые в модули проведения, если они не вынесены в жесткие подписки на события.Отключить контроль взаиморасчетов при проведении документа. Как показывает практика, если один раз документ был проведен с этой галкой, последующие перепроведения могут вести себя нетипично.Основная логика проверки задолженности в УПП 1.3 сосредоточена в общих модулях. Для диагностики нам потребуется отладчик. Выясним, какая функция отвечает за расчет просрочки. Как правило, это функция СуммаПросроченнойЗадолженности(Договор, ДатаДокумента) в общем модуле ПродажиСервер или аналогичные механизмы в модуле УправлениеДенежнымиСредствами.
Рассмотрим фрагмент кода, который выполняет запрос к регистру накопления ВзаиморасчетыСКонтрагентамиПоДокументамРасчетов. Система ищет самую старую дату сделки, по которой есть остаток долга:
Запрос.Текст = "ВЫБРАТЬ
| ВзаиморасчетыПоДокументамОстатки.ДоговорКонтрагента,
| МИНИМУМ(ВзаиморасчетыПоДокументамОстатки.ДокументРасчетовСКонтрагентом.Дата) КАК ДатаПервойСделки
|ИЗ
| РегистрНакопления.ВзаиморасчетыСКонтрагентамиПоДокументамРасчетов.Остатки(&Период,
| ДоговорКонтрагента = &Договор
| И УпрУчет = ИСТИНА) КАК ВзаиморасчетыПоДокументамОстатки
|ГДЕ
| ВзаиморасчетыПоДокументамОстатки.СуммаВзаиморасчетовОстаток > 0
|
|СГРУППИРОВАТЬ ПО
| ВзаиморасчетыПоДокументамОстатки.ДоговорКонтрагента";
Проанализируем этот запрос. Система берет только те записи, где СуммаВзаиморасчетовОстаток > 0. Это критически важный момент. Если по контрагенту в регистре «зависли» микро-остатки с разными знаками (например, из-за курсовых разниц или ручных корректировок), сумма может не попасть в выборку.
Разберем ситуации, когда отчет показывает долг, а программный запрос — нет. Это происходит из-за специфики работы регистров в УПП.
ВзаиморасчетыСКонтрагентамиПоДокументамРасчетов имеет измерения: Организация, Контрагент, Договор, Сделка, ДокументРасчетов. Если оплата была разнесена на договор в целом, а реализация — на конкретный «Заказ покупателя» (который выступает в роли сделки), в регистре возникнет «перекос». По одному документу будет висеть плюс, по другому — минус. В сумме по отчету долга может не быть, или он будет виден иначе, но программный запрос МИНИМУМ(Дата) может отработать некорректно, если не найдет положительный остаток по конкретной аналитике.И УпрУчет = ИСТИНА в запросе. Контроль в УПП часто завязан именно на валюту управленческого учета (обычно это рубли). Если договор ведется в валюте (например, USD), а в управленческом учете из-за округления копеек при пересчете курсов возник отрицательный остаток в 0.01 руб., условие СуммаВзаиморасчетовОстаток > 0 отсечет эту задолженность, и система «пропустит» отгрузку.Остатки() может возвращать пустой результат. Попробуем выполнить полный пересчет итогов в конфигураторе (меню «Администрирование» — «Тестирование и исправление» — «Пересчет итогов»).Если визуальный осмотр договора и прав не помог, выполним следующие действия:
Шаг 1: Использование консоли запросов. Возьмем запрос из модуля (приведенный выше) и выполним его в консоли запросов, подставив в качестве параметра &ПроблемныйДоговор ссылку на договор контрагента, который проводится без контроля. Если запрос не возвращает ДатаПервойСделки, значит, проблема в данных регистра.
Шаг 2: Проверка ведомостей. Сформируем отчет «Ведомость по взаиморасчетам с контрагентами» с детализацией до документа расчетов. Важно: в настройках отчета обязательно выберем показатели «Сумма (упр. учет)» и проверим наличие сумм с разными знаками по одной и той же сделке. Если мы видим, что по реализации висит долг 100 руб., а по какому-то другому документу (например, корректировке) висит аванс -100 руб., их нужно «схлопнуть» документом «Корректировка долга» с видом операции «Проведение взаимозачета».
Шаг 3: Проверка времени документов. Проанализируем время документов. Если реализация проводится той же датой и временем, что и платеж, или расчет РазницаДней в коде дает нулевое значение из-за специфики вычисления секунд в сутках, система может считать, что просрочки еще нет. Рассмотрим код вычисления разницы:
РазницаДатВСекундах = ДатаТекущегоДокумента - Выборка.ДатаПервойСделки;
РазницаДней = Цел(РазницаДатВСекундах / (24 * 60 * 60));
Если РазницаДней > ДопустимоеЧислоДнейЗадолженности Тогда
// Блокировка
КонецЕсли;
Здесь используется функция Цел(). Если разница составляет, к примеру, 15.9 дней, а лимит — 16 дней, РазницаДней будет равна 15, и документ проведется. Убедимся, что фактическое количество полных суток превышает лимит, указанный в договоре.
Выяснив причину, применим соответствующее решение:
ВзаиморасчетыСКонтрагентамиПоДокументамРасчетов.Таким образом, «невидимость» просрочки в 1С:УПП 1.3 чаще всего связана не с программной ошибкой как таковой, а с состоянием данных в регистрах, которые программный код интерпретирует буквально. Тщательный анализ регистра по документам расчетов в разрезе управленческого учета — кратчайший путь к решению данной задачи.