Extending Receipt Template Capabilities from Plugins
In the V9Preview2 API, the ability to change the printed XDocument has been added through BeforeFormatDocumentHandler and AfterFormatDocumentHandler.
The markup itself can contain the <section> tag, which is used for logically dividing the document into blocks. The tag has a mandatory name attribute and an optional data attribute.
<section name="section_name" data="section_data" />
The name attribute defines a specific section. It can also be used to determine the type of document (guest check, payment receipt, service check, etc.)
The optional data attribute can contain additional information required by the plugin. For example, orderId can be passed.
The BeforeFormatDocument subscription is intended for adding additional information to the receipt that is not present in the data model but may exist in the plugin’s data model.
Or for executing business logic that depends on the plugin’s data model and is not available in razor templates and DocumentService.
Example 1.
Resto.Front.Api.SamplePlugin.PrintTester.cs
Example 2.
Add the car number to the invoice. The car number is absent in the ITemplateRootModel data model and in DocumentService. Let’s assume this information is available in some plugin. To implement the task through this plugin, we add the <section> tag in the invoice template.
<doc>
...
...
<section name="plate_number" data="@orderId">
...
...
</doc>
In the plugin code: here is an example of code that adds the car number to the section named “plate_number”.
public XDocument BeforeFormatDocument(XDocument doc)
{
XElement section = doc
.Elements("section")
.FirstOrDefault(e => e.Attribute("name") != null && (string)e.Attribute("name") == "plate_number");
if (section != null)
{
XElement newElement = new XElement("pair",
new XAttribute("left", "Car Number:"),
new XAttribute("right", "A001MR77")); //insert real data
section.AddAfterSelf(newElement);
}
return markup;
}
Example 3.
Configurable loyalty system in an external system for sending payment receipts and product checks via email instead of printing them on a printer.
We add <section> tags in the payment receipt and product check templates:
@inherits TemplateBase<IReceiptCheque>
@{
var order = Model.Order;
}
<doc>
<section name="ReceiptCheque" data="@order.Id">
...
</doc>
In the product check template:
@inherits TemplateBase<ICashMemoCheque>
@{
var order = Model.Order;
}
<doc>
<section name="CashMemo" data="@order.Id">
...
</doc>
In the plugin code:
public XDocument BeforeFormatDocument(XDocument doc)
{
XElement receiptChequeSection = doc
.Elements("section")
.FirstOrDefault(e => e.Attribute("name") != null && Attribute("name") == "ReceiptCheque");
if (receiptChequeSection != null)
{
//current document - payment receipt
orderId = receiptChequeSection.Attributes["orderId"]?.Value
if (orderId != null)
{
//Using plugin data model (customer settings)
var customerInfo = GetCustomerInfo(orderId);
if (customerSettings != null && customerSettings.SendElectronicReceiptOnly)
{
SendElectronicReceipt(customerInfo.UserId, doc); //Some plugin method to send electronic receipt
return new XElement("nodoc"); //do not print the document on the printer
}
}
}
//Similar code for product check
return doc;
}
In this example, the plugin received customer settings (not available in the razor model ITemplateRootModel), and if the SendElectronicReceiptOnly option is set, the entire document is replaced with <nodoc />.
When the document is finally sent to the printer, the <section> tags are ignored and do not affect the appearance of the document.