Определения новых комбо в API

Теги: v10 v10preview2

В IOperationService добавлен метод GetComboDefinitions, возвращающий описания новых (RMS-)комбо, настроенных в BackOffice. Полученные определения используются, чтобы собрать комбо в заказе: подобрать блюда по шагам, учесть размеры, цены и стоп-листы, а затем добавить комбо методом AddOrderCombo.

Описания публикуются в новом пространстве имён Resto.Front.Api.Data.Combo.

Сущности комбо

IComboDefinition

Определение комбо.

IComboStep

Шаг (группа) комбо.

IComboStepItem

Позиция продукта внутри шага.

IComboDefinitionCategory

Категория отображения определения комбо.

Цены и видимость

Для учёта комбо-прайслиста и стоп-листов при подборе блюд добавлены два метода.

GetComboItemPrice

Возвращает цену продукта в составе комбо для заданных шага и размера комбо. Аргументы: product, productSize (или null для базовой цены), comboGroupId — идентификатор шага (группы) комбо, comboSize (или null для базовой цены без размера), priceCategory (или null для категории по умолчанию), pricingTime — момент времени, на который рассчитывается цена.

Возвращает null, если в комбо-прайслисте нет записи для этой комбинации.

GetComboItemIncludedInMenu

Возвращает, включён ли продукт в комбо-меню для заданных шага и размера комбо. Сигнатура совпадает с GetComboItemPrice. Возвращает null, если в комбо-прайслисте нет записи для этой комбинации (ограничения нет); false означает, что блюдо недоступно (в том числе из-за стоп-листа) и должно быть исключено из подбора.

Пример: сборка комбо в заказе

private void AddComboInOrder(IOrder order, IOperationService os)
{
    // 1. Получаем активные определения комбо
    var comboDefinitions = os.GetComboDefinitions();
    if (comboDefinitions.Count == 0)
        return;

    var editSession = os.CreateEditSession();
    var guest = order.Guests.Last();
    var comboDefinition = comboDefinitions[0];

    // 2. Определяем размер комбо, если у комбо есть шкала
    IProductSize comboSize = null;
    if (comboDefinition.Scale != null)
    {
        var availableSizes = comboDefinition.Sizes
            ?? PluginContext.Operations.GetProductScaleSizes(comboDefinition.Scale);
        comboSize = availableSizes.FirstOrDefault();
    }

    // 3. Для каждого шага подбираем блюдо и добавляем его в заказ
    var comboItems = new Dictionary<ComboGroupIdAndName, IOrderCookingItemStub>();
    var expectedComboPrice = 0m;

    foreach (var comboStep in comboDefinition.Steps)
    {
        // Отбираем блюда, совместимые с выбранным размером комбо
        var compatibleItems = comboStep.Items.Where(item =>
        {
            if (comboSize == null || item.Sizes == null)
                return true;
            return item.Sizes.TryGetValue(comboSize, out var sizes) && sizes.Count > 0;
        }).ToList();

        // Исключаем недоступные по прайслисту / стоп-листу
        compatibleItems = compatibleItems.Where(item =>
        {
            IProductSize productSize = null;
            if (item.Product.Scale != null)
                productSize = PluginContext.Operations
                    .GetProductScaleSizes(item.Product.Scale)
                    .FirstOrDefault();

            var included = os.GetComboItemIncludedInMenu(
                item.Product, productSize, comboStep.Id, comboSize,
                order.PriceCategory, DateTime.Now);

            return included != false; // null — записи в прайслисте нет (ограничения нет)
        }).ToList();

        if (compatibleItems.Count == 0)
            return;

        var product = compatibleItems[0].Product;
        IProductSize productSize = null;
        if (product.Scale != null)
            productSize = product.Scale.DefaultSize;

        // Цена блюда именно в составе комбо
        var comboItemPrice = os.GetComboItemPrice(
            product, productSize, comboStep.Id, comboSize,
            order.PriceCategory, DateTime.Now);
        expectedComboPrice += comboItemPrice ?? 0m;

        // Добавляем блюдо в заказ
        var stub = editSession.AddOrderProductItem(1, product, order, guest, productSize);

        // Ключ словаря — идентификатор шага (группы) комбо
        comboItems.Add(new ComboGroupIdAndName(comboStep.Id, null), stub);
    }

    // 4. Добавляем само комбо
    editSession.AddOrderCombo(
        Guid.NewGuid(),           // id комбо в заказе
        null,                     // имя (можно null, это RMS-комбо, ядро само рассчитает имя) 
        1,                        // количество
        expectedComboPrice,       // цена. Если передать 0, и это RMS-комбо, ядро само рассчитает цену
        comboDefinition.Id,       // sourceActionId — id определения комбо
        Guid.Empty,               // programId — программа лояльности (Guid.Empty, если нет iikoCard)
        comboItems,               // блюда по шагам
        order,
        guest,
        comboSize);               // размер комбо (null, если без шкалы)

    os.SubmitChanges(editSession);
}

Цена комбо рассчитывается плагином как сумма GetComboItemPrice по шагам; за достоверность цены отвечает плагин.

См. также