Zero Block
Click "Block Editor" to enter the edit mode. Use layers, shapes and customize adaptability. Everything is in your hands.
Tilda Publishing
create your own block from scratch
Zero Block
Click "Block Editor" to enter the edit mode. Use layers, shapes and customize adaptability. Everything is in your hands.
Tilda Publishing
create your own block from scratch
Редагування шаблонів чеку при переході на v. 9.3.6
При переході з версії 8.Х.Х на 9.3.6 змінився ряд функцій у шаблонах чеків
Для того, щоб перехід відбувся без додаткових звернень клієнта - прошу під час оновлення виконати декілька простих змін у шаблонах чеків (про це детально нижче)
Попередній чек (він же "Гостьовий рахунок" або "Пречек")

1. Замінити скрізь "RepeateBillHeaderTitleFormat" на "RepeatBillHeaderTitleFormat"

Як було

@string.Format(Resources.RepeateBillHeaderTitleFormat, Model.RepeatBillNumber)

Як стало

@string.Format(Resources.RepeatBillHeaderTitleFormat, Model.RepeatBillNumber)

2. Додати скрізь текст після "OrderItemsToPrintFilter"

Як було

Items = guest.Items.Where(item => orderItemsFilter(item) && OrderItemsToPrintFilter(item, order.DiscountItems))

Items = order.Guests.SelectMany(g => g.Items.Where(item => orderItemsFilter(item) && OrderItemsToPrintFilter(item, order.DiscountItems)))

Як стало

Items = guest.Items.Where(item => orderItemsFilter(item) && OrderItemsToPrintFilter(item, order.DiscountItems) && OrderItemsPrechequePrintableFilter(item))

Items = order.Guests.SelectMany(g => g.Items.Where(item => orderItemsFilter(item) && OrderItemsToPrintFilter(item, order.DiscountItems) && OrderItemsPrechequePrintableFilter(item)))

3. Додати +1 метод в кінці документу

Як було

    }
**тут ніфіга немає
}

Як стало

    }
	
	private static bool OrderItemsPrechequePrintableFilter(IOrderItem orderItem)
	{
    if (orderItem.Cost != 0m)
        return true;
    return orderItem.Product.PrechequePrintable;
	}
}

4. Замінити скрізь "GetCost()" на "Cost"

Як було

var productItemSum = productItem.GetCost() - order.DiscountItems.Select(di => di.GetDiscountSumFor(productItem)).Sum();

var modifierEntrySum = modifierEntry.GetCost() - order.DiscountItems.Select(di => di.GetDiscountSumFor(modifierEntry)).Sum();

Як стало

var productItemSum = productItem.Cost - order.DiscountItems.Select(di => di.GetDiscountSumFor(productItem)).Sum();

var modifierEntrySum = modifierEntry.Cost - order.DiscountItems.Select(di => di.GetDiscountSumFor(modifierEntry)).Sum();
"Пряма мова автора", або оригінал статті (авторство: Валентин Сальников)
# Сводная инструкция по миграции шаблонов (8.5.8 → 9.3.6)

## Что было при сделано:
- Шаблон пречека - проверен 
- Шаблон накладной - работает без исправлений, + предоставлены инструкции для 9.1.7 связанные с ошибками компиляции из-за удаления IIikoNetPaymentItem
- Шаблон квитанции - работает без исправлений
- шаблон сервисного - работает без исправлений
- Шаблон товарного чека - работает без исправлений (кроме одного кастомного - Теж кажуть чек v.1.0)

## Что изменилось при переходе на 9.3.6
- Ключ ресурса повторного пречека переименован: `Resources.RepeateBillHeaderTitleFormat` → `Resources.RepeatBillHeaderTitleFormat`. Старый ключ больше не существует и ломает компиляцию. Изменения состоит в том что раньше было опечатка в слове "Repeat".
- В шаблонах предчека обязательно применять фильтр `OrderItemsPrechequePrintableFilter`. Без него загрузка обрывается на позициях с нулевой ценой.
- Методы `GetCost()` помечены устаревшими и генерируют варнинги. Используйте свойство `Cost`.
- Свойство `DiscountMarketingCampaigns` и интерфейс `IIikoNetPaymentItem` удалены из движка; шаблоны, которые их вызывают, не компилируются.

## Кастомный пречек (8.5.8 → 9.3.6)
### 1. Обновите заголовок повторного пречека
- Найдите любую строку с `Resources.RepeateBillHeaderTitleFormat`.
- Замените на `Resources.RepeatBillHeaderTitleFormat` (пример ниже).
```cshtml
<center>@string.Format(Resources.RepeatBillHeaderTitleFormat, Model.RepeatBillNumber)</center>
```

### 2. Добавьте фильтр печатаемых позиций гостей
- Найдите блок `@helper Guests` или аналогичный фрагмент, где вызывается `guest.Items.Where(...)`.
- Внутри `Where(item => ...)` сразу после `OrderItemsToPrintFilter(item, order.DiscountItems)` добавьте `&& OrderItemsPrechequePrintableFilter(item)`.
- Повторите правку для ветки с `DisplayGuests == true` и для ветки без гостей (обычно с `EnumerableEx.Return`).
```cshtml
Items = guest.Items.Where(item => orderItemsFilter(item)
    && OrderItemsToPrintFilter(item, order.DiscountItems)
    && OrderItemsPrechequePrintableFilter(item))
```
- Важно: фильтр должен находиться внутри скобок `Where(...)`, иначе появится ошибка про `EnumerableEx.Return<TResult>`.

### 3. Добавьте helper в секцию `@functions`
- В конце секции `@functions` вставьте новый метод (если его ещё нет).
```cshtml
private static bool OrderItemsPrechequePrintableFilter(IOrderItem orderItem)
{
    if (orderItem.Cost != 0m)
        return true;
    return orderItem.Product.PrechequePrintable;
}
```

### 4. Перейдите на свойство `Cost`
- Через поиск найдите все вызовы `GetCost()` в файле.
- Замените на обращение к свойству `Cost`, без круглых скобок.
```cshtml
var total = includedEntries.Sum(orderEntry => orderEntry.Cost);
var productItemSum = productItem.Cost;
```
- После замены убедитесь, что больше нигде нет `Cost()` — это вызовет ошибку «Non-invocable member».

## Стандартный пречек (шаблон из поставки)
### 1. Исправьте ключ ресурса
- Найдите `Resources.RepeateBillHeaderTitleFormat` и замените на `Resources.RepeatBillHeaderTitleFormat`.

### 2. Расширьте фильтрацию позиций
- В блоке формирования списков блюд добавьте `OrderItemsPrechequePrintableFilter(item)` по аналогии с кастомным шаблоном.
- Проверьте обе ветки: с гостями и без гостей.

### 3. Обновите секцию `@functions`
- Если метода `OrderItemsPrechequePrintableFilter` нет, добавьте тот же helper, что и выше.

### 4. Замените `GetCost()`
- Проходите по всем суммам (`Sum(...)`, расчёт итогов) и меняйте `GetCost()` на `Cost`.
- Особое внимание на раздел «По контрагентам» — там чаще всего остаются старые вызовы.

## Накладная доставки (9.1.7 и выше)
### 1. Уберите зависимости от `IIikoNetPaymentItem`
- В методе `Body` замените блок обработки `nonCategorizedDiscounts` на версию без приведения к `IIikoNetPaymentItem`.
```cshtml
foreach (var paymentItem in order.Payments.Concat(order.PrePayments)
           .Where(pi => pi.Type.ProcessAsDiscount && pi.Type is INonCashPaymentType))
{
    var replaceDiscount = ((INonCashPaymentType)paymentItem.Type).ReplaceDiscount;
    if (replaceDiscount == null)
        continue;

    nonCategorizedDiscounts.Add(new NonCategorizedDiscountItem(
        replaceDiscount.PrintableName,
        CalculatePercent(fullSum, paymentItem.Sum),
        paymentItem.Sum,
        string.Empty,
        replaceDiscount.DiscountBySum));
}
```

### 2. Обновите вывод платежей с нестандартной группой
- Найдите цикл, в котором используется `var iikoNetPaymentItem = payment as IIikoNetPaymentItem`.
- Замените на прямой вывод суммы и дополнительную печать контрагента (см. пример ниже).
```cshtml
foreach (var payment in payments.Where(p => p.Type.Group != PaymentGroup.Cash
    && p.Type.Group != PaymentGroup.Card))
{
    var nameFormat = GetPaymentItemName(payment);
    <pair left="@nameFormat" right="@MyFormatMoney(payment.Sum)" />

    var creditPaymentItem = payment as ICreditPaymentItem;
    if (creditPaymentItem != null && creditPaymentItem.Counteragent != null)
    {
        <left>@string.Format(Resources.CounteragentFormat, creditPaymentItem.Counteragent.Name)</left>
        <left>@string.Format(Resources.CounteragentCardFormat, creditPaymentItem.Counteragent.Card)</left>
    }
}
```

### 3. Переименуйте свойство фильтра оплаты
- Замените `ProccessAsDiscount` на `ProcessAsDiscount`, чтобы убрать предупреждения компилятора. Опять опечатка в слове "Process".

Інформація станом на 13.11.2025р