Przejdź do głównej zawartości

Szablony paragonów i raportów Razor

Co to jest Razor

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

Przebieg drukowania szablonów Razor: Dane > Szablon Razor > Wyświetl XML (nasz znacznik drukowania) > Drukowanie.

Szablony paragonów i modele danych

Każdy paragon ma swój własny model danych. Modele danych są zawarte w pakiecie instalacyjnym 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. Dalej omówimy tylko klasy Syrve POS.
  • RmsEntityWrappers.xml — opis klas serwera.
  • Pliki CSHTML — dostępne szablony paragonów.

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

Plik TemplateModels.xml zawiera model CookingCompleteCheque:

<Model Name="CookingCompleteCheque" Comment=“Bilet zakończenia gotowania" TemplateRootModel="true" CommentEn="Cooking complete ticket"><Include PropertiesGroupId="CommonChequeProperties" /><Property Name="CookingPlace" Type="RestaurantSection" Nullness="NotNull" Comment=“Miejsce gotowania biletu" CommentEn="Production place ticket" /><Property Name="Order" Type="KitchenOrder" Nullness="NotNull" Comment=“Zamówienie" CommentEn="Order" /><Property Name="Item" Type="KitchenOrderItem" Nullness="NotNull" Comment=“Pozycja biletu" CommentEn="Order item ticket" /><Property Name="CompoundItemSecondaryComponent" Type="KitchenOrderProductItem" Nullness="CanBeNull"
Comment=“Prawa połowa pizzy, dla której drukowany jest bilet"
CommentEn="Right half of divided pizza for which ticket is printed" /></Model>

Tag zawiera parametr TemplateRootModel = "true". Pokazuje, ż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 i grupy pól. W poniższym przykładzie można zobaczyć grupę pól CommonChequeProperties. Opis pól i grup można znaleźć w TemplateModels.xml.

include PropertiesGroupId="CommonChequeProperties" />

Właściwości Order i Item są obiektami Syrve POS klas KitchenOrder i KitchenOrderItem opisanymi w TemplateModels.xml.

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

<Model Name="RestaurantSection" Comment=“Sekcja"><Property Name="Name" Type="string" Nullness="NotNull" Comment=“Nazwa sekcji" /><Property Name="PrintProductItemCommentInCheque" Type="bool" Comment=“Czy komentarz do pozycji menu powinien być drukowany na paragonie" /><Property Name="PrintBarcodeInServiceCheque" Type="bool" Comment="Czy kod kreskowy pozycji menu powinien być drukowany na bilecie serwisowym" /><Property Name="DisplayGuests" Type="bool" Comment=“Czy goście powinni być wyświetlani w tej sekcji" /><Property Name="PrintSummaryServiceCheque" Type="bool" Comment=“Czy w sekcji powinien być drukowany skonsolidowany bilet serwisowy (true) czy bilet serwisowy sekcji (false)" /></Model>

Szablony raportów i modele danych

Raporty Razor używają jednego i 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 itp.).
  • 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 CashRegisterAktywny drukarka paragonów
[CanBeNull] ICafeSession CafeSessionAktualna zmiana kasowa
DateTime CurrentTimeAktualna data i czas
[CanBeNull] IUser CurrentUserAktualny użytkownik
[NotNull] IGroup GroupAktualna grupa
[NotNull] ICafeSetup CafeSetupUstawienia POS
[NotNull] string CurrentTerminalNazwa aktywnego terminala
bool IsOnlyBodyMarkupRequiredCzy sam znacznik treści raportu jest wystarczający (wersje 4.0+)
bool? IsXReportFinal

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

  • true — tak, raport X to raport Z;
  • false — nie, raport X nie jest ostateczny dla zmiany kasowej;
  • null — raport nie jest raportem X.
[CanBeNull] ISettings ReportSettingsUstawienia/parametry raportu
[NotNull] IEntitiesProvider EntitiesDostawca, który daje dostęp do jednostek Syrve POS
[NotNull] IEventsProvider EventsDostawca, który daje dostęp do zdarzeń Syrve POS 
[NotNull] ITransactionsProvider TransactionsDostawca, który daje dostęp do transakcji Syrve POS 
[NotNull] IOlapReportsProvider OlapReportsDostawca, który daje dostęp do raportów OLAP serwera

Dostęp do jednostek Syrve POS

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

// 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 na zmianę kasową
IEnumerable<IOrder> GetAllNotDeletedNotBoundToNonStartedReservesOrdersBySession([NotNull] ICafeSession session);
// Pobierz wszystkie nieusunięte sekcje z tabelami w grupie

Chunk 2/4:

IEnumerable GetAllNotDeletedSectionsWithAnyTablesByGroup([NotNull] IGroup group); // Pobierz wszystkie metody płatności IEnumerable GetAllPaymentTypes(); // Pobierz wszystkie systemy płatności IEnumerable GetAllPaymentSystems(); // Pobierz wszystkie nieusunięte zamówienia dostawy IEnumerable GetAllNotDeletedDeliveries(); // Pobierz wszystkie problematyczne operacje IEnumerable GetProblemOperationsEvents(bool allTerminalsEvents, DateTime dateBegin, DateTime dateEnd);


### Dostęp do wydarzeń Syrve POS

W modelu raportu pole Events umożliwia uzyskanie listy różnych wydarzeń Syrve POS.

```c#
// Pobierz wszystkie wydarzenia sprzedaży artykułów na zmianę kasy
IEnumerable<IItemSaleEvent> GetItemSaleEventsBySession([NotNull] ICafeSession session);
// Pobierz wszystkie wydarzenia 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 uzyskanie listy różnych transakcji Syrve POS.

// Pobierz wszystkie transakcje płatności za zamówienia
IEnumerable<IOrderPaymentTransaction> GetOrderPaymentTransactions();
// Pobierz wszystkie transakcje płatności za zamówienia na zmianę kasy
IEnumerable<IOrderPaymentTransaction> GetOrderPaymentTransactionsBySession([NotNull] ICafeSession session);
// Pobierz wszystkie transakcje fiskalne wpłat i wypłat na zmianę kasy
IEnumerable<IPayInOutFiscalTransaction> GetPayInOutFiscalTransactionsBySession([NotNull] ICafeSession session);
// Pobierz wszystkie transakcje płatności za zamówienia 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 uzyskanie danych raportu OLAP serwera i ich osadzenie. To pole ma dostępne następujące 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 (wyliczenie, boolean, okres, string, liczba) wpływa na uzyskaną wartość. 

Jak uzyskać wartości:

  • Wyliczenie

    var settings = Model.ReportSettings;
    // Pobierz wartość wyliczenia według nazwy 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 według parametru
    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 string „str”
    var myStr = (string)settings.GetValue("str");
  • Liczba

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

Szczegóły dotyczące dodawania i edytowania niestandardowych parametrów raportu można znaleźć w artykule Raporty Syrve POS.

Dodatkowe funkcje dla paragonów i raportów

Te same bloki kodu są często używane w paragonach i raportach: zaokrąglanie kwot walutowych, formatowanie dat i wagi, uzyskiwanie wszystkich pozycji zamówienia, kwot VAT, kwot przedpłat za zamówienia itp. Aby uniknąć błędów i duplikatów, bloki kodu zostały przeniesione do oddzielnych metod. Niektóre metody mogą być używane tylko dla paragonów lub raportów, a niektóre dla obu.

PodpisOpisZastosowanie
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, В — 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 przypadku.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. % znajduje się po wartości.Paragony, raporty
string FormatAveragePercent(decimal percent)Format wartości procentowej dokładny do jednego miejsca po przecinku. % znajduje się 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 są podane w formacie 24-godzinnym (HH:mm).Paragony, raporty
string FormatLongTime(DateTime time)Format czasu. Godziny, minuty i sekundy są podane w formacie 24-godzinnym (HH:mm:ss).Paragony
string FormatLongDateTime(DateTime dateTime)Format daty i czasu. Dzień, miesiąc, rok, godziny i minuty (dd.MM.yyyy HH:mm) są wyświetlaneParagony, raporty
string FormatFullDateTime(DateTime dateTime)Format daty i czasu. Dzień, miesiąc słownie, godziny i minuty (d MMM HH:mm) są wyświetlane.Paragony
string FormatDate(DateTime dateTime)Format daty. Dzień, miesiąc i rok (dd.MM.yyyy) są wyświetlane.Paragony, raporty
string FormatDateTimeCustom(DateTime dateTime, string format)Niestandardowy format daty/czasu. Formatowanie jest wykonywane w masce ustawionej przez drugi argument funkcji.Paragony
string FormatTimeSpan(TimeSpan timeSpan, bool displaySeconds)Format wartości przedziału czasu. 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, jeśli >=30, w przeciwnym razie w dół.Paragony, raporty
decimal CalculatePercent(decimal fullValue, decimal partValue)Oblicza procent partValue w porównaniu do fullValue z dokładnością do dwóch miejsc po przecinku. Jeśli fullValue wynosi 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)Pobierz kwotę dla pozycji paragonu. Uproszczona formuła: cena * ilość = całkowita kwotaParagony
decimal GetCost([NotNull] this IOrderEntry orderEntry)Pobierz kwotę dla pozycji zamówienia. Uproszczona formuła: cena * ilość = całkowita kwotaParagony, raporty
IEnumerable<IOrderEntry> GetAllEntries([NotNull] this IOrder order)Pobierz listę wszystkich pozycji zamówienia.Raporty
IEnumerable<IOrderEntry> ExpandAllEntries([NotNull] this IOrderItem orderItem)Pobierz 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)Pobierz 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)Pobierz listę wszystkich nieusuniętych pozycji zamówienia.Paragony, raporty
IEnumerable<IOrderEntry> ExpandIncludedEntries([NotNull] this IOrderItem orderItem)Pobierz 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)Pobierz 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)Pobierz kwotę VAT, która nie jest uwzględniona w cenie pozycji zamówienia. Jeśli VAT jest uwzględniony w cenie, kwota = 0. Lista rabatów zamówienia musi być przekazana do metody.Paragony, raporty
decimal GetVatSumIncludedInPriceForOrderEntry([NotNull] this IOrderEntry orderEntry, [NotNull] IEnumerable<IDiscountItem> discountItems)Pobierz kwotę VAT uwzględnioną w cenie pozycji zamówienia. Jeśli VAT nie jest uwzględniony w cenie, kwota = 0. Lista rabatów zamówienia musi być przekazana do metody.Paragony
decimal GetDiscountSumFor([NotNull] this IDiscountItem discountItem, [NotNull] IOrderEntry orderEntry)Pobierz kwotę rabatu dla określonego rabatu i pozycji zamówienia.Paragony
decimal GetDiscountSum([NotNull] this IDiscountItem discountItem)Pobierz kwotę rabatu na wszystkie nieusunięte pozycje zamówienia dla określonego rabatu.Paragony, raporty
bool IsDiscount([NotNull] this IDiscountItem discountItem)Określony rabat jest rabatem (nie dopłatą).Paragony, raporty
decimal GetFullSum([NotNull] this IOrder order)Pobierz pełną kwotę zamówienia przed rabatami/dopłatami i bez VAT nie uwzględnionego w cenie.Paragony, raporty
decimal GetResultSum([NotNull] this IOrder order)Pobierz kwotę zamówienia po rabatach/dopłatach i z VAT nie uwzględnionym w cenie.Raporty
decimal GetResultSumWithoutExcludedVat([NotNull] this IOrder order)Pobierz kwotę zamówienia po rabatach/dopłatach ALE bez VAT nie uwzględnionego w cenie.Raporty
decimal GetCategorizedDiscountsSum([NotNull] this IOrder order)Pobierz kwotę rabatów kategorii dla zamówienia.Paragony
decimal GetNonCategorizedDiscountsSum([NotNull] this IOrder order)Pobierz kwotę rabatów niekategoryzowanych dla zamówienia.Paragony
decimal GetVatSumExcludedFromPrice([NotNull] this IOrder order)Pobierz 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)Pobierz kwotę wszystkich zaliczek na zamówienie.Paragony
decimal GetChangeSum([NotNull] this IOrder order, decimal resultSum)Pobierz kwotę reszty na zamówienie. Całkowita kwota musi być przekazana do metody.Paragony
string GetNameOrEmpty([CanBeNull] this IUser user)Zwraca nazwę użytkownika, jeśli użytkownik nie jest pusty, w przeciwnym razie zwraca pusty wiersz.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 określona ilość 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 mieszanki. Gość musi być przekazany do metody.Paragony
DateTime GetPeriodBegin([NotNull] this ISettings settings, [NotNull] string name = "ReportInterval")Zwraca parametr „Początek okresu” typu „Okres” dla ustawień raportu. Wartość nazwy, która ma być przekazana, 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ść nazwy, która ma być przekazana, 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ść nazwy, która ma być przekazana, to nazwa parametru w Syrve Office.Raporty
string GetEnum([NotNull] this ISettings settings, [NotNull] string name)Zwraca wartość wyliczenia parametru „Wyliczenie”. Wartość nazwy, która ma być przekazana, to nazwa parametru w Syrve Office.Raporty
IEnumerable<IUser> GetCounteragents([NotNull] this ISettings settings, [NotNull] string name)Zwraca listę kontrahentów parametru „Kontrahenci”. Wartość nazwy, która ma być przekazana, to nazwa parametru w Syrve Office.Raporty, 4.2+
Anulowanie zadania drukowania w szablonie ------------------------------------------

Otrzymanie zadań drukowania raportów można anulować w szablonie, rzucając wyjątek OperationCanceledException z tekstem wyjątku. Wiadomość Uruchamianie szablonu zostało anulowane. Wiadomość: {0} zostanie zapisana w pliku print-templates.log, 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("Nieprawidłowy typ modelu '{0}'", Model.GetType()));
}
</doc>