При работе с системой 1С:Управление торговлей версии 11.5 (УТ 11.5) пользователи могут столкнуться с неожиданным поведением при формировании кассовых чеков. В частности, при печати чека из документа «Приходный кассовый ордер» (ПКО) вместо позиций текущей реализации в чек попадают товары из предыдущих отгрузок, по которым на момент оплаты существовала задолженность. Давайте рассмотрим подробнее, почему так происходит, и какие шаги можно предпринять для решения этой проблемы.
Первоначально выясним, почему система ведет себя таким образом. Это поведение не является ошибкой в чистом виде, а скорее следствием заложенной логики взаиморасчетов, которая могла измениться по сравнению с предыдущими версиями УТ.
ПлановыеОплатыКлиентов и ПлановыеОплатыПоСрокам будут показывать самую старую задолженность, если оплата не привязана к конкретному расчетному документу.Одним из наиболее эффективных и рекомендованных способов решения проблемы является изменение порядка взаиморасчетов в договоре с клиентом. Если оплата четко привязана к конкретному документу, система будет использовать данные именно этого документа при формировании чека.
При такой настройке система будет понимать, какая оплата за какой документ получена, и печатать чек с позициями из указанного расчетного документа, а не из старых задолженностей.
Если в вашей организации предполагается работа с предварительными договоренностями или резервированием товаров, активно используйте документ «Заказ клиента». Этот подход помогает жестко связать оплату с конкретной сделкой.
Заказ клиента.Приходного кассового ордера (ПКО), основанием для него должен быть именно Заказ клиента или соответствующая Реализация товаров и услуг, которая, в свою очередь, сформирована на основании заказа.Приходных кассовых ордеров при проведении реализаций, что позволит избежать накопления задолженности и смешивания товаров из предыдущих накладных.Привязка оплаты к конкретному Заказу клиента гарантирует, что при печати чека система будет использовать информацию именно из этого заказа, а не из общей задолженности контрагента, что помогает четко связать оплату с конкретной реализацией.
Как уже упоминалось, использование обезличенного контрагента, такого как «Частное лицо», является одной из основных причин проблемы. Наиболее корректным с точки зрения учета является ведение раздельного учета по каждому покупателю.
Контрагенты.Таким образом, система сможет корректно отслеживать задолженность и оплаты для каждого конкретного покупателя, и чеки будут формироваться правильно, без смешивания товаров из разных реализаций разных клиентов. Это наиболее дисциплинированный подход, который исключает саму возможность возникновения подобных логических коллизий.
В некоторых случаях, когда стандартные средства не дают желаемого результата или требуется специфическое поведение системы, можно прибегнуть к доработке конфигурации. Один из предложенных вариантов предполагает изменение логики формирования списка объектов расчетов, используемого при пробитии чека.
Мы рассмотрим пример изменения общего модуля ВзаиморасчетыСервер, а именно процедуры ЗаполнитьТаблицуОстатковРасчетов. Эта процедура отвечает за формирование таблицы остатков расчетов, из которой затем берутся данные для чека. Цель доработки – заставить систему выбирать конкретный документ расчетов, связанный с текущей оплатой, а не просто самую старую задолженность.
Важно: Любые доработки стандартных модулей требуют квалификации программиста 1С и тщательного тестирования, так как могут повлиять на другие участки учета. Всегда делайте резервные копии перед внесением изменений.
Вот пример кода, который был предложен одним из пользователей для изменения логики:
// В общем модуле ВзаиморасчетыСервер
// Вместо стандартной процедуры
&Вместо("ЗаполнитьТаблицуОстатковРасчетов")
Процедура УЛ_ЗаполнитьТаблицуОстатковРасчетов(Реквизиты, АдресПлатежейВХранилище, ТаблицаОстатковРасчетов, ДополнительныеОтборы = Неопределено) Экспорт
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("ВалютаДокумента", Реквизиты.Валюта);
Запрос.УстановитьПараметр("ПоВсемКонтрагентам", Не ЗначениеЗаполнено(Реквизиты.Контрагент));
Запрос.УстановитьПараметр("Контрагент", Реквизиты.Контрагент);
Запрос.УстановитьПараметр("ПоВсемПартнерам", Не ЗначениеЗаполнено(Реквизиты.Партнер));
Запрос.УстановитьПараметр("Партнер", Реквизиты.Партнер);
Запрос.УстановитьПараметр("ПартнерПрочиеОтношения", Реквизиты.ПартнерПрочиеОтношения);
Запрос.УстановитьПараметр("Период", ?(Реквизиты.Дата <> '00010101',Реквизиты.Дата, ТекущаяДатаСеанса));
УчитыватьФилиалы = ?(Реквизиты.Свойство("УчитыватьФилиалы"), Реквизиты.УчитыватьФилиалы, Истина);
Если УчитыватьФилиалы И ТипЗнч(Реквизиты.Организация) <> Тип("Массив") Тогда
ГоловнаяОрганизация = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Реквизиты.Организация,"ГоловнаяОрганизация");
Если ГоловнаяОрганизация = Реквизиты.Организация Тогда
ГоловнаяОрганизация = Неопределено;
ЭтоГоловнаяОрганизация = Истина;
Иначе
ЭтоГоловнаяОрганизация = Ложь;
КонецЕсли;
Иначе
ЭтоГоловнаяОрганизация = Ложь;
ГоловнаяОрганизация = Неопределено;
КонецЕсли;
Запрос.УстановитьПараметр("Организация", Реквизиты.Организация);
Запрос.УстановитьПараметр("ЭтоГоловнаяОрганизация", ЭтоГоловнаяОрганизация);
Запрос.УстановитьПараметр("ГоловнаяОрганизация", ГоловнаяОрганизация);
Запрос.УстановитьПараметр("ДебиторскаяЗадолженность", Реквизиты.ПодборДебиторскойЗадолженности);
Запрос.УстановитьПараметр("ТолькоБезусловнаяЗадолженность", Реквизиты.ПодборТолькоБезусловнойЗадолженности);
Если Реквизиты.Свойство("ХозяйственнаяОперация") Тогда
СтатьяДвиженияДенежныхСредств = Справочники.СтатьиДвиженияДенежныхСредств.СтатьяДвиженияДенежныхСредствПоХозяйственнойОперации( Реквизиты.ХозяйственнаяОперация);
Иначе
СтатьяДвиженияДенежныхСредств = Справочники.СтатьиДвиженияДенежныхСредств.ПустаяСсылка;
КонецЕсли;
Запрос.УстановитьПараметр("СтатьяДвиженияДенежныхСредств", СтатьяДвиженияДенежныхСредств);
УстановитьПривилегированныйРежим(Истина);
ТекстЗапроса = "
|ВЫБРАТЬ
| РасшифровкаПлатежа.ОбъектРасчетов КАК ОбъектРасчетов,
| РасшифровкаПлатежа.Партнер КАК Партнер,
| РасшифровкаПлатежа.ВалютаВзаиморасчетов КАК Валюта,
| РасшифровкаПлатежа.Сумма КАК Сумма
|
|ПОМЕСТИТЬ ТаблицаПлатежей
|ИЗ
| &РасшифровкаПлатежа КАК РасшифровкаПлатежа
|;
|///////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ РАЗРЕШЕННЫЕ РАЗЛИЧНЫЕ
| Филиалы.Ссылка КАК Ссылка
|ПОМЕСТИТЬ ЦентрализованныеДоговоры
|ИЗ
| Справочник.ДоговорыКонтрагентов.Филиалы КАК Филиалы
|ГДЕ
| Филиалы.Организация = &Организация
|;
|///////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ОбъектыРасчетов.Ссылка КАК ОбъектРасчетов,
| ОбъектыРасчетов.Объект КАК Объект,
| ОбъектыРасчетов.Организация.ВалютаРегламентированногоУчета КАК ВалютаРегламентированногоУчета
|ПОМЕСТИТЬ ОбъектыРасчетов
|ИЗ
| Справочник.ОбъектыРасчетов КАК ОбъектыРасчетов
|ГДЕ
| (ОбъектыРасчетов.Организация В (&Организация)
| ИЛИ НЕ &ЭтоГоловнаяОрганизация
| И ОбъектыРасчетов.Договор В (ВЫБРАТЬ Ссылка ИЗ ЦентрализованныеДоговоры)
| И (ОбъектыРасчетов.Организация = &ГоловнаяОрганизация
| ИЛИ ОбъектыРасчетов.Договор.РазрешаетсяПередачаОплатМеждуФилиалами)
| ИЛИ &ЭтоГоловнаяОрганизация
| И ОбъектыРасчетов.Организация.ГоловнаяОрганизация В (&Организация)
| И ОбъектыРасчетов.Организация.ДопускаютсяВзаиморасчетыЧерезГоловнуюОрганизацию)
| И (ОбъектыРасчетов.Партнер = &Партнер ИЛИ &ПоВсемПартнерам)
| И (ОбъектыРасчетов.Контрагент = &Контрагент ИЛИ &ПоВсемКонтрагентам)
| И (&ПартнерПрочиеОтношения И ОбъектыРасчетов.Партнер.ПрочиеОтношения
| ИЛИ НЕ &ПартнерПрочиеОтношения)
|
| И (ОбъектыРасчетов.Ссылка <> Значение(Справочник.ДоговорыКонтрагентов.ПустаяСсылка)
| И ОбъектыРасчетов.Договор.Статус <> Значение(Перечисление.СтатусыДоговоровКонтрагентов.Закрыт))
|
|ИНДЕКСИРОВАТЬ ПО
| ОбъектРасчетов
|;
|///////////////////////////////////////////////////////////////////////////////////
|
|ВЫБРАТЬ
| ОбъектыРасчетов.ОбъектРасчетов КАК ОбъектРасчетов,
| ВалютыИКурсыДокументов.КурсЧислительВалютыВзаиморасчетов КАК КурсЧислительВалютыВзаиморасчетов,
| ВалютыИКурсыДокументов.КурсЗнаменательВалютыВзаиморасчетов КАК КурсЗнаменательВалютыВзаиморасчетов,
| ВалютыИКурсыДокументов.КурсЧислительВалютыУправленческогоУчета КАК КурсЧислительВалютыУправленческогоУчета,
| ВалютыИКурсыДокументов.КурсЗнаменательВалютыУправленческогоУчета КАК КурсЗнаменательВалютыУправленческогоУчета,
| ВалютыИКурсыДокументов.КурсЧислительВалютыДокумента КАК КурсЧислительВалютыДокумента,
| ВалютыИКурсыДокументов.КурсЗнаменательВалютыДокумента КАК КурсЗнаменательВалютыДокумента,
| ВалютыИКурсыДокументов.ВалютаДокумента КАК ВалютаДокумента,
| ВалютыИКурсыДокументов.ВалютаВзаиморасчетов КАК ВалютаВзаиморасчетов,
| ОтносительныеКурсыВалютСрезПоследних.КурсЧислитель КАК КурсЧислительПеременный,
| ОтносительныеКурсыВалютСрезПоследних.КурсЗнаменатель КАК КурсЗнаменательПеременный
|ИЗ
| ОбъектыРасчетов КАК ОбъектыРасчетов
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.ВалютыИКурсыДокументов КАК ВалютыИКурсыДокументов
| ПО ОбъектыРасчетов.Объект = ВалютыИКурсыДокументов.Документ,
| РегистрСведений.ОтносительныеКурсыВалют.СрезПоследних(
| &Период,
| Валюта = &ВалютаДокумента
| И БазоваяВалюта В
| (ВЫБРАТЬ
| Т.ВалютаРегламентированногоУчета
| ИЗ
| ОбъектыРасчетов КАК Т)) КАК ОтносительныеКурсыВалютСрезПоследних
|
|;
|///////////////////////////////////////////////////////////////////////////////////
|
|ВЫБРАТЬ &ТекстЗапросаРасчеты
|
|УПОРЯДОЧИТЬ ПО
| Организация,
| Контрагент,
| Дата,
| Номер
|";
Если Реквизиты.ТипРасчетов = Перечисления.ТипыРасчетовСПартнерами.РасчетыСКлиентом Тогда
ТекстЗапроса = СтрЗаменить( ТекстЗапроса, "ВЫБРАТЬ &ТекстЗапросаРасчеты", ТекстЗапросаПоОстаткамРасчетовСКлиентами);
Иначе
ТекстЗапроса = СтрЗаменить( ТекстЗапроса, "ВЫБРАТЬ &ТекстЗапросаРасчеты", ТекстЗапросаПоОстаткамРасчетовСПоставщиками);
КонецЕсли;
Запрос.Текст = ТекстЗапроса;
Если ЗначениеЗаполнено(АдресПлатежейВХранилище) Тогда
РасшифровкаПлатежа = ПолучитьИзВременногоХранилища(АдресПлатежейВХранилище);
Если РасшифровкаПлатежа.Колонки.Найти("Партнер") = Неопределено Тогда
РасшифровкаПлатежа.Колонки.Добавить("Партнер", Новый ОписаниеТипов("СправочникСсылка.Партнеры"));
РасшифровкаПлатежа.ЗаполнитьЗначения(Реквизиты.Партнер, "Партнер");
КонецЕсли;
ИначеЕсли ТаблицаОстатковРасчетов = Неопределено Тогда
РасшифровкаПлатежа = Новый ТаблицаЗначений;
РасшифровкаПлатежа.Колонки.Добавить("ОбъектРасчетов", Новый ОписаниеТипов("СправочникСсылка.ОбъектыРасчетов"));
РасшифровкаПлатежа.Колонки.Добавить("Партнер", Новый ОписаниеТипов("СправочникСсылка.Партнеры"));
РасшифровкаПлатежа.Колонки.Добавить("ВалютаВзаиморасчетов", Новый ОписаниеТипов("СправочникСсылка.Валюты"));
РасшифровкаПлатежа.Колонки.Добавить("Сумма", Новый ОписаниеТипов("Число"));
Иначе
РасшифровкаПлатежа = ТаблицаОстатковРасчетов.Выгрузить(,).СкопироватьКолонки;
КонецЕсли;
РасшифровкаПлатежа.Свернуть("ОбъектРасчетов, Партнер, ВалютаВзаиморасчетов", "Сумма");
Если РасшифровкаПлатежа.Количество = 1 И Не ЗначениеЗаполнено(РасшифровкаПлатежа[0].ОбъектРасчетов) Тогда
РасшифровкаПлатежа.Очистить;
КонецЕсли;
Запрос.УстановитьПараметр("РасшифровкаПлатежа", РасшифровкаПлатежа);
Если ДополнительныеОтборы <> Неопределено Тогда
СхемаЗапросаОстатков = Новый СхемаЗапроса;
СхемаЗапросаОстатков.УстановитьТекстЗапроса(Запрос.Текст);
Оператор = СхемаЗапросаОстатков.ПакетЗапросов[2].Операторы[0];
сч = 0;
Для Каждого КлючИЗначение Из ДополнительныеОтборы Цикл
Отбор = "ЕСТЬNULL(ОбъектыРасчетов."+КлючИЗначение.Ключ+", Неопределено) = &Параметр"+Строка(сч);
Запрос.УстановитьПараметр("Параметр"+Строка(сч), КлючИЗначение.Значение);
Оператор.Отбор.Добавить(Отбор);
сч= сч + 1;
КонецЦикла;
Запрос.Текст = СхемаЗапросаОстатков.ПолучитьТекстЗапроса;
КонецЕсли;
РезультатЗапроса = Запрос.ВыполнитьПакет;
Если ТаблицаОстатковРасчетов = Неопределено Тогда
ТаблицаОстатковРасчетов = РезультатЗапроса[4].Выгрузить;
Иначе
ТаблицаОстатковРасчетов.Загрузить(РезультатЗапроса[4].Выгрузить);
КонецЕсли;
Если РасшифровкаПлатежа.Количество = 0 Тогда
СуммаКРаспределению = Реквизиты.СуммаДокумента;
Иначе
СуммаКРаспределению = 0;
КонецЕсли;
СоответствиеКурсовВалют = Новый Соответствие;
ВыборкаФиксКурса = РезультатЗапроса[3].Выбрать;
ВалютаУправленческогоУчета = ЗначениеНастроекПовтИсп.ВалютаУправленческогоУчета;
Пока ВыборкаФиксКурса.Следующий Цикл
Если Реквизиты.Валюта = ВыборкаФиксКурса.ВалютаВзаиморасчетов Тогда
КоэффициентПересчета = 1;
ИначеЕсли Реквизиты.Валюта = ВыборкаФиксКурса.ВалютаДокумента Тогда
КоэффициентПересчета = ВыборкаФиксКурса.КурсЧислительВалютыДокумента * ВыборкаФиксКурса.КурсЗнаменательВалютыВзаиморасчетов / (ВыборкаФиксКурса.КурсЗнаменательВалютыДокумента * ВыборкаФиксКурса.КурсЧислительВалютыВзаиморасчетов)
ИначеЕсли Реквизиты.Валюта = ВалютаУправленческогоУчета Тогда
КоэффициентПересчета = ВыборкаФиксКурса.КурсЧислительВалютыУправленческогоУчета * ВыборкаФиксКурса.КурсЗнаменательВалютыВзаиморасчетов / (ВыборкаФиксКурса.КурсЗнаменательВалютыУправленческогоУчета * ВыборкаФиксКурса.КурсЧислительВалютыВзаиморасчетов)
Иначе
КоэффициентПересчета = ВыборкаФиксКурса.КурсЧислительПеременный * ВыборкаФиксКурса.КурсЗнаменательВалютыВзаиморасчетов / (ВыборкаФиксКурса.КурсЗнаменательПеременный * ВыборкаФиксКурса.КурсЧислительВалютыВзаиморасчетов)
КонецЕсли;
Коэффициенты = Новый Структура("КоэффициентПересчетаВВалютуВзаиморасчетов", КоэффициентПересчета);
СоответствиеКурсовВалют.Вставить(ВыборкаФиксКурса.ОбъектРасчетов, Коэффициенты);
КонецЦикла;
Для Каждого СтрокаТаблицы Из ТаблицаОстатковРасчетов Цикл
Если Не СтрокаТаблицы.Выбран Тогда
Если СтрокаТаблицы.ДолгПартнера <> 0 И Реквизиты.ПодборДебиторскойЗадолженности Тогда
СтрокаТаблицы.Сумма = Мин(СтрокаТаблицы.ДолгПартнера, СтрокаТаблицы.КОплате);
ИначеЕсли СтрокаТаблицы.НашДолг <> 0 И НЕ Реквизиты.ПодборДебиторскойЗадолженности Тогда
СтрокаТаблицы.Сумма = Мин(СтрокаТаблицы.НашДолг,СтрокаТаблицы.КОплате);
ИначеЕсли СтрокаТаблицы.КОплате <> 0 Тогда
СтрокаТаблицы.Сумма = СтрокаТаблицы.КОплате;
КонецЕсли;
Если ЗначениеЗаполнено(Реквизиты.Валюта) И Реквизиты.Валюта <> СтрокаТаблицы.ВалютаВзаиморасчетов Тогда
Если СтрокаТаблицы.ВариантКурсаДоговора = Перечисления.ВариантыКурсаДоговора.УстановленныйВДоговоре Тогда
Коэффициенты = СоответствиеКурсовВалют.Получить(СтрокаТаблицы.Договор);
ИначеЕсли СтрокаТаблицы.ВариантКурсаДоговора = Перечисления.ВариантыКурсаДоговора.ФиксированныйНаДатуОтгрузки Тогда
Коэффициенты = СоответствиеКурсовВалют.Получить(СтрокаТаблицы.ОбъектРасчетов);
Иначе
Коэффициенты = СоответствиеКурсовВалют.Получить(СтрокаТаблицы.ВалютаВзаиморасчетов);
КонецЕсли;
Если Коэффициенты = Неопределено Тогда
Коэффициенты = РаботаСКурсамиВалютУТ.ПолучитьКоэффициентыПересчетаВалюты(
Реквизиты.Валюта,
СтрокаТаблицы.ВалютаВзаиморасчетов,
?(Реквизиты.Дата <> '00010101',Реквизиты.Дата, ТекущаяДатаСеанса),
СтрокаТаблицы.Организация,,,
СтрокаТаблицы.ОбъектРасчетов);
Если СтрокаТаблицы.ВариантКурсаДоговора = Перечисления.ВариантыКурсаДоговора.УстановленныйВДоговоре Тогда
СоответствиеКурсовВалют.Вставить(СтрокаТаблицы.Договор, Коэффициенты);
Иначе
СоответствиеКурсовВалют.Вставить(СтрокаТаблицы.ВалютаВзаиморасчетов, Коэффициенты);
КонецЕсли;
КонецЕсли;
СтрокаТаблицы.Сумма = ?(Коэффициенты.КоэффициентПересчетаВВалютуВзаиморасчетов <> 0, СтрокаТаблицы.Сумма / Коэффициенты.КоэффициентПересчетаВВалютуВзаиморасчетов, 0);
КонецЕсли;
КонецЕсли;
Если СуммаКРаспределению > 0 Тогда
СтрокаТаблицы.Выбран = Истина;
Если СтрокаТаблицы.Сумма > СуммаКРаспределению Тогда
СтрокаТаблицы.Сумма = СуммаКРаспределению;
КонецЕсли;
СуммаКРаспределению = СуммаКРаспределению - СтрокаТаблицы.Сумма;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Данный код представляет собой замещающую процедуру (&Вместо), которая переопределяет стандартную логику. Основная идея заключается в том, чтобы:
Реализацию товаров и услуг), который и формирует позиции чека.Обратите внимание, что один из пользователей сообщил, что этот код ему «Не помогло», что подчеркивает сложность и индивидуальность таких доработок. Возможно, требуется дополнительная отладка или адаптация под конкретную конфигурацию и бизнес-процессы.
Самым прямым и простым способом избежать проблемы, если вы не готовы к сложным настройкам или доработкам, является изменение процесса пробития чека. Вместо того чтобы печатать чек из Приходного кассового ордера, пробивайте его непосредственно из документа Реализация товаров и услуг. Этот подход гарантирует, что в чек попадут именно те товары, которые указаны в текущей реализации.
Проблема печати некорректных позиций в чеке из ПКО в УТ 11.5 является распространенной и имеет несколько путей решения. Мы рассмотрели следующие варианты:
Выбор конкретного решения зависит от ваших бизнес-процессов, квалификации персонала и готовности к изменениям в конфигурации. Наиболее универсальными и рекомендованными являются первые три подхода, как системные и поддерживаемые типовым функционалом.