Rabaty i dopłaty
Syrve Office posiada wbudowany system rabatów. Zewnętrzne systemy lojalnościowe (Plazius, Syrve Loyalty i inne) nie są objęte tym artykułem. System rabatów Syrve Office pozwala na stosowanie rabatów i dopłat w różnych warunkach. Rabat oznacza obniżenie ceny pozycji o określoną kwotę, a dopłata — jej podwyższenie. Aby uprościć pojęcia używane dalej i ponieważ różnica między rabatem a dopłatą to jedynie znak kwoty, nazwiemy oba rabatami (w kodzie DiscountType, DiscountItem, DiscountCard itd.), przy czym dodatnia wartość DiscountSum odpowiada rabatowi, a ujemna — dopłacie, jeśli jest używana w danym kontekście.
Generalnie rabat może być tak skonfigurowany, że w ramach jednego zamówienia może jednocześnie obniżać cenę jednej pozycji, działając jak rabat, i podwyższać cenę innej, działając jak dopłata, dlatego rozdzielenie rabatów i dopłat wydaje się symboliczne.
Ograniczenia
Zasady i warunki stosowania rabatu (DiscountItem) definiuje typ rabatu (DiscountType). Może to być kwota stała (kupon), procent ceny, zaokrąglenie (odrzucenie groszy) i tak dalej, ale kwota po rabacie (AppliedDiscountItem) jest zawsze wartością bezwzględną, konkretną liczbą. Algorytmy stosowania rabatów zależą od kategorii pozycji, sekcji zamówienia, wartości zamówienia (FullSum), trybu obsługi, aktualnego czasu oraz czasu wydruku obsługi; rabaty mogą być łączone lub nie, mogą być stosowane zarówno równolegle (do pełnej ceny), jak i szeregowo (z uwzględnieniem poprzednich rabatów) — wszystkie te warunki są specyfiką implementacji i nie są publikowane w API.
Ogólne ustawienia dostępne w API to m.in.:
IsActive— czy rabat jest aktywny w bieżącej grupie,IsAutomatic— czy rabat może być dodawany do zamówień automatycznie,CanApplyManually— czy rabat może być dodany do zamówień ręcznie przez wybór z listy,CanApplyByCardNumber— czy rabat może być dodany do zamówień za pomocą numeru karty rabatowej (poprzez wpisanie numeru na klawiaturze ekranowej),CanApplyByDiscountCard— czy rabat może być dodany do zamówień za pomocą karty rabatowej (poprzez odczytanie ścieżki karty),DiscountByFlexibleSum— czy przy dodawaniu rabatu należy podać jego kwotę,CanApplySelectively— czy rabat może być stosowany selektywnie do kilku pozycji zamówienia.
Kwota rabatu jest obliczana dla każdej pozycji osobno, nawet jeśli rabat dotyczy całego zamówienia. Dlatego rabat na zamówienie to suma rabatów na wszystkie pozycje. Kwota rabatu, jak każda inna kwota pieniężna, jest podzielna przez najmniejszą jednostkę waluty. Suma wszystkich stosowanych rabatów nie może przekroczyć ceny, innymi słowy, cena pozycji po wszystkich rabatach może wynosić zero (100% rabatu), ale nie może być ujemna. Dopłaty nie mają takiego ograniczenia — do ceny zamówienia można dodać dowolną kwotę.
Cykl życia
Dodany do zamówienia rabat może mieć jeden z dwóch stanów: ustalony lub nieustalony. Rabaty mogą zmieniać stan, ale nie można nimi zarządzać, ponieważ stan jest powiązany z cyklem życia zamówienia. Obecnie rabaty są ustalane, gdy zamówienie przyjmuje status Bill, a nieustalone, gdy zamówienie ma status New, jednak procedura ta może ulec zmianie.
Rabat nieustalony
Gdy rabat jest dodawany do zamówienia, system przechowuje jedynie warunki obliczania. Kwoty są obliczane na żądanie, a wyniki obliczeń nie są zapisywane. Ponieważ za każdym razem obliczenia wykonują się na podstawie najnowszych dostępnych parametrów algorytmu stosowania rabatu, w tym ustawień Syrve Office i aktualnego czasu, wynik obliczeń może się różnić. W związku z tym wartość całkowita zamówienia może się zmieniać.
Automatyczne rabaty (IsAutomatic) nie są widoczne w zamówieniach z rabatami nieustalonymi i nie są wyświetlane na liście Discounts każdego zamówienia, jednak po ustaleniu rabatów ich widoczność zależy od efektu zastosowania.
Rabat ustalony
Gdy całkowita kwota zamówienia nie może się już zmienić, automatycznie obliczone wartości (ceny, rabaty itd.) zostają ustalone. Ostatni wynik obliczeń jest zapisywany i używany do dalszych odniesień zamiast ponownego przeliczania. Umożliwia to pracę niezależnie od ustawień rabatu i innych parametrów aplikacji. Od tego momentu system zapamiętuje wraz z algorytmem i parametrami stosowania rabatu kwoty przypisane do poszczególnych pozycji zamówienia. Jednak jeśli w momencie ustalenia rabat nie ma efektu (jego efekt jest zerowy), jest on usuwany z zamówienia.
Struktura danych
DiscountType— typ rabatu, pozycja w bazie rabatów. Bazę można pobrać za pomocą metodyGetDiscountTypes.DiscountItem— dodany rabat. Użyj metodAddDiscount,AddFlexibleSumDiscount,AddDiscountByCardNumber,AddFlexibleSumDiscountByCardNumberdo dodania rabatu do zamówienia. UżyjDeleteDiscountdo usunięcia rabatu,Discountsdo usunięcia listy dodanych rabatów.AppliedDiscountItem— wynik wcześniej dodanych rabatów; użyj metodyGetOrderAppliedDiscounts, aby ją uzyskać; rabaty mogą być stosowane automatycznie w momencie składania zamówienia lub system zwraca wynik wcześniej zastosowanych rabatów, jeśli zostały one ustalone w zamówieniu.FullSum— całkowita kwota zamówienia przed rabatami (wartość netto).ResultSum— całkowita kwota zamówienia po rabatach.
Uwaga. Nie zalecamy definiowania całkowitej kwoty rabatu jako różnicy między dwoma ostatnimi parametrami, ponieważ różnią się one nie tylko rabatami, ale także VAT-em, który nie jest uwzględniony w cenach pozycji. Całkowitą kwotę rabatu lepiej uzyskać przez dodanie wartości DiscountSum.
Selektywne stosowanie rabatów
Domyślnie rabaty dotyczą wszystkich pozycji, w tym tych dodanych po zastosowaniu rabatu. Jednak rabaty z włączoną opcją CanApplySelectively mogą być stosowane selektywnie do jednej lub więcej pozycji i wpływać tylko na nie. Na przykład, jeśli lokal sprzedaje wyroby piekarnicze, gorące bułki mogą być sprzedawane po pełnej cenie, natomiast schłodzone — z rabatem. Pozycja z listy magazynowej jest w obu przypadkach taka sama. To użytkownik (lub wtyczka) decyduje, do których pozycji i modyfikatorów rabat powinien być zastosowany. Ta decyzja (lub ograniczenie) działa jak lista dozwolonych, dlatego taki selektywny rabat nie będzie stosowany do pozycji dodanych później. Wszystkie inne ograniczenia (kategoria, czas, kwota itp.) pozostają w mocy, co oznacza, że rabat będzie stosowany tylko do tych pozycji z listy dozwolonych, które spełniają również pozostałe warunki.
Jeśli rabaty są stosowane selektywnie, dotyczą tylko określonych pozycji zamówienia. Na przykład, jeśli w zamówieniu znajduje się pozycja z wycenionymi modyfikatorami, a rabat jest zastosowany do tej pozycji, to tylko ta pozycja będzie sprzedawana z rabatem. Aby zastosować rabat zarówno do pozycji, jak i modyfikatorów, muszą one być wyraźnie określone.
Kluczowe funkcje
ChangeSelectiveDiscount— pozwala na utworzenie listy dozwolonych pozycji zamówienia, które mogą być objęte rabatem. Biorąc pod uwagę różne typy pozycji istniejące w systemie, faktycznie istnieją trzy listy: proste pozycje, składniki pozycji złożonych oraz modyfikatory.
Jeśli dla wszystkich trzech list zostanie ustawionenull, rabat nie będzie stosowany selektywnie, lecz do całego zamówienia.GetSelectiveDiscountItemSettings— pozwala zwrócić parametry selektywnego stosowania (wspomniane powyżej listy) lubnull, jeśli rabat dotyczy całego zamówienia bez określonych pozycji.IsSelectivelyApplied— pokazuje, czy rabat jest stosowany selektywnie, czy do całego zamówienia.
Przykłady
Przykład selektywnie stosowanego rabatu można znaleźć w wtyczce Resto.Front.Api.SamplePlugin (EditorTester.AddSelectiveDiscount) jako część SDK:
/// <summary>
/// Dodawanie selektywnego rabatu.
/// </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);
}