Как правильно реализовать логику смешанной оплаты в чеке 1С?

Программист 1С v8.3 (Управляемые формы) Управленческий учет Торговля и дистрибуция
← На главную

При разработке собственных кассовых решений (так называемых «нетленок») часто возникает задача распределения суммы чека по нескольким видам оплаты: наличными, картой и эквайрингом. Проблема заключается в том, что пользователь может менять суммы в произвольном порядке, и система должна автоматически пересчитывать остальные поля, чтобы в сумме они всегда были равны итоговой сумме продажи. Давайте разберем, как реализовать такую логику корректно и без «мини-квестов» для кассира.

Основные принципы проектирования логики оплат

Для того чтобы система работала предсказуемо, необходимо придерживаться следующих правил:

  1. Определите приоритеты. Если вы позволите изменять любое из трех полей, система будет пытаться угадать намерение пользователя. Лучше всего закрепить порядок или использовать «активное поле».
  2. Автоматический баланс. При изменении одного поля остальные должны автоматически пересчитываться так, чтобы разница между итогом и введенными суммами всегда стремилась к нулю.
  3. Валидация данных. Всегда проверяйте, не превышает ли введенная сумма итоговую сумму чека, чтобы избежать ошибок при передаче данных в фискальный накопитель.

Реализация алгоритма пересчета

Рассмотрим рабочее решение, которое позволяет управлять распределением сумм через процедуру обработки изменений в полях формы. Суть метода заключается в передаче «стартового поля» (того, которое отредактировал пользователь) и принудительном пересчете остальных переменных.

Для реализации этой логики создадим процедуру, которая будет вызываться при событии ПриИзменении для каждого поля оплаты.


Процедура КонтрольСумм(СтартовоеПоле)
    
    СуммаПродажиСоСкидкой = СуммаПродажиСоСкидкой();
    
    // Пересчет для случая, если пользователь меняет наличные
    Если СтартовоеПоле = "СуммаНал" Тогда
        Если СуммаНал > СуммаПродажиСоСкидкой Тогда
            ЭтаФорма.СуммаНал = СуммаПродажиСоСкидкой;
        КонецЕсли;
        СуммаНаКарту = СуммаПродажиСоСкидкой - СуммаНал; 
        СуммаЭквайринг = 0;
    КонецЕсли;
    
    // Пересчет для случая, если пользователь меняет оплату картой
    Если СтартовоеПоле = "СуммаНаКарту" Тогда
        Если СуммаНаКарту > СуммаПродажиСоСкидкой Тогда
            СуммаНаКарту = СуммаПродажиСоСкидкой;
        КонецЕсли;
        Если СуммаНал + СуммаНаКарту > СуммаПродажиСоСкидкой Тогда
            СуммаНаКарту = СуммаПродажиСоСкидкой - СуммаНал;
        КонецЕсли;
        СуммаЭквайринг = СуммаПродажиСоСкидкой - СуммаНал - СуммаНаКарту; 
    КонецЕсли;
    
    // Пересчет для случая, если пользователь меняет эквайринг
    Если СтартовоеПоле = "СуммаЭквайринг" Тогда
        Если СуммаЭквайринг > СуммаПродажиСоСкидкой Тогда
            СуммаЭквайринг = СуммаПродажиСоСкидкой;
        КонецЕсли;
        Если СуммаНал + СуммаЭквайринг > СуммаПродажиСоСкидкой Тогда
            СуммаЭквайринг = СуммаПродажиСоСкидкой - СуммаНал;
        КонецЕсли;
        СуммаНаКарту = СуммаПродажиСоСкидкой - СуммаНал - СуммаЭквайринг; 
    КонецЕсли;
    
КонецПроцедуры

Почему это решение эффективно

Данный подход является «жестким», но понятным для пользователя. Разберем ключевые особенности этого кода:

Рекомендации по улучшению интерфейса

Для создания более профессионального интерфейса в 1С рекомендуем добавить следующие элементы:

  1. Кнопка сброса: Добавьте кнопку «Очистить всё», которая обнуляет все поля ввода. Это поможет пользователю, если он запутался в последовательности ввода.
  2. Индикация остатка: Выводите на форму поле ОстатокКОплате. Это наглядно покажет кассиру, сколько еще денег нужно внести, чтобы закрыть чек.
  3. Блокировка пробития: В процедуре, отвечающей за фискализацию, обязательно проверяйте равенство СуммаНал + СуммаНаКарту + СуммаЭквайринг == ИтоговаяСумма. Если суммы не равны, выдавайте информативное сообщение пользователю.

Используя данный метод, вы сможете гибко настроить процесс приема оплаты в любой конфигурации. Помните, что главное — это предсказуемость поведения системы для конечного пользователя. Взаимосвязь колонок должна быть такой, чтобы кассиру не приходилось совершать лишних действий для корректировки баланса.

← На главную