В типовых конфигурациях 1С взаиморасчеты с контрагентами ведутся с детализацией до договоров, заказов или расчетных документов (накладных, актов). Однако на практике часто возникает потребность узнать, какие именно товарные позиции или услуги из документа отгрузки уже оплачены клиентом, а какие еще висят в дебиторской задолженности. Разберем ограничения типовой архитектуры, а также рассмотрим организационные и программные способы решения этой задачи.
Прежде чем приступать к доработке, проанализируем, почему разработчики типовых решений не включают номенклатуру в стандартные регистры расчетов:
62, 60, 76) уже занято максимально допустимое типовое количество субконто — Контрагенты, Договоры, ДокументыРасчетовСКонтрагентами. Добавление четвертого субконто Номенклатура потребует глубокой модификации плана счетов и тысяч типовых процедур проведения.РасчетыСКлиентами и ВзаиморасчетыСКлиентами работают на уровне объектов расчетов. Включение аналитики номенклатуры разрушит типовые алгоритмы автозачета авансов, переоценки валюты и закрытия месяца.Если на предприятии используются конфигурации 1С:УТ 11, 1С:КА или 1С:ERP, решим задачу без изменения конфигурации за счет правильной организации документооборота:
Заказ клиента на полный перечень позиций.Реализация товаров и услуг исключительно на оплачиваемый состав номенклатуры на основании заказа.Поступление безналичных ДС или Приходный кассовый ордер) привяжем к конкретной реализации.Таким образом, на один общий заказ формируется несколько реализаций, каждая из которых закрывается своей оплатой. Этот подход позволяет видеть долги по конкретным товарам штатными отчетами по взаиморасчетам без модификации кода.
Если бизнес-процесс требует оформления единого документа реализации на все позиции сразу с последующей частичной пономенклатурной оплатой, спроектируем собственный регистр накопления остатков.
Создадим регистр накопления РасчетыПоНоменклатуре (вид: Остатки) со следующей структурой:
Организация, Контрагент, ДокументОснование (тип ДокументСсылка.РеализацияТоваровУслуг, ДокументСсылка.АктВыполненныхРабот), Номенклатура (при необходимости — Характеристика).Сумма, Количество.При проведении документа реализации формируются движения вида Приход в разрезе каждой строки табличной части. При проведении платежных документов формируются движения вида Расход.
Для удобства пользователей расширим форму платежного документа: добавим дополнительную табличную часть РасшифровкаПоНоменклатуре, куда при выборе накладной подтягиваются текущие остатки непогашенных позиций из нашего регистра.
Рассмотрим алгоритмы, позволяющие распределить поступившую сумму оплаты по номенклатурным позициям документа отгрузки, если клиент не указал конкретный перечень оплачиваемых строк.
1. Метод ФИФО (последовательное погашение строк):
// СуммаПлатежа - общая сумма входящей оплаты
// ТаблицаОстатковПоНакладной - остатки долга по номенклатуре документа отгрузки
ОстатокКРаспределению = СуммаПлатежа;
Для Каждого СтрокаДолга Из ТаблицаОстатковПоНакладной Цикл
Если ОстатокКРаспределению <= 0 Тогда
Прервать;
КонецЕсли;
СуммаСписания = Мин(ОстатокКРаспределению, СтрокаДолга.Сумма);
// Формируем движение Расход по регистру
Движение = Движения.РасчетыПоНоменклатуре.ДобавитьРасход();
Движение.Период = Дата;
Движение.Организация = Организация;
Движение.Контрагент = Контрагент;
Движение.ДокументОснование = СтрокаДолга.ДокументОснование;
Движение.Номенклатура = СтрокаДолга.Номенклатура;
Движение.Сумма = СуммаСписания;
ОстатокКРаспределению = ОстатокКРаспределению - СуммаСписания;
КонецЦикла;
2. Пропорциональное распределение с контролем погрешности округления:
Если требуется закрыть все позиции документа пропорционально внесенной сумме, рассчитаем распределение по формуле с обязательным отнесением копеек на строку с максимальной суммой:
ВсегоОстатокДолга = ТаблицаОстатковПоНакладной.Итог("Сумма");
РаспределеноВсего = 0;
Для Индекс = 0 По ТаблицаОстатковПоНакладной.Количество() - 1 Цикл
СтрокаДолга = ТаблицаОстатковПоНакладной[Индекс];
Если Индекс = ТаблицаОстатковПоНакладной.Количество() - 1 Тогда
// Относим копеечную разницу на последнюю строку
СуммаПоСтроке = СуммаПлатежа - РаспределеноВсего;
Иначе
СуммаПоСтроке = Окр(СуммаПлатежа * (СтрокаДолга.Сумма / ВсегоОстатокДолга), 2);
РаспределеноВсего = РаспределеноВсего + СуммаПоСтроке;
КонецЕсли;
Движение = Движения.РасчетыПоНоменклатуре.ДобавитьРасход();
Движение.Период = Дата;
Движение.Организация = Организация;
Движение.Контрагент = Контрагент;
Движение.ДокументОснование = СтрокаДолга.ДокументОснование;
Движение.Номенклатура = СтрокаДолга.Номенклатура;
Движение.Сумма = СуммаПоСтроке;
КонецЦикла;
Подобная архитектура позволяет гибко учитывать частичную оплату в разрезе номенклатурных позиций, сохраняя полную стабильность и обновляемость типовых механизмов конфигурации.