Syrve POS API SDK

Discounts & Surcharges

Syrve Office has a built-in discount system. External loyalty systems (Plazius, Syrve Loyalty, and others) are not covered in this article. Syrve Office discount system allows applying discounts and surcharges under various conditions. A discount means an item price decrease for a particular amount, and a surcharge — increase. To simplify the terms we use hereunder and since the difference between a discount and a surcharge is merely the sign of the amount in question, let us call both the discounts (in the code DiscountType, DiscountItem, DiscountCard etc.), implying that the positive DiscountSum value corresponds to the discount and negative — to the surcharge if used within the subject matter.

Generally, a discount can be so configured that within an order it may concurrently decrease the price of one item, acting as a discount, and increase the price of another, acting like a surcharge, therefore, the separation of discounts and surcharges seems quite symbolic.

Restrictions

Rules and conditions for the discount (DiscountItem) application are defined by the type of discount (DiscountType). It can be a fixed amount (coupon), percentage of the price, rounding off (cents dropping), and so on, but the amount after discount (AppliedDiscountItem) is always an absolute value, a specific number. Discounts application algorithms depend on the item category, order section, order amount (FullSum), service mode, current time, and service printing time; discounts can be combined or not, can be applied both in parallel (to the full price), and in series (with account to previous discounts), — all such conditions are implementation specifics and are not published in the API.

General settings are given in the API, such as:

The discount amount is calculated for each item separately even if the discount applies to the entire order. Therefore, an order discount is all item discounts put together. The discount amount as any other monetary amount is divisible by the minimum currency face value. The total of all applicable discounts cannot exceed the price, in other words, the item price after all discounts can be zero (100% discount) but cannot be a negative amount. Surcharges do not have such a restriction — any amount can be added to the order price.

Life Cycle

The discount added to the order may have one of the two states: fixed or not fixed. Discounts may change from one state to another, but they can’t be managed as the state is linked to the order life cycle. Presently, discounts are fixed when an order takes the status Bill and unfixed when the order takes the Newstatus, however, this procedure is subject to change.

Unfixed Discount

When the discount is added to the order, the system stores only calculating conditions. Amounts are calculated upon the request, whereas calculation results are not stored. Since each time the calculation takes place most recent available parameters of the discount application algorithm are used, including Syrve Office settings and current time, the calculation may have a different result. Therefore, the total order value may change.

Automatic discounts (IsAutomatic) are not visible in orders with unfixed discounts and are not given on the list of Discounts of each order, however, once discounts are fixed, the visibility depends on the application effect.

Fixed Discount

When the order total amount can no longer change, automatically calculated values (prices, discounts, etc) will be fixed. The last calculation result is saved and used for further reference instead of recalculating it. This makes it possible to work regardless of the discount settings and other application parameters used. From this point on, along with the algorithm and discount application parameters, the system remembers amounts per order item. However, if at the time of fixation, the discount is not in effect (has zero effect), it is removed from the order.

Data Structure

Note. We do not recommend defining the total discount amount as the difference between the last two parameters for they differ not only in discounts but also in the VAT, not included in the item prices. The total discount amount is better be obtained by adding DiscountSum values.

Selective Use of Discounts

By default, discounts apply to all items, including those added after the discount. However, discounts with the CanApplySelectively setting enabled can be selectively applied to one or more items and hence affect only them. For example, if a venue sells bakery products, hot buns can be sold at a full price, whereas, cooled ones — at a discount. The Stocklist item is the same in both cases. It is up to a user (or a plugin) to decide which items and modifiers a discount should be applied to. This decision (or limitation) works as a whitelist, therefore, such a selective discount will not apply to the items added thereafter. All other limitations (category, time, amount, etc.) remain in force, meaning the discount will only apply to those whitelist items that comply with other conditions as well.

If used selectively, discounts apply only to the specified order items. For example, if there is an item with priced modifiers in the order, and a discount is applied to the item, it is only the item that will be sold at a discount. To apply a discount to both the item and modifiers, they should be expressly specified.

Key functions

Examples

An example of a selectively applied discount can be found in the Resto.Front.Api.SamplePlugin (EditorTester.AddSelectiveDiscount) plugin as part of the SDK:

/// <summary>
/// Adding a selective discount.
/// </summary>
private void AddSelectiveDiscount()
{
    var order = PluginContext.Operations.GetOrders().Last();
    var selectedDish = new List<IOrderProductItemStub> { order.Items.OfType<IOrderProductItem>().Last() };
    var discountType = PluginContext.Operations.GetDiscountTypes().Last(x => !x.Deleted && x.IsActive && x.CanApplySelectively);
    var editSession = PluginContext.Operations.CreateEditSession();
    editSession.AddDiscount(discountType, order);
    editSession.ChangeSelectiveDiscount(order, discountType, selectedDish, null, null);
    PluginContext.Operations.SubmitChanges(PluginContext.Operations.GetCredentials(), editSession);
}