Przejdź do głównej zawartości

Szablony paragonów i raportów Razor

Czym jest Razor

Razor to składnia znaczników ASP.NET, która pozwala na osadzenie kodu po stronie serwera (Visual Basic i C#) w stronach internetowych. W Syrve Razor jest osadzony w kodzie XML, który następnie jest wysyłany do drukarek.

Proces drukowania szablonów Razor: Dane > Szablon Razor > Widok XML (nasz język znaczników do drukowania) > Drukowanie.

Szablony paragonów i modele danych

Każdy paragon ma swój własny model danych. Modele danych są dołączone do pakietu instalacyjnego Syrve. Wszystkie modele i szablony paragonów są przechowywane w następującym katalogu: \Resources\Cheques\RazorTemplates.

Co można tu znaleźć:

  • TemplateModels.xml — modele danych paragonów. Modele paragonów obejmują klasy Syrve POS i serwera. W dalszej części omówimy tylko klasy Syrve POS.
  • RmsEntityWrappers.xml — opis klas serwera.
  • Pliki CSHTML — dostępne szablony paragonów.

Weźmy na przykład bilet zakończenia gotowania.

Plik TemplateModels.xml zawiera model CookingCompleteCheque:

<Model Name="CookingCompleteCheque" Comment=“Cooking completion ticket" TemplateRootModel="true" CommentEn="Cooking complete ticket"><Include PropertiesGroupId="CommonChequeProperties" /><Property Name="CookingPlace" Type="RestaurantSection" Nullness="NotNull" Comment=“Ticket cooking place" CommentEn="Production place ticket" /><Property Name="Order" Type="KitchenOrder" Nullness="NotNull" Comment=“Order" CommentEn="Order" /><Property Name="Item" Type="KitchenOrderItem" Nullness="NotNull" Comment=“Ticket item" CommentEn="Order item ticket" /><Property Name="CompoundItemSecondaryComponent" Type="KitchenOrderProductItem" Nullness="CanBeNull"
Comment=“Right pizza half, for which the ticket is printed"
CommentEn="Right half of divided pizza for which ticket is printed" /></Model>

Znacznik zawiera parametr TemplateRootModel = "true". Oznacza to, że element opisuje model biletu.

W szablonie paragonu CookingCompleteCheque.cshtml określamy, który model jest używany:

@inherits TemplateBase<ICookingCompleteCheque>

Szablon może zawierać pola paragonu oraz grupy pól. W poniższym przykładzie widoczna jest grupa pól CommonChequeProperties. Opis pól i grup można znaleźć w pliku TemplateModels.xml.

include PropertiesGroupId="CommonChequeProperties" />

Właściwości Order i Item to obiekty Syrve POS klas KitchenOrder i KitchenOrderItem opisane w TemplateModels.xml.

Właściwość CookingPlace to obiekt klasy RestaurantSection. Jest to typ serwerowy, dlatego jego opis można znaleźć w pliku RmsEntityWrappers.xml.

<Model Name="RestaurantSection" Comment=“Section"><Property Name="Name" Type="string" Nullness="NotNull" Comment=“Section name" /><Property Name="PrintProductItemCommentInCheque" Type="bool" Comment=“Whether or not a menu item comment should be printed on the receipt" /><Property Name="PrintBarcodeInServiceCheque" Type="bool" Comment="Whether or not a menu item barcode should be printed on the service ticket" /><Property Name="DisplayGuests" Type="bool" Comment=“Whether or not guests should be displayed in this section" /><Property Name="PrintSummaryServiceCheque" Type="bool" Comment=“Whether a consolidated service ticket (true) or section service ticket (false) should be printed in the section" /></Model>

Szablony raportów i modele danych

Raporty Razor używają tego samego modelu danych. Opis obiektów i szablony raportów są przechowywane w katalogu \Resources\Reports\Templates.

W tym folderze:

  • CashServerEntityWrappers.xml — opis obiektów tworzonych w Syrve POS (zamówienie, pozycja zamówienia i inne). Można ich używać w raportach.
  • RmsEntityWrappers.xml — opis obiektów tworzonych na serwerze (produkt, użytkownik, grupa, sekcja itd.).
  • EventWrappers.xml — opis zdarzeń Syrve POS.
  • TransactionWrappers.xml — opis transakcji Syrve POS.
  • Pliki CSHTML — szablony raportów.

Model danych raportów Razor:

Pole modelu

[NotNull/CanBeNull] TypDanych NazwaPola

Opis
[NotNull] string NameNazwa raportu
[CanBeNull] ICashRegister CashRegisterAktywna drukarka paragonów
[CanBeNull] ICafeSession CafeSessionAktualna zmiana kasy
DateTime CurrentTimeAktualna data i godzina
[CanBeNull] IUser CurrentUserAktualny użytkownik
[NotNull] IGroup GroupAktualna grupa
[NotNull] ICafeSetup CafeSetupUstawienia POS
[NotNull] string CurrentTerminalNazwa aktywnego terminala
bool IsOnlyBodyMarkupRequiredCzy wystarczy sam znacznik ciała raportu (wersje 4.0+)
bool? IsXReportFinal

Czy raport X jest ostateczny dla zmiany kasy (reprezentuje raport Z) czy nie:

  • true — tak, raport X jest raportem Z;
  • false — nie, raport X nie jest ostateczny dla zmiany kasy;
  • null — raport nie jest raportem X.
[CanBeNull] ISettings ReportSettingsUstawienia/parametry raportu
[NotNull] IEntitiesProvider EntitiesDostawca umożliwiający dostęp do encji Syrve POS
[NotNull] IEventsProvider EventsDostawca umożliwiający dostęp do zdarzeń Syrve POS
[NotNull] ITransactionsProvider TransactionsDostawca umożliwiający dostęp do transakcji Syrve POS
[NotNull] IOlapReportsProvider OlapReportsDostawca umożliwiający dostęp do serwerowych raportów OLAP

Dostęp do encji Syrve POS

W modelu raportu pole Entities umożliwia pobieranie list różnych encji Syrve POS (zamówienia, operacje, typy płatności itd.).

// Pobierz wszystkie zamówienia, które nie zostały usunięte i nie są powiązane z rezerwacjami/bankietami, które nigdy się nie rozpoczęły, dla zmiany kasy
IEnumerable<IOrder> GetAllNotDeletedNotBoundToNonStartedReservesOrdersBySession([NotNull] ICafeSession session);
// Pobierz wszystkie nieusunięte sekcje z stolikami w grupie
IEnumerable<IRestaurantSection> GetAllNotDeletedSectionsWithAnyTablesByGroup([NotNull] IGroup group);
// Pobierz wszystkie metody płatności
IEnumerable<IPaymentType> GetAllPaymentTypes();
// Pobierz wszystkie systemy płatności
IEnumerable<IPaymentSystem> GetAllPaymentSystems();
// Pobierz wszystkie nieusunięte zamówienia dostawy
IEnumerable<IDelivery> GetAllNotDeletedDeliveries();
// Pobierz wszystkie problematyczne operacje
IEnumerable<ICommonGroup> GetProblemOperationsEvents(bool allTerminalsEvents, DateTime dateBegin, DateTime dateEnd);

Dostęp do zdarzeń Syrve POS

W modelu raportu pole Events umożliwia pobranie list różnych zdarzeń Syrve POS.

// Pobierz wszystkie zdarzenia sprzedaży pozycji na zmianę kasy
IEnumerable<IItemSaleEvent> GetItemSaleEventsBySession([NotNull] ICafeSession session);
// Pobierz wszystkie zdarzenia wpłat i wypłat na zmianę kasy
IEnumerable<IPayInOutEvent> GetPayInOutEventsBySession([NotNull] ICafeSession session);

Dostęp do transakcji Syrve POS

W modelu raportu pole Transactions umożliwia pobranie list różnych transakcji Syrve POS.

// Pobierz wszystkie transakcje płatności zamówień
IEnumerable<IOrderPaymentTransaction> GetOrderPaymentTransactions();
// Pobierz wszystkie transakcje płatności zamówień na zmianę kasy
IEnumerable<IOrderPaymentTransaction> GetOrderPaymentTransactionsBySession([NotNull] ICafeSession session);
// Pobierz wszystkie fiskalne transakcje wpłat i wypłat na zmianę kasy
IEnumerable<IPayInOutFiscalTransaction> GetPayInOutFiscalTransactionsBySession([NotNull] ICafeSession session);
// Pobierz wszystkie transakcje płatności zamówień z informacji o zamknięciu zamówienia
IEnumerable<IOrderPaymentTransaction> GetOrderPaymentTransactionsByOrderCloseInfo([NotNull] IOrderCloseInfo orderCloseInfo);

Dostęp do raportów OLAP serwera

W modelu raportu pole OlapReports umożliwia pobranie danych raportów OLAP serwera i ich osadzenie. To pole posiada następujące dostępne metody:

// Uruchom raport OLAP zgodnie z ustawieniami
IOlapReport BuildReport([NotNull] OlapReportSettings reportSettings);
// Uruchom kilka raportów OLAP zgodnie z listą ustawień
List<IOlapReport> BuildReports([NotNull] IEnumerable<OlapReportSettings> reportsSettings);

 

Ustawienia i parametry raportu Razor

Niektóre parametry wpływają na dane raportu i jego formatowanie. Korzystając z pola ReportSettings w modelu, można uzyskać dostęp do parametrów w Syrve Office i Syrve POS.

Aby uzyskać wartość parametru, należy znać jego nazwę i typ danych. Typ danych (enumeracja, boolean, okres, string, liczba) wpływa na uzyskaną wartość. 

Jak uzyskać wartości:

  • Enumeracja

    var settings = Model.ReportSettings;
    // Pobierz wartość enumeracji po nazwie parametru i porównaj ją z jedną z wartości
    if (settings.GetEnum("GroupDishes") == "GroupByDishes")
    // Grupuj według pozycji
  • Boolean

    var settings = Model.ReportSettings;
    // Pobierz wartość boolean po parametrze
    if (settings.GetBool("ShowOneDishPrice"))
    // Pokaż cenę jednostkową pozycji
  • Okres

    var settings = Model.ReportSettings;
    // Pobierz datę rozpoczęcia okresu
    var periodBegin = settings.GetPeriodBegin("ReportInterval");
    // Pobierz datę zakończenia okresu
    var periodEnd = settings.GetPeriodEnd("ReportInterval");
  • String

    var settings = Model.ReportSettings;
    // Pobierz parametr typu string „str”
    var myStr = (string)settings.GetValue("str");
  • Liczba

    var settings = Model.ReportSettings;
    // Pobierz parametr numeryczny „number” (gdzie Format to liczba ułamkowa lub kwota)
    var myNumber = (decimal)settings.GetValue("number");
    // Pobierz parametr numeryczny „number” (gdzie Format to liczba całkowita)
    myNumber = (int)settings.GetValue("number");

Szczegóły dotyczące dodawania i edytowania niestandardowych parametrów raportów znajdują się w artykule Syrve POS Reports.

Dodatkowe funkcje dla paragonów i raportów

Te same bloki kodu są często używane w paragonach i raportach: zaokrąglanie kwot walut, formatowanie dat i wag, pobieranie wszystkich pozycji zamówienia, kwot VAT, zaliczek na zamówienie i tak dalej. Aby uniknąć błędów i duplikatów, bloki kodu zostały przeniesione do osobnych metod. Niektóre metody mogą być używane tylko dla paragonów lub raportów, a niektóre dla obu.

SygnaturaOpisZastosowanie
string FormatAmount(decimal amount)Format ilości. Wartość całkowita jest wyświetlana bez części ułamkowej, wartość ułamkowa jest dokładna do trzech miejsc po przecinku.Paragony, raporty
string FormatFoodValueItem(decimal foodValueItem)Format wartości odżywczej. Wartość całkowita jest wyświetlana bez części ułamkowej, wartość ułamkowa jest dokładna do jednego miejsca po przecinku.Paragony
string FormatMoney(decimal money)Format ceny z częścią ułamkową. Bez separatorów. Długość części ułamkowej zależy od waluty (określonej w Syrve Office).Paragony
string FormatPrice(decimal price)Odpowiednik FormatMoney.Raporty
string FormatAmountAndPrice(decimal amount, decimal price)Format ilości i ceny jako AxB, gdzie A — FormatAmount, B — FormatMoneyMin.Raporty
string FormatMoneyMin(decimal money)Formatowanie ceny. Wartość całkowita jest wyświetlana bez części ułamkowej, długość części ułamkowej odpowiada długości części ułamkowej aktywnej waluty (określonej w Syrve Office). Bez separatorów.Paragony
string FormatMoneyInWords(decimal money)Konwertuje liczbę i zwraca ją w formie tekstowej (drukowanej). Pełne nazwy walut są podane w odpowiednim deklinacji.Paragony
string FormatPercent(decimal value)Format wartości procentowej. Wartość całkowita jest wyświetlana bez części ułamkowej, wartość ułamkowa jest dokładna do dwóch miejsc po przecinku. % jest umieszczany po wartości.Paragony, raporty
string FormatAveragePercent(decimal percent)Format wartości procentowej dokładny do jednego miejsca po przecinku. % jest umieszczany po wartości.Raporty
string FormatAverage(decimal amount)Format liczby. Wartość całkowita jest wyświetlana bez części ułamkowej, wartość ułamkowa jest dokładna do dwóch miejsc po przecinku.Raporty
string FormatTime(DateTime time)Format czasu. Godziny i minuty podane są w formacie 24-godzinnym (HH:mm).Paragony, raporty
string FormatLongTime(DateTime time)Format czasu. Godziny, minuty i sekundy podane są w formacie 24-godzinnym (HH:mm:ss).Paragony
string FormatLongDateTime(DateTime dateTime)Format daty i czasu. Wyświetlane są dzień, miesiąc, rok, godziny i minuty (dd.MM.yyyy HH:mm)Paragony, raporty
string FormatFullDateTime(DateTime dateTime)Format daty i czasu. Wyświetlane są dzień, miesiąc słownie, godziny i minuty (d MMM HH:mm).Paragony
string FormatDate(DateTime dateTime)Format daty. Wyświetlane są dzień, miesiąc i rok (dd.MM.yyyy).Paragony, raporty
string FormatDateTimeCustom(DateTime dateTime, string format)Niestandardowy format daty/czasu. Formatowanie wykonywane jest według maski ustawionej w drugim argumencie funkcji.Paragony
string FormatTimeSpan(TimeSpan timeSpan, bool displaySeconds)Format wartości przedziału czasowego. W zależności od wartości drugiego parametru, sekundy są wyświetlane (true) lub nie (false) (HH:mm:ss/HH:mm). Jeśli sekundy nie są wyświetlane, są zaokrąglane do minuty w górę, jeśli >=30, w przeciwnym razie w dół.Paragony, raporty
decimal CalculatePercent(decimal fullValue, decimal partValue)Oblicza procent wartości partValue względem fullValue z dokładnością do dwóch miejsc po przecinku. Jeśli fullValue jest 0, procent wynosi 0.Paragony
decimal CalculateDiscountPercent(decimal fullSum, decimal discountSum)Odpowiednik CalculatePercentRaporty
decimal RoundMoney(this decimal value)Kwoty walutowe są zaokrąglane zgodnie z długością części ułamkowej aktywnej waluty.Paragony, raporty
decimal RoundWeight(this decimal value)Zaokrąglanie wagi do trzeciego miejsca po przecinku.Paragony, raporty
decimal GetCost([NotNull] this IChequeTaskSale chequeTaskSale)Pobiera kwotę pozycji paragonu. Uproszczony wzór: cena * ilość = kwota całkowitaParagony
decimal GetCost([NotNull] this IOrderEntry orderEntry)Pobiera kwotę pozycji zamówienia. Uproszczony wzór: cena * ilość = kwota całkowitaParagony, raporty
IEnumerable<IOrderEntry> GetAllEntries([NotNull] this IOrder order)Pobiera listę wszystkich pozycji zamówienia.Raporty
IEnumerable<IOrderEntry> ExpandAllEntries([NotNull] this IOrderItem orderItem)Pobiera listę wszystkich elementów podrzędnych dla elementu zamówienia. Sam element jest również uwzględniony w kolekcji.Raporty
IEnumerable<IOrderEntry> GetChildren([NotNull] this IOrderItem orderItem)Pobiera listę wszystkich elementów podrzędnych dla elementu zamówienia. Sam element nie jest uwzględniony w kolekcji.Raporty
IEnumerable<IOrderEntry> GetIncludedEntries([NotNull] this IOrder order)Pobiera listę wszystkich nieusuniętych pozycji zamówienia.Paragony, raporty
IEnumerable<IOrderEntry> ExpandIncludedEntries([NotNull] this IOrderItem orderItem)Pobiera listę wszystkich nieusuniętych elementów podrzędnych dla elementu zamówienia. Sam element jest również uwzględniony w kolekcji. Jeśli element jest usunięty, zwracana jest pusta kolekcja.Paragony, raporty
IEnumerable<IOrderEntry> GetNotDeletedChildren([NotNull] this IOrderItem orderItem)Pobiera listę wszystkich nieusuniętych elementów podrzędnych dla elementu zamówienia. Sam element nie jest uwzględniony w kolekcji. Jeśli element jest usunięty, zwracana jest pusta kolekcja.Paragony, raporty
decimal GetVatSumExcludedFromPriceForOrderEntry([NotNull] this IOrderEntry orderEntry, [NotNull] IEnumerable<IDiscountItem> discountItems)Pobiera kwotę VAT, która nie jest uwzględniona w cenie pozycji zamówienia. Jeśli VAT jest uwzględniony w cenie, kwota = 0. Do metody należy przekazać listę rabatów zamówienia.Paragony, raporty
decimal GetVatSumIncludedInPriceForOrderEntry([NotNull] this IOrderEntry orderEntry, [NotNull] IEnumerable<IDiscountItem> discountItems)Pobiera kwotę VAT uwzględnioną w cenie pozycji zamówienia. Jeśli VAT nie jest uwzględniony w cenie, kwota = 0. Do metody należy przekazać listę rabatów zamówienia.Paragony
decimal GetDiscountSumFor([NotNull] this IDiscountItem discountItem, [NotNull] IOrderEntry orderEntry)Pobiera kwotę rabatu dla określonego rabatu i pozycji zamówienia.Paragony
decimal GetDiscountSum([NotNull] this IDiscountItem discountItem)Pobiera kwotę rabatu na wszystkich nieusuniętych pozycjach zamówienia dla określonego rabatu.Paragony, raporty
bool IsDiscount([NotNull] this IDiscountItem discountItem)Określa, czy wskazany rabat jest rabatem (a nie narzutem).Paragony, raporty
decimal GetFullSum([NotNull] this IOrder order)Pobiera pełną kwotę zamówienia przed rabatami/narzutami i bez VAT niewliczonego w cenę.Paragony, raporty
decimal GetResultSum([NotNull] this IOrder order)Pobiera kwotę zamówienia po rabatach/narzutach i z VAT niewliczonym w cenę.Raporty
decimal GetResultSumWithoutExcludedVat([NotNull] this IOrder order)Pobiera kwotę zamówienia po rabatach/narzutach ALE bez VAT niewliczonego w cenę.Raporty
decimal GetCategorizedDiscountsSum([NotNull] this IOrder order)Pobiera kwotę rabatów kategorii dla zamówienia.Paragony
decimal GetNonCategorizedDiscountsSum([NotNull] this IOrder order)Pobiera kwotę rabatów niekategorii dla zamówienia.Paragony
decimal GetVatSumExcludedFromPrice([NotNull] this IOrder order)Pobiera kwotę VAT, która nie jest uwzględniona w cenie, dla zamówienia. Jeśli VAT jest uwzględniony w cenie, kwota = 0.Paragony, raporty
decimal GetPrepaySum([NotNull] this IOrder order)Pobiera kwotę wszystkich zaliczek na zamówienie.Paragony
decimal GetChangeSum([NotNull] this IOrder order, decimal resultSum)Pobiera kwotę reszty dla zamówienia. Do metody należy przekazać kwotę całkowitą.Paragony
string GetNameOrEmpty([CanBeNull] this IUser user)Zwraca nazwę użytkownika, jeśli użytkownik nie jest pusty, w przeciwnym razie zwraca pusty ciąg.Paragony
string StringView([NotNull] this IAddress address)Zwraca adres jako ciąg znaków.Paragony
string GetKitchenOrDefaultName([NotNull] this IProduct product)Zwraca nazwę kuchni produktu, jeśli nie jest pusta, w przeciwnym razie zwraca zwykłą nazwę.Paragony
bool IsAmountIndependentOfParentAmount([NotNull] this IModifierEntry modifier)Czy ilość określonego modyfikatora jest niezależna od ilości pozycji, czy nie.Paragony
IEnumerable<HashSet<IProductItem>> GetNotDeletedProductItemsByMix([NotNull] this IGuest guest)Zwraca listę pozycji zamówienia (dań) pogrupowanych według miksu. Do metody należy przekazać gościa.Paragony
DateTime GetPeriodBegin([NotNull] this ISettings settings, [NotNull] string name = "ReportInterval")Zwraca parametr „Początek okresu” typu „Okres” dla ustawień raportu. Wartość name to nazwa parametru w Syrve Office. Domyślnie name = "ReportInterval".Raporty
DateTime GetPeriodEnd([NotNull] this ISettings settings, [NotNull] string name = "ReportInterval")Zwraca parametr „Koniec okresu” typu „Okres” dla ustawień raportu. Wartość name to nazwa parametru w Syrve Office. Domyślnie name = "ReportInterval".Raporty
bool GetBool([NotNull] this ISettings settings, [NotNull] string name)Zwraca wartość logiczną parametru „Wartość logiczna (tak/nie)”. Wartość name to nazwa parametru w Syrve Office.Raporty
string GetEnum([NotNull] this ISettings settings, [NotNull] string name)Zwraca wartość wyliczeniową parametru „Wyliczenie”. Wartość name to nazwa parametru w Syrve Office.Raporty
IEnumerable<IUser> GetCounteragents([NotNull] this ISettings settings, [NotNull] string name)Zwraca listę kontrahentów parametru „Kontrahenci”. Wartość name to nazwa parametru w Syrve Office.Raporty, 4.2+
Anulowanie zadania drukowania w szablonie -----------------------------------------

Odbiór zadań drukowania raportów można anulować w szablonie, wyrzucając wyjątek OperationCanceledException z tekstem wyjątku. W pliku print-templates.log zostanie zapisana wiadomość Template running was canceled. Message: {0}, gdzie {0} — tekst wyjątku, który można wprowadzić w szablonie.

@inherits TemplateBase<IBillCheque>
@{
var order = Model.Order;
if (order.Number % 2 == 0)
{
throw new OperationCanceledException("Parzyste zamówienia nie muszą być drukowane");
}
}

   

@inherits TemplateBase<IServiceChequeBase>

@helper ThrowException(string message)
{
throw new OperationCanceledException(message);
}

<doc bell="" formatter="split">
@if (Model is IServiceCheque)
{
if (Model.Order.Number % 2 == 0)
{
@ThrowException("Nie drukuj biletu kuchennego dla parzystych zamówień")
}
@Service((IServiceCheque)Model)
}
else if (Model is IBanquetServiceCheque)
{
@Banquet((IBanquetServiceCheque)Model)
}
else if (Model is IDeleteProductsServiceCheque)
{
@DeleteProducts((IDeleteProductsServiceCheque)Model)
}
else if (Model is IDeleteModifiersServiceCheque)
{
@DeleteModifiers((IDeleteModifiersServiceCheque)Model)
}
else if (Model is IProductsServeCheque)
{
@ProductsServe((IProductsServeCheque)Model)
}
else if (Model is IWholeCourseServeCheque)
{
@WholeCourseServe((IWholeCourseServeCheque)Model)
}
else
{
throw new NotSupportedException(string.Format("Nieobsługiwany typ modelu '{0}'", Model.GetType()));
}
</doc>