При разработке собственных кассовых решений (так называемых «нетленок») часто возникает задача распределения суммы чека по нескольким видам оплаты: наличными, картой и эквайрингом. Проблема заключается в том, что пользователь может менять суммы в произвольном порядке, и система должна автоматически пересчитывать остальные поля, чтобы в сумме они всегда были равны итоговой сумме продажи. Давайте разберем, как реализовать такую логику корректно и без «мини-квестов» для кассира.
Для того чтобы система работала предсказуемо, необходимо придерживаться следующих правил:
Рассмотрим рабочее решение, которое позволяет управлять распределением сумм через процедуру обработки изменений в полях формы. Суть метода заключается в передаче «стартового поля» (того, которое отредактировал пользователь) и принудительном пересчете остальных переменных.
Для реализации этой логики создадим процедуру, которая будет вызываться при событии ПриИзменении для каждого поля оплаты.
Процедура КонтрольСумм(СтартовоеПоле)
СуммаПродажиСоСкидкой = СуммаПродажиСоСкидкой();
// Пересчет для случая, если пользователь меняет наличные
Если СтартовоеПоле = "СуммаНал" Тогда
Если СуммаНал > СуммаПродажиСоСкидкой Тогда
ЭтаФорма.СуммаНал = СуммаПродажиСоСкидкой;
КонецЕсли;
СуммаНаКарту = СуммаПродажиСоСкидкой - СуммаНал;
СуммаЭквайринг = 0;
КонецЕсли;
// Пересчет для случая, если пользователь меняет оплату картой
Если СтартовоеПоле = "СуммаНаКарту" Тогда
Если СуммаНаКарту > СуммаПродажиСоСкидкой Тогда
СуммаНаКарту = СуммаПродажиСоСкидкой;
КонецЕсли;
Если СуммаНал + СуммаНаКарту > СуммаПродажиСоСкидкой Тогда
СуммаНаКарту = СуммаПродажиСоСкидкой - СуммаНал;
КонецЕсли;
СуммаЭквайринг = СуммаПродажиСоСкидкой - СуммаНал - СуммаНаКарту;
КонецЕсли;
// Пересчет для случая, если пользователь меняет эквайринг
Если СтартовоеПоле = "СуммаЭквайринг" Тогда
Если СуммаЭквайринг > СуммаПродажиСоСкидкой Тогда
СуммаЭквайринг = СуммаПродажиСоСкидкой;
КонецЕсли;
Если СуммаНал + СуммаЭквайринг > СуммаПродажиСоСкидкой Тогда
СуммаЭквайринг = СуммаПродажиСоСкидкой - СуммаНал;
КонецЕсли;
СуммаНаКарту = СуммаПродажиСоСкидкой - СуммаНал - СуммаЭквайринг;
КонецЕсли;
КонецПроцедуры
Данный подход является «жестким», но понятным для пользователя. Разберем ключевые особенности этого кода:
СуммаПродажиСоСкидкой. Если кассир вводит сумму больше необходимой, система принудительно обрезает её до максимума.СтартовоеПоле), мы можем однозначно определить, какое поле должно быть «ведущим» в данной операции.Макс() или условий Если гарантирует, что мы не получим отрицательные значения в полях, даже если пользователь вводит некорректные данные.Для создания более профессионального интерфейса в 1С рекомендуем добавить следующие элементы:
ОстатокКОплате. Это наглядно покажет кассиру, сколько еще денег нужно внести, чтобы закрыть чек.СуммаНал + СуммаНаКарту + СуммаЭквайринг == ИтоговаяСумма. Если суммы не равны, выдавайте информативное сообщение пользователю.Используя данный метод, вы сможете гибко настроить процесс приема оплаты в любой конфигурации. Помните, что главное — это предсказуемость поведения системы для конечного пользователя. Взаимосвязь колонок должна быть такой, чтобы кассиру не приходилось совершать лишних действий для корректировки баланса.