Контроль количества выбираемых слотов времени/дней для всех или различных услуг по отдельным правилам

Порядок оказания некоторых услуг может подразумевать минимальное количество часов бронирования, допустимый диапазон или строго заданное количество времени/дней.

Определенным образом прописав вводные данные (правила) в приведенном здесь коде, Вы можете добавить в Ваш виджет онлайн-записи специальную надстройку, ограничивающую возможность записаться на все или некоторые определенные услуги пока клиент не выберет заданное для них количество времени или дней.
Фрагмент, в который необходимо внести изменения, совсем компактный и не требует навыков программирования (при возникновении каких-либо затруднений Вы можете обратиться в нашу службу поддержки):

Наглядный пример настройки


Приведем пример конструкции с единственным правилом, содержащим все возможные переменные (при этом обязательная из них только одна - slotsMin):

var SLOTS_COUNT_RULES = [    
    { slotsMin: 2, serviceIDs: ["11111", "22222"], slotsSynName: "часов", slotsMax: 5 }
];

- правило соответствует двум услугам по прокату разных лодок от 2 до 5 часов

Назначение переменных


  • slotsMin - число, ограничение минимального количества слотов. Не дает клиенту продолжить бронирование, пока не будет выбрано минимальное количество слотов.

    Единственная обязательная переменная, правило может содержать только ее, и содержать ее должно любое правило.

    Отсутствие ограничения минимального количества выражается значением { slotsMin: 1 }.

  • serviceIDs - ID услуг, к которым применяется правило. Заключены в квадратные скобки, прописываются в кавычках через запятую, после последнего или единственного ID запятая не ставится. Если serviceIDs отсутствует, правило применяется ко всем услугам.
  • slotsSynName - Ваше название слотов времени в родительном падеже в кавычках: "часов", "дней", "интервалов" и т. д. Если slotsSynName отсутствует, по умолчанию клиенту универсально предлагается выбрать количество "слотов".
  • slotsMax - число, ограничение максимального количества слотов (при необходимости). Может быть равно минимальному ограничению - например, для услуг с фиксированным временным интервалом. В том числе возможно правило { slotsMin: 1, slotsMax: 1 }.

Оформление правил


В зависимости от поставленной задачи, правил можно прописать несколько или только одно.

Общий вид конструкции с правилами:

Код


Полностью скопируйте приведенный ниже код в раздел "Настройки -> Дополнительные CSS/JS -> JS", заменив содержимое конструкции var SLOTS_COUNT_RULES = [ ]; на Ваши правила:

<script>
var SLOTS_COUNT_RULES = [
    { slotsMin: 3, serviceIDs: ["11111", "22222", "33333"]}, // бронирование беседки минимум от 3 часов (3 беседки по разной цене, отдельные услуги)
    { slotsMin: 2, serviceIDs: ["44444"], slotsMax: 8 }, // катание на лодке от 1 до 4 часов при выборе получасовых интервалов (одна или несколько лодок по одной цене, одна услуга)
    { slotsMin: 3, serviceIDs: ["55555", "66666"], slotsSynName: "дней", slotsMax: 3 } // бронирование домика на 3 дня (2 домика по разной цене, отдельные услуги)
];

var INFO_TEXT = "Чтобы продолжить, выберите"; // подсказка необходимого количества слотов
var TEXT_COLOR_TIP = '#08a83d'; // цвет текста подсказки
var TEXT_COLOR_ALERT = '#ff3c00'; // цвет текста подсказки в процессе выбора
var BACKGROUND_COLOR = '#f5f5f5'; // цвет блока подсказки
var BORDER_COLOR = '#ececec'; // цвет границы блока подсказки

let countMsgAlert;
function slotsCountControl() {
    let selectedServiceId = $('#service-data a[data-href].selected').attr('data-id');
    if (!selectedServiceId) return;
    let matchedRule = false;
    matchedRule = SLOTS_COUNT_RULES.find(rule => { // поиск правила по selectedServiceId или с установленным slotsMin
        return rule.slotsMin && (!rule.serviceIDs || rule.serviceIDs.includes(selectedServiceId));
    });
    if (!matchedRule) return;
    if (matchedRule) {
        let tBtn = $('.time-checkbox:checked').length;
        let nextButton = $('.next-btn');
        let { slotsMin, slotsSynName, slotsMax } = matchedRule;
        if (!document.getElementById('countAlert')) {
            countMsgAlert = document.createElement('div');
            countMsgAlert.id = 'countAlert';
            countMsgAlert.setAttribute('style', `display: inline-block; font-size: 120%; padding: 6px 20px; margin-top: 10px; text-align: center; background: ${BACKGROUND_COLOR}; border: 1px solid ${BORDER_COLOR}; border-radius: 6px; position: relative; left: 50%; transform: translateX(-50%);`);
            if ($('#time-block').css('display') !== 'none') {
                $('#dates-area__block').append(countMsgAlert);
            } else if ($('#dates-area__calendar').css('display') !== 'none') {
                $('#dates-area__calendar').append(countMsgAlert);
            }
        } else {
            countMsgAlert = document.getElementById('countAlert');
        }
        nextButton.hide();
        if (slotsMin > 1) {
            countMsgAlert.innerHTML = INFO_TEXT + ' ' + (slotsSynName ? slotsSynName : 'слотов') + ': ' + (slotsMin - tBtn);
            countMsgAlert.style.setProperty("color", `${TEXT_COLOR_TIP}`);
            countMsgAlert.style.display = 'inline-block';
        } else {
            countMsgAlert.style.display = 'none';
        }
        if (slotsMin > 1 && tBtn < slotsMin && tBtn >= 1) {
            nextButton.removeClass('active').hide();
            countMsgAlert.innerHTML = INFO_TEXT + ' еще ' + (slotsSynName ? slotsSynName : 'слотов') + ': ' + (slotsMin - tBtn);
            countMsgAlert.style.setProperty("color", `${TEXT_COLOR_ALERT}`);
            countMsgAlert.style.display = 'inline-block';
        } else if (slotsMin > 1 && tBtn < 1) {
            nextButton.removeClass('active').hide();
            countMsgAlert.innerHTML = INFO_TEXT + ' ' + (slotsSynName ? slotsSynName : 'слотов') + ': ' + (slotsMin - tBtn);
            countMsgAlert.style.setProperty("color", `${TEXT_COLOR_TIP}`);
            countMsgAlert.style.display = 'inline-block';
        } else if (tBtn > slotsMax) {
            nextButton.removeClass('active').hide();
            countMsgAlert.innerHTML = INFO_TEXT + ' ' + (slotsSynName ? slotsSynName : 'слотов') + ' не более: ' + slotsMax;
            countMsgAlert.style.setProperty("color", `${TEXT_COLOR_ALERT}`);
            countMsgAlert.style.display = 'inline-block';
        } else if (tBtn >= slotsMin && (!slotsMax || tBtn <= slotsMax)) {
            nextButton.addClass('active').css({ display: 'inline-block' });
            countMsgAlert.style.display = 'none';
        }
    } else {
        return;
    }
}
$('body').on('change', '.time-checkbox', function () { setTimeout(slotsCountControl, 20); });
$(document).ajaxComplete(function () { countMsgAlert = null; setTimeout(slotsCountControl, 30); });
</script>

- комментарии напротив правил (желтым текстом) даны для ориентировки, их писать не обязательно

Примечание:

Совместно с применением данного скрипта рекомендуется скрыть отображение длительности и цены услуги для клиента, вместо этого обозначив их в названии и/или описании услуги.

Читайте также

Какие возможности и выгоды предоставляют приложения на телефон для записи клиентов
Какие возможности и выгоды предоставляют приложения на телефон для записи клиентов
Задумались о внедрении в работу своей компании мобильного приложения для записи клиентов? Нам кажется, что это очень актуальная мысль! В наше время конкуренция практически во всех сферах торговли и услуг зашкаливает, а подобные средства автоматизации позволяют получить весомое конкурентное преимущество...
Как CRM-система помогает автоматизировать работу агентств
Как CRM-система помогает автоматизировать работу агентств
Любое агентство — от кадрового до туристического — сталкивается с множеством задач, которые требуют максимальной точности, координации и скорости...