Return of Goods and Orders from Closed Cash Shifts

Tags: v8

Now it is possible to return goods or orders from closed cash shifts not only from the UI SyrveFront but also from the API V8.

In one of the previous news articles we discussed ways to retrieve orders from closed cash shifts. Now, if necessary, you can adjust the list of dishes in such an order and return it by calling the method StornoPastOrder.

If you need to return goods not tied to a specific order, you can use the method StornoPastOrderItems, preparing a list of goods items to return. PastOrderItem.Price and PastOrderItem.SumWithoutDiscounts are not used and can be left empty when passed to the method.

You can also specify the size of the dish from the API if sizes are supported. Each of the passed items can be marked as a modifier or main dish (PastOrderItem.IsMainDish). Similarly to the UI, there are no strict checks for compliance with the nomenclature type from the card. However, the first item in the list cannot be a modifier. Also, a dish marked as a modifier cannot have a size. Each PastOrderItem must specify the place of preparation and the type of place of preparation.

Currently, returns are only possible on the fiscal registrar of the current terminal by default. The cash shift on the FR must be open, and there must be enough cash for a cash return.

The payment type for the return can be obtained through GetPaymentTypesToStornoPastOrderItems. You can also return using a plugin payment type (with the flag canProcessPaymentReturnWithoutOrder set to true, passed in RegisterPaymentSystem).

The removal type for the return can be obtained through GetRemovalTypesToStornoPastOrderItems. The removal type can be

When returning with write-off, the presence of a configurable payment type “Return from Customer” is checked.

The branch must belong to the current group and the branch must have a warehouse.

The taxation system is passed only if it was obtained through GetTaxationSystemsToStornoPastOrderItems.

When returning with write-off, the right F_STRN (To process payment return) is checked. When returning without write-off, the right F_SWWOFF (To process payment return by check without return to warehouse) is checked.

Examples:

private void StornoPastOrder()
{
    var pastOrder = PluginContext.Operations.GetPastOrders().First();
    var paymentType = pastOrder.Payments.First().PaymentType;

    // rt.WriteoffType.HasFlag(WriteoffType.Cafe) - return with write-off
    // rt.WriteoffType == WriteoffType.None - return without write-off
    var removalType = PluginContext.Operations.GetRemovalTypesToStornoPastOrderItems().First(rt => rt.WriteoffType.HasFlag(WriteoffType.Cafe));
    var section = pastOrder.RestaurantSection;
    var orderType = pastOrder.OrderType;
    var taxationSystem = PluginContext.Operations.GetTaxationSystemsToStornoPastOrderItems().Select(ts => (TaxationSystem?)ts).FirstOrDefault();

    PluginContext.Operations.StornoPastOrder(
        PluginContext.Operations.GetCredentials(),
        pastOrder,
        paymentType,
        removalType,
        section,
        orderType,
        null,
        taxationSystem,
        null);
}

private void StornoProducts()
{
    var paymentType = PluginContext.Operations.GetPaymentTypesToStornoPastOrderItems().First(pt => pt.Name.Contains("SampleApiPayment"));

    // rt.WriteoffType.HasFlag(WriteoffType.Cafe) - return with write-off
    // rt.WriteoffType == WriteoffType.None - return without write-off
    var removalType = PluginContext.Operations.GetRemovalTypesToStornoPastOrderItems().First(rt => rt.WriteoffType.HasFlag(WriteoffType.Cafe));
    var section = PluginContext.Operations.GetTerminalsGroupRestaurantSections(PluginContext.Operations.GetHostTerminalsGroup()).First();
    var orderType = PluginContext.Operations.GetOrderTypes().FirstOrDefault(ot => ot.OrderServiceType == OrderServiceTypes.Common);
    var taxationSystem = PluginContext.Operations.GetTaxationSystemsToStornoPastOrderItems().Select(ts => (TaxationSystem?)ts).FirstOrDefault();

    var activeProducts = PluginContext.Operations.GetActiveProducts()
        .Where(product => product.Template == null &&
            (product.Type == ProductType.Dish || product.Type == ProductType.Modifier || product.Type == ProductType.Goods || product.Type == ProductType.ForPurchase))
        .ToList();

    PluginContext.Operations.StornoPastOrderItems(
        PluginContext.Operations.GetCredentials(),
        GetPastOrderItems(activeProducts).ToList(),
        paymentType,
        removalType,
        section,
        orderType,
        null,
        taxationSystem,
        null);
}

private IEnumerable<PastOrderItem> GetPastOrderItems(IReadOnlyList<IProduct> activeProducts)
{
    var product = activeProducts.First(p => p.Name.Contains("Tea"));
    yield return new PastOrderItem
    {
        IsMainDish = true,
        Product = product,
        ProductSize = PluginContext.Operations.GetProductSizes().FirstOrDefault(ps => ps.Name.Contains("S")),
        Amount = 2,
        SumWithDiscounts = 100.5m,
        Price = 0, // not used in StornoPastOrderItems
        SumWithoutDiscounts = 0, // not used in StornoPastOrderItems
    };

    product = activeProducts.First(p => p.Name.Contains("Cream"));
    yield return new PastOrderItem
    {
        IsMainDish = false,
        Product = product,
        ProductSize = null,
        Amount = 2,
        SumWithDiscounts = 0m,
        Price = 0, // not used in StornoPastOrderItems
        SumWithoutDiscounts = 0, // not used in StornoPastOrderItems
    };

    product = activeProducts.First(p => p.Name.Contains("Puree"));
    yield return new PastOrderItem
    {
        IsMainDish = true,
        Product = product,
        ProductSize = null,
        Amount = 1,
        SumWithDiscounts = 90m,
        Price = 0, // not used in StornoPastOrderItems
        SumWithoutDiscounts = 0, // not used in StornoPastOrderItems
    };

    product = activeProducts.First(p => p.Name.Contains("Bottle"));
    yield return new PastOrderItem
    {
        IsMainDish = true,
        Product = product,
        ProductSize = null,
        Amount = 2,
        SumWithDiscounts = -15m,
        Price = 0, // not used in StornoPastOrderItems
        SumWithoutDiscounts = 0, // not used in StornoPastOrderItems
    };
}