diff --git a/EpsonPrintService/EpsonPrintService.csproj b/EpsonPrintService/EpsonPrintService.csproj
index 6b5d985..3e07211 100644
--- a/EpsonPrintService/EpsonPrintService.csproj
+++ b/EpsonPrintService/EpsonPrintService.csproj
@@ -5,6 +5,7 @@
net8.0
enable
enable
+ 1.0.0
diff --git a/EpsonTemplatesTest/Templates/final-receipt.template b/EpsonTemplatesTest/Templates/final-receipt.template
index f0cfece..4ead507 100644
--- a/EpsonTemplatesTest/Templates/final-receipt.template
+++ b/EpsonTemplatesTest/Templates/final-receipt.template
@@ -4,24 +4,27 @@
#center# {Phone} #
@row bold
-|24|Rechnung Nr. {ReceiptNumber}|24,right|{DateTime:HH:mm dd.MM.yyyy}
+|24,left|Rechnung Nr. {ReceiptNumber}|24,right|{DateTime:HH:mm dd.MM.yyyy} #
+@endrow
Guests: {Guests}
-
-
@foreach item in Items
-{item.Quantity}x {item.Description} {right:{item.UnitPrice:F2} {item.TotalPrice:F2} {item.TaxCategory}}
+@row
+|30|{item.Quantity}x {item.Description}|18,right|{item.UnitPrice:F2} {item.TotalPrice:F2} {item.TaxCategory}
+@endrow
@end
+#right# ---------
-{right:---------}
#big,bold,center# Summe: {Total:F2} {Currency} #
@if TotalInAlternateCurrency
-{right:{TotalInAlternateCurrency:F2} {AlternateCurrency}}
+#right#{TotalInAlternateCurrency:F2} {AlternateCurrency}
@end
-#bold# {PaymentMethod} {right:{PaymentAmount:F2} {Currency}} #
+@row bold
+|24|{PaymentMethod}|25,right|{PaymentAmount:F2} {Currency}
+@endrow
@if TaxBreakdown.count > 0
MwSt % Brutto Netto MwSt
diff --git a/EpsonTest/Program.cs b/EpsonTest/Program.cs
index 278fc2a..7458e1d 100644
--- a/EpsonTest/Program.cs
+++ b/EpsonTest/Program.cs
@@ -1,688 +1,201 @@
-using Inspectron.Epson;
-using Inspectron.Epson.PrintServer.Printers.Utils;
+using EpsonTest;
+using Inspectron.Epson;
using Inspectron.Epson.PrintServer.Printers.Utils.FinalRecipe;
-using Inspectron.Epson.PrintServer.Printers.Utils.KitchenReceipt;
-using Inspectron.Epson.SOAP;
-using SixLabors.ImageSharp;
-using SixLabors.ImageSharp.PixelFormats;
-using System.Text;
-using System.Text.Json;
-using System.Xml.Linq;
using Inspectron.Epson.PrintServer.Printers.Utils.FinalReceipt;
+using Inspectron.Epson.PrintServer.Printers.Utils.InvoiceReceipt;
+using Inspectron.Epson.PrintServer.Printers.Utils.KitchenReceipt;
using Inspectron.Epson.PrintServer.Printers.Utils.OrderItems;
-using FinalReceipt = Inspectron.Epson.PrintServer.Printers.Utils.FinalRecipe.FinalReceipt;
+using System.Text.Json;
+
+// ============================================================================
+// FINAL RECEIPT - HTML PRINTER
+// ============================================================================
+//var receipt = TestHelpers.BuildSampleFinalReceipt();
+//var serializedReceipt = JsonSerializer.Serialize(receipt, new JsonSerializerOptions { WriteIndented = true });
+
+//var converter = new FinalReceiptConverter(lineWidth: 48, bigFontLineWidth: 24);
+//var printCommands = converter.Convert(serializedReceipt);
+
+//TestHelpers.PrintCommandsToConsole(printCommands);
+
+//var printer = await TestHelpers.CreateHtmlPrinterAsync();
+//await TestHelpers.PrintCommandsToHtmlPrinterAsync(
+// printer,
+// printCommands,
+// logoPath: "ristorante-klinglers.ch-logo_white_bg.png");
-//SoapEpsonPrinter printer = new SoapEpsonPrinter("localhost:8888");
-//var print = new SoapEpsonPrint();
-//print
-// .AddText("123")
-// .AddFeed()
-// .AddFeed()
-// .AddCut(SoapEpsonPrint.CUT_FEED);
+// ============================================================================
+// FINAL RECEIPT - EPSON PRINTER
+// ============================================================================
+//var receipt = TestHelpers.BuildSampleFinalReceipt();
+//var serializedReceipt = JsonSerializer.Serialize(receipt, new JsonSerializerOptions { WriteIndented = true });
-//var task = await printer.Send(print);
-//var status = await printer.GetStatus(print);
+//var converter = new FinalReceiptConverter(lineWidth: 48, bigFontLineWidth: 24);
+//var printCommands = converter.Convert(serializedReceipt);
-//HttpClient httpClient = new HttpClient(new HttpClientHandler
-//{
-// ServerCertificateCustomValidationCallback = (message, cert, chain, errors) => true
-//});
+//TestHelpers.PrintCommandsToConsole(printCommands);
-//var requestText = @"
-//
-//
-// Hello, World!
-//
-//
-//";
+//var printer = await TestHelpers.CreateEpsonPrinterAsync();
+//await TestHelpers.PrintCommandsToEpsonPrinterAsync(printer, printCommands);
-//var request = new HttpRequestMessage(HttpMethod.Post,
-// "https://localhost:8888/cgi-bin/epos/service.cgi?devid=local_printer&timeout=10000");
-//var response = httpClient.Send(request);
-//var responseText = await response.Content.ReadAsStringAsync();
-//Console.WriteLine(responseText);
-
-
-
-//var printer = new EpsonPrinter();
-//await printer.ConnectAsync("127.0.0.1",8888);
-//for (int i = 0; i < 20; i++)
-//{
-// await printer.PrintTextAsync("Hello\n");
-//}
-
-//await printer.FeedLinesAsync(5);
-//await printer.CutAsync();
-
-//var status = await printer.GetPrinterStatusAsync();
-//Console.ReadLine();
-
-
-var receipt = new FinalReceipt
-{
- CompanyName = "Klingler Gastro AG",
- Address1 = "Münzplatz 3",
- Address2 = "CH-8001 Zürich",
- Phone = "043 321 22 22",
- ReceiptNumber = "1-81-202",
- DateTime = new DateTime(2025, 12, 16, 14, 58, 0),
- Guests = 2,
- Total = 160.00m,
- Currency = "CHF",
- TotalInAlternateCurrency = 172.80m,
- AlternateCurrency = "EUR",
- PaymentMethod = "MASTER",
- PaymentAmount = 160.00m,
- WaiterName = "Yves",
- Terminal = "Hauptkasse ZH",
- TableNumber = "12",
- VatNumber = "CHE-449.635.880 MWST",
- ThankYouMessage = "Das Team bedankt sich herzlich für Ihren",
- GoodbyeMessageLine1 = "Besuch.",
- GoodbyeMessageLine2 = "Auf Wiedersehen.",
- SplitPayments = new List
- {
- new SplitPaymentInfo { PaymentMethod = "Cash", Amount = 50.00m, Currency = "CHF"},
- new SplitPaymentInfo { PaymentMethod = "Card", Amount = 110.00m, Currency = "CHF" }
- },
- TerminalReceipts = new List
- {
- new PaymentTerminalReceipt
- {
- ReceiptType = "*** Kundenbeleg ***",
- BookingType = "Buchung",
- PaymentSystem = "TWINT",
- TransactionNumber = "XXXXXXXXXXXXXXX1494",
- TransactionDateTime = new DateTime(2025, 11, 11, 12, 34, 49),
- TerminalId = "31108834",
- AID = "A0000015749E",
- TransactionSeqCount = "6127",
- TransactionRefNo = "99036644599",
- AuthCode = "0d3396",
- AcquirerId = "2",
- EftAmount = 67.00m,
- TipAmount = 6.70m,
- TotalEftAmount = 73.70m,
- Currency = "CHF"
- },
- new PaymentTerminalReceipt
- {
- ReceiptType = "*** Kundenbeleg ***",
- BookingType = "Buchung",
- PaymentSystem = "MASTER",
- TransactionNumber = "XXXXXXXXXXXXXXX2587",
- TransactionDateTime = new DateTime(2025, 11, 11, 12, 36, 12),
- TerminalId = "31108834",
- AID = "A0000000041010",
- TransactionSeqCount = "6128",
- TransactionRefNo = "99036644600",
- AuthCode = "1a4b2c",
- AcquirerId = "1",
- EftAmount = 93.00m,
- TipAmount = 0.00m,
- TotalEftAmount = 93.00m,
- Currency = "CHF"
- }
- }
-};
-
-// Add items
-receipt.Items.Add(new ReceiptItem
-{
- Quantity = 1,
- Description = "San Pellegrino 50cl",
- UnitPrice = 6.50m,
- TotalPrice = 6.50m,
- TaxCategory = "A"
-});
-
-receipt.Items.Add(new ReceiptItem
-{
- Quantity = 1,
- Description = "Panna 50cl",
- UnitPrice = 6.50m,
- TotalPrice = 6.50m,
- TaxCategory = "A"
-});
-
-receipt.Items.Add(new ReceiptItem
-{
- Quantity = 1,
- Description = "Granini Tomatensaft",
- UnitPrice = 5.50m,
- TotalPrice = 5.50m,
- TaxCategory = "A"
-});
-
-receipt.Items.Add(new ReceiptItem
-{
- Quantity = 2,
- Description = "Business Lunch Menu Seco",
- UnitPrice = 44.00m,
- TotalPrice = 88.00m,
- TaxCategory = "A"
-});
-
-receipt.Items.Add(new ReceiptItem
-{
- Quantity = 2,
- Description = "Brunello di Montalcino 1",
- UnitPrice = 16.00m,
- TotalPrice = 32.00m,
- TaxCategory = "A"
-});
-
-receipt.Items.Add(new ReceiptItem
-{
- Quantity = 2,
- Description = "Espresso",
- UnitPrice = 5.50m,
- TotalPrice = 11.00m,
- TaxCategory = "A"
-});
-
-receipt.Items.Add(new ReceiptItem
-{
- Quantity = 1,
- Description = "Tip",
- UnitPrice = 10.50m,
- TotalPrice = 10.50m,
- TaxCategory = "B"
-});
-
-// Add tax breakdown
-receipt.TaxBreakdown.Add(new TaxInfo
-{
- Category = "A",
- Rate = 8.1m,
- Gross = 149.50m,
- Net = 138.30m,
- TaxAmount = 11.20m,
- Currency = "CHF"
-});
-
-receipt.TaxBreakdown.Add(new TaxInfo
-{
- Category = "B",
- Rate = 0m,
- Gross = 10.50m,
- Net = 10.50m,
- TaxAmount = 0.00m,
- Currency = "CHF"
-});
-
+// ============================================================================
+// INVOICE RECEIPT - HTML PRINTER
+// ============================================================================
+var receipt = TestHelpers.BuildSampleInvoiceReceipt();
var serializedReceipt = JsonSerializer.Serialize(receipt, new JsonSerializerOptions { WriteIndented = true });
-var deserializedReceipt = JsonSerializer.Deserialize(serializedReceipt);
-// Convert to print commands
-var converter = new FinalReceiptConverter(lineWidth: 48, bigFontLineWidth: 24);
+
+var converter = new InvoiceReceiptConverter(lineWidth: 48, bigFontLineWidth: 24);
var printCommands = converter.Convert(serializedReceipt);
+TestHelpers.PrintCommandsToConsole(printCommands);
+
+var printer = await TestHelpers.CreateHtmlPrinterAsync();
+await TestHelpers.PrintCommandsToHtmlPrinterAsync(
+ printer,
+ printCommands,
+ logoPath: "ristorante-klinglers.ch-logo_white_bg.png");
+// ============================================================================
+// INVOICE RECEIPT - EPSON PRINTER
+// ============================================================================
+//var receipt = TestHelpers.BuildSampleInvoiceReceipt();
+//var serializedReceipt = JsonSerializer.Serialize(receipt, new JsonSerializerOptions { WriteIndented = true });
-// Print the commands
-Console.WriteLine("=== PRINT COMMANDS ===\n");
-var printer = new HtmlPrinter(@".\test.html", paperWidth: 384);
-await printer.ConnectAsync("");
-await printer.SetAbsolutePrintPosition(42);
-await printer.LoadImageAsync("ristorante-klinglers.ch-logo_white_bg.png", 300);
-await printer.PrintLoadedImage();
-await printer.SetAbsolutePrintPosition(0);
-await Task.Delay(200);
-//await printer.FeedLinesAsync(1);
-await printer.SetCustomLineSpacing(22);
-foreach (var command in printCommands)
-{
- string attributes = "";
- if (command.IsBig) attributes += "[BIG] ";
- if (command.IsBold) attributes += "[BOLD] ";
+//var converter = new InvoiceReceiptConverter(lineWidth: 48, bigFontLineWidth: 24);
+//var printCommands = converter.Convert(serializedReceipt);
- Console.WriteLine($"{attributes}{command.Text}");
+//TestHelpers.PrintCommandsToConsole(printCommands);
- if (command.IsBig)
- {
- await printer.SetFontSizeAsync(2, 1);
- }
- else
- {
- await printer.SetFontSizeAsync(1, 1);
- }
- //await Task.Delay(200);
-
- await printer.SetEmphasized(command.IsBold);
- //await Task.Delay(200);
-
- await printer.PrintTextAsync(command.Text + "\n");
- //await Task.Delay(200);
-
-}
+//var printer = await TestHelpers.CreateEpsonPrinterAsync();
+//await TestHelpers.PrintCommandsToEpsonPrinterAsync(printer, printCommands);
-//var receipt = new KitchenReceipt
-//{
-// Title = "Warme Küche",
-// TransactionDateTime = new DateTime(2025, 10, 23, 12, 18, 0),
-// ReceiptNumber = "132018166",
-// WaiterName = "Mariano Amato",
-// WaiterId = "32 (VK Restaurant)",
-// TableNumber = 22
-//};
-
-//// Add dishes (this section can be empty if no dishes were ordered)
-
-//receipt.Gangs.Add(new Gang(1, "Gang"));
-//receipt.Gangs.Add(new Gang(2, "Gang"));
-
-//receipt.Gangs[0].Dishes.Add(new Dish(1, "Avocado Sashimi")
-//{
-// Modifications = new DishModifications
-// {
-// Removed = new List { "Wasabi" },
-// Added = new List { "Extra Ginger" }
-// },
-// Comment = "No soy sauce"
-//});
-//receipt.Gangs[0].Dishes.Add(new Dish(1, "Baby Spinach Salad with Truffl"));
-//receipt.Gangs[0].Dishes.Add(new Dish(1, "Beef Tataki")
-//{
-// Modifications = new DishModifications
-// {
-// Removed = new List { "Onion" },
-// Added = new List { "Extra Sauce" }
-// },
-// Comment = "Medium rare"
-//});
-//receipt.Gangs[0].Dishes.Add(new Dish(1, "Salmon Taco")
-//{
-// Modifications = new DishModifications
-// {
-// Added = new List { "Extra Lime" }
-// }
-//});
-
-
-//receipt.Gangs[1].Dishes.Add(new Dish(1, "Avocado Sashimi"));
-//receipt.Gangs[1].Dishes.Add(new Dish(1, "Baby Spinach Salad with Truffl"));
-//receipt.Gangs[1].Dishes.Add(new Dish(1, "Beef Tataki"));
-//receipt.Gangs[1].Dishes.Add(new Dish(1, "Salmon Taco"));
-
-//receipt.Dishes.Add(new Dish(1, "Avocado Sashimi"));
-//receipt.Dishes.Add(new Dish(1, "Baby Spinach Salad with Truffl"));
-//receipt.Dishes.Add(new Dish(1, "Beef Tataki"));
-//receipt.Dishes.Add(new Dish(1, "Salmon Taco"));
-
-
-//// Add additional info
-
+// ============================================================================
+// KITCHEN RECEIPT - HTML PRINTER
+// ============================================================================
+//var receipt = TestHelpers.BuildSampleKitchenReceipt();
//var serializedReceipt = JsonSerializer.Serialize(receipt, new JsonSerializerOptions { WriteIndented = true });
//var deserializedReceipt = JsonSerializer.Deserialize(serializedReceipt);
-//KitchenReceiptConverter converter = new KitchenReceiptConverter(bigLineWidth: 20, lineWidth: 33);
+
+//var converter = new KitchenReceiptConverter(bigLineWidth: 20, lineWidth: 33);
//var printCommands = converter.ConvertToPrintCommands(deserializedReceipt);
-//Console.WriteLine("=== PRINT COMMANDS ===\n");
-//var printer = new HtmlPrinter(@".\test.html", paperWidth: 258);
-//await printer.ConnectAsync("");
-//await Task.Delay(200);
-//await printer.FeedLinesAsync(1);
-//await printer.SetCustomLineSpacing(22);
-//foreach (var command in printCommands)
-//{
-// string attributes = "";
-// if (command.IsBig) attributes += "[BIG] ";
-// if (command.IsBold) attributes += "[BOLD] ";
-// if (command.IsRed) attributes += "[RED] ";
+//TestHelpers.PrintCommandsToConsole(printCommands);
-// Console.WriteLine($"{attributes}{command.Text}");
-
-// if (command.IsBig)
-// {
-// await printer.SetFontSizeAsync(2, 1);
-// }
-// else
-// {
-// await printer.SetFontSizeAsync(1, 1);
-// }
-
-// await printer.SetRedColor(command.IsRed);
-
-// //await Task.Delay(200);
-
-// await printer.SetEmphasized(command.IsBold);
-// //await Task.Delay(200);
-
-// await printer.PrintTextAsync(command.Text + "\n");
-// //await Task.Delay(200);
-
-//}
+//var printer = await TestHelpers.CreateHtmlPrinterAsync(
+// path: @".\kitchen_test.html",
+// paperWidth: TestHelpers.KitchenPaperWidth);
+//await TestHelpers.PrintKitchenCommandsToHtmlPrinterAsync(printer, printCommands);
-//var receipt = new KitchenReceipt
-//{
-// Title = "Warme Küche",
-// TransactionDateTime = new DateTime(2025, 10, 23, 12, 18, 0),
-// ReceiptNumber = "132018166",
-// WaiterName = "Mariano Amato",
-// WaiterId = "32 (VK Restaurant)",
-// TableNumber = "22",
-// SpecialInstruction = "Next dish"
-//};
-
-//// Add dishes (this section can be empty if no dishes were ordered)
-
-//receipt.Gangs.Add(new Gang(2, "Gang"));
-
-//receipt.Gangs[0].Dishes.Add(new Dish(1, "Avocado Sashimi")
-//{
-// Modifications = new DishModifications
-// {
-// Removed = new List { "Wasabi" },
-// Added = new List { "Extra Ginger" }
-// },
-// Comment = "No soy sauce"
-//});
-//receipt.Gangs[0].Dishes.Add(new Dish(1, "Baby Spinach Salad with Truffl"));
-//receipt.Gangs[0].Dishes.Add(new Dish(1, "Beef Tataki")
-//{
-// Modifications = new DishModifications
-// {
-// Removed = new List { "Onion" },
-// Added = new List { "Extra Sauce" }
-// },
-// Comment = "Medium rare"
-//});
-//receipt.Gangs[0].Dishes.Add(new Dish(1, "Salmon Taco")
-//{
-// Modifications = new DishModifications
-// {
-// Added = new List { "Extra Lime" }
-// }
-//});
-
-//// Add additional info
-
+// ============================================================================
+// KITCHEN RECEIPT (NEXT DISH) - HTML PRINTER
+// ============================================================================
+//var receipt = TestHelpers.BuildSampleKitchenReceiptNextDish();
//var serializedReceipt = JsonSerializer.Serialize(receipt, new JsonSerializerOptions { WriteIndented = true });
//var deserializedReceipt = JsonSerializer.Deserialize(serializedReceipt);
-//KitchenReceiptConverter converter = new KitchenReceiptConverter(bigLineWidth: 18, lineWidth: 33);
+
+//var converter = new KitchenReceiptConverter(bigLineWidth: 18, lineWidth: 33);
//var printCommands = converter.ConvertToPrintCommands(deserializedReceipt);
-//Console.WriteLine("=== PRINT COMMANDS ===\n");
-////var printer = new HtmlPrinter(@".\test.html", paperWidth: 258);
-////await printer.ConnectAsync("");
-//bool useDelay=true;
-//var printer = new EpsonPrinter();
-//await printer.ConnectAsync("127.0.0.1", 8888);
-//if (useDelay)await Task.Delay(200);
-//await printer.FeedLinesAsync(1);
-//await printer.SetCustomLineSpacing(22);
-//foreach (var command in printCommands)
-//{
-// string attributes = "";
-// if (command.IsBig) attributes += "[BIG] ";
-// if (command.IsBold) attributes += "[BOLD] ";
-// if (command.IsRed) attributes += "[RED] ";
+//TestHelpers.PrintCommandsToConsole(printCommands);
-// Console.WriteLine($"{attributes}{command.Text}");
-// await printer.SetBiggerFontTM220(command.IsBig, command.IsTall| command.IsBig, secondaryFont: false);
+//var printer = await TestHelpers.CreateHtmlPrinterAsync(
+// path: @".\kitchen_next_dish.html",
+// paperWidth: TestHelpers.KitchenPaperWidth);
+//await TestHelpers.PrintKitchenCommandsToHtmlPrinterAsync(printer, printCommands);
+// ============================================================================
+// KITCHEN RECEIPT - EPSON PRINTER
+// ============================================================================
+//var receipt = TestHelpers.BuildSampleKitchenReceiptNextDish();
+//var serializedReceipt = JsonSerializer.Serialize(receipt, new JsonSerializerOptions { WriteIndented = true });
+//var deserializedReceipt = JsonSerializer.Deserialize(serializedReceipt);
-// if (useDelay) await Task.Delay(200);
+//var converter = new KitchenReceiptConverter(bigLineWidth: 18, lineWidth: 33);
+//var printCommands = converter.ConvertToPrintCommands(deserializedReceipt);
-// await printer.SetRedColor(command.IsRed);
+//TestHelpers.PrintCommandsToConsole(printCommands);
-// if (useDelay) await Task.Delay(200);
+//var printer = await TestHelpers.CreateEpsonPrinterAsync(paperWidth:TestHelpers.KitchenPaperWidth);
+//await TestHelpers.PrintCommandsToEpsonPrinterAsync(printer, printCommands, useDelay: true);
-// await printer.SetEmphasized(command.IsBold);
-// if (useDelay) await Task.Delay(200);
-// await printer.PrintTextAsync(command.Text + "\n");
-// if (useDelay) await Task.Delay(200);
+// ============================================================================
+// ORDER ITEMS RECEIPT - HTML PRINTER
+// ============================================================================
+//var receipt = TestHelpers.BuildSampleOrderItemsReceipt();
+//var serializedReceipt = JsonSerializer.Serialize(receipt, new JsonSerializerOptions { WriteIndented = true });
+//Console.WriteLine(serializedReceipt);
+//var deserializedReceipt = JsonSerializer.Deserialize(serializedReceipt);
-//}
+//var converter = new ReceiptConverter(lineWidth: 50, bigFontLineWidth: 21);
+//var printCommands = converter.ConvertToPrintCommands(deserializedReceipt);
+//TestHelpers.PrintCommandsToConsole(printCommands);
+
+//var printer = await TestHelpers.CreateHtmlPrinterAsync(path: @".\order_items.html");
+//await TestHelpers.PrintCommandsToHtmlPrinterAsync(printer, printCommands);
+
+
+// ============================================================================
+// BASIC PRINTER STATUS CHECK
+// ============================================================================
+//var printer = await TestHelpers.CreateEpsonPrinterAsync();
+//var status = await printer.GetPrinterStatusAsync();
+//Console.WriteLine($"Printer Status: {status}");
+//var paperStatus = await printer.GetPaperSensorStatusAsync();
+//Console.WriteLine($"Paper Sensor Status: {paperStatus}");
+
+
+// ============================================================================
+// SIMPLE TEXT PRINT TEST
+// ============================================================================
+//var printer = await TestHelpers.CreateEpsonPrinterAsync();
+//await printer.InitAsync();
+//await printer.PrintTextAsync("Hello, World!\n");
//await printer.FeedLinesAsync(5);
-//if (useDelay) await Task.Delay(200*5);
//await printer.CutAsync();
-//await printer.SetDefaultLineSpacing();
-//await printer.PrintTextAsync(
-// "1x San Pellegrino 50cl 6.50 6.50 A\n1x Panna 50cl 6.50 6.50 A");
-//// Order Items Receipt Test
-//var orderItemsReceipt = new OrderItemsReceipt
-//{
-// OrderNumber = "1",
-// QRInfo = "Margherita Pizza Classic longer text",
-// DateTime = new DateTime(2026, 1, 14, 14, 35, 47),
-// ClientNotes = "Some main note",
-// Items = new List
-// {
-// new OrderItem
-// {
-// Number = 1,
-// Name = "pappara",
-// Quantity = 1,
-// SubItems = new List { "pizza", "cola" },
-// Comment = "Cola zero please"
-// },
-// new OrderItem
-// {
-// Number = 2,
-// Name = "Classic Beef Burger",
-// Quantity = 1,
-// Modifications = new ItemModifications
-// {
-// Removed = new List { "Onion" },
-// Added = new List { "butter" }
-// },
-// Comment = "Medium rare please"
-// },
-// new OrderItem
-// {
-// Number = 3,
-// Name = "Margherita Pizza Classic",
-// Quantity = 2,
-// Size = "L"
-// }
-// }
-//};
-
-//var serializedOrderItems = JsonSerializer.Serialize(orderItemsReceipt, new JsonSerializerOptions { WriteIndented = true });
-//Console.WriteLine(serializedOrderItems);
-//var deserializedOrderItems = JsonSerializer.Deserialize(serializedOrderItems);
-
-//var orderItemsConverter = new Inspectron.Epson.PrintServer.Printers.Utils.OrderItems.ReceiptConverter(lineWidth: 50, bigFontLineWidth: 21);
-//var printCommands = orderItemsConverter.ConvertToPrintCommands(deserializedOrderItems);
-
-//Console.WriteLine("=== PRINT COMMANDS ===\n");
-//var printer = new HtmlPrinter(@".\order_items.html", paperWidth: 384);
-//await printer.ConnectAsync("");
-//await Task.Delay(200);
-////await printer.FeedLinesAsync(1);
-//await printer.SetCustomLineSpacing(22);
-//foreach (var command in printCommands)
-//{
-// string attributes = "";
-// if (command.IsBig) attributes += "[BIG] ";
-// if (command.IsBold) attributes += "[BOLD] ";
-
-// Console.WriteLine($"{attributes}{command.Text}");
-
-// if (command.IsBig)
-// {
-// await printer.SetFontSizeAsync(2, 1);
-// }
-// else
-// {
-// await printer.SetFontSizeAsync(1, 1);
-// }
-// //await Task.Delay(200);
-
-// await printer.SetEmphasized(command.IsBold);
-// //await Task.Delay(200);
-
-// await printer.PrintTextAsync(command.Text + "\n");
-// //await Task.Delay(200);
-
-//}
-
-
-
-
-
-
-
-// clear printer buffer
-//await printer.SendRawCommandAsync([0x10, 0x14, 0x08, 0x01, 0x03, 0x14, 0x01, 0x06, 0x02, 0x08]);
-//
-//for (int i = 0; i < 10; i++)
-//{
-// await printer.SendRawCommandAsync(EpsonCommands.LineFeed);
-// await Task.Delay(200);
-//}
-
-//await printer.InitAsync();
-//await Task.Delay(200);
-
-//KitchenReceiptPrinter krp = new KitchenReceiptPrinter(33);
-//var receipt = new TranslatedKitchenReceipt(
-// Location: "Warme Küche",
-// Date: "23-Okt-25 12:18 Nr.:13201B166",
-// Owner: "Mariano Amato\n32 (VK Restaurant)",
-// Tisch: "22",
-// items: new List
-// {
-// new KitchenGang("1. Gang"),
-// new KitchenProduct(1, "Avocado Sashimi"),
-// new KitchenProduct(1, "Baby Spinach Salad with Truffl"),
-// new KitchenGang("2. Gang"),
-// new KitchenProduct(1, "Beef Tataki"),
-// new KitchenProduct(1, "Salmon Taco")
-// }
-//);
-
-//var test = JsonSerializer.Serialize(receipt, new JsonSerializerOptions() { WriteIndented = true });
-//Console.WriteLine(test);
-
-////// Create printer with 42 character line width (default)
-//var commands = krp.ConvertToCommands(receipt);
-
-//foreach (PrintCommand command in commands)
-//{
-// await printer.SetBiggerFontTM220(command.IsBig);
-// await Task.Delay(200);
-// await printer.SetRedColor(command.IsRed);
-// await Task.Delay(200);
-// await printer.SetEmphasized(command.IsBold);
-// await Task.Delay(200);
-// await printer.PrintTextAsync(command.Text + "\n");
-// await Task.Delay(200);
-//}
-
-
-
-//await printer.SetBiggerFontTM220(true);
-// 24
-//await printer.SetFontSizeAsync(2,2);
-//await Task.Delay(200);
-//await printer.SelectFont(EpsonCommands.PrinterFont.A);
-//await Task.Delay(200);
-//await printer.PrintTextAsync("HHHH_HHHH_HHHH_HHHH_HHHH_HHHH_HHHH_\n");
-//await Task.Delay(200);
-
-//// 48
-//await printer.SetFontSizeAsync(1, 1);
-//await Task.Delay(200);
-//await printer.SelectFont(EpsonCommands.PrinterFont.A);
-//await Task.Delay(200);
-//await printer.PrintTextAsync("HHHH_HHHH_HHHH_HHHH_HHHH_HHHH_HHHH_HHHH_HHHH_HHHH_HHHH_HHHH_\n");
-//await Task.Delay(200);
-//await printer.SetBiggerFontTM220(false);
-//await Task.Delay(200);
-//await printer.SelectFont(EpsonCommands.PrinterFont.A);
-//await Task.Delay(200);
-//await printer.PrintTextAsync("HHHH_HHHH_HHHH_HHHH_HHHH_HHHH_HHHH_\n");
-//await Task.Delay(200);
-
-
-
-//await printer.FeedLinesAsync(10);
-//await Task.Delay(1000);
-
-
-//await printer.SetQuadrupleMode(false);
-//await printer.PrintImageBitModeAsync("test.png",maxWidth:24);
+// ============================================================================
+// IMAGE PRINT TEST
+// ============================================================================
+//var printer = await TestHelpers.CreateEpsonPrinterAsync();
//await printer.LoadImageAsync("test.png", 100);
//await printer.PrintLoadedImage();
-
-//for (int i = 1; i < 5; i++)
-//{
-// List lineBytes = new List();
-
-// for (int j = 0; j < i; j++)
-// {
-// lineBytes.AddRange([0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,]);
-// lineBytes.AddRange([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,]);
-
-// }
-// var bytes = EpsonCommands.CreateBitImageCommand(EpsonCommands.BitImageMode.SingleDensity8Dot,
-// lineBytes.ToArray(), i*16);
-// await printer.SendRawCommandAsync(bytes);
-// await printer.SendRawCommandAsync(EpsonCommands.LineFeed);
-//}
-
-
-//await printer.SetAbsolutePrintPosition(50);
-//await printer.SetFontSizeAsync(2, 2);
-//await printer.PrintTextAsync("Hello!");
-//await printer.SendRawCommandAsync(EpsonCommands.LineFeed);
-//await printer.FeedLinesAsync(7);
-
-//await printer.PrintImageBitModeAsync("test.png");
-//var bytes = EpsonCommands.CreateBitImageCommand(EpsonCommands.BitImageMode.SingleDensity8Dot,
-// [
-// 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-// 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
-// 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ], 32);
-//await printer.SendRawCommandAsync(bytes);
-//await Task.Delay(2000);
-//await printer.PrintBuffer();
-
-//var printer = new EpsonPrinter();
-//await printer.ConnectAsync("127.0.0.1", 8888);
-//await printer.InitAsync();
-
-//await printer.PrintTextAsync("Hello!");
//await printer.FeedLinesAsync(5);
-
//await printer.CutAsync();
+// ============================================================================
+// FONT SIZE TEST
+// ============================================================================
+//var printer = await TestHelpers.CreateEpsonPrinterAsync();
+//await printer.InitAsync();
-////await CheckStatus(20);
+//// Double size (24 chars per line)
+//await printer.SetFontSizeAsync(2, 2);
+//await printer.SelectFont(EpsonCommands.PrinterFont.A);
+//await printer.PrintTextAsync("HHHH_HHHH_HHHH_HHHH_HHHH_HHHH_HHHH_\n");
-//Task CheckStatus(int iterations)
-//{
-// return Task.Run(async () =>
-// {
-// for (int i = 0; i < iterations; i++)
-// {
-// var status = await printer.GetPrinterStatusAsync();
-// Console.WriteLine($"Printer Status: {status}");
-// var paperStatus = await printer.GetPaperSensorStatusAsync();
-// Console.WriteLine($"Paper Sensor Status: {paperStatus}");
-// await Task.Delay(100);
-// }
-// });
+//// Normal size (48 chars per line)
+//await printer.SetFontSizeAsync(1, 1);
+//await printer.SelectFont(EpsonCommands.PrinterFont.A);
+//await printer.PrintTextAsync("HHHH_HHHH_HHHH_HHHH_HHHH_HHHH_HHHH_HHHH_HHHH_HHHH_HHHH_HHHH_\n");
-//}
+//await printer.FeedLinesAsync(5);
+//await printer.CutAsync();
-//SoapEpsonPrinter printer = new SoapEpsonPrinter("10.0.20.11");
-//SoapEpsonPrinter printer = new SoapEpsonPrinter("localhost:8888");
+// ============================================================================
+// SOAP PRINTER TEST
+// ============================================================================
+//var printer = new SoapEpsonPrinter("localhost:8888");
//var print = new SoapEpsonPrint();
//print
// .AddTextAlign(SoapEpsonPrint.ALIGN_CENTER)
@@ -695,5 +208,4 @@ foreach (var command in printCommands)
//var task = await printer.Send(print);
//var status = await printer.GetStatus(print);
-
-//Console.WriteLine($"Printer Status: {status}");
\ No newline at end of file
+//Console.WriteLine($"Printer Status: {status}");
diff --git a/EpsonTest/TestHelpers.cs b/EpsonTest/TestHelpers.cs
new file mode 100644
index 0000000..028d37b
--- /dev/null
+++ b/EpsonTest/TestHelpers.cs
@@ -0,0 +1,520 @@
+using Inspectron.Epson;
+using Inspectron.Epson.PrintServer.Printers.Utils;
+using Inspectron.Epson.PrintServer.Printers.Utils.FinalRecipe;
+using Inspectron.Epson.PrintServer.Printers.Utils.InvoiceReceipt;
+using Inspectron.Epson.PrintServer.Printers.Utils.KitchenReceipt;
+using Inspectron.Epson.PrintServer.Printers.Utils.OrderItems;
+
+namespace EpsonTest;
+
+public static class TestHelpers
+{
+ // Default connection settings
+ public const string DefaultEpsonIp = "127.0.0.1";
+ public const int DefaultEpsonPort = 8888;
+ public const string DefaultHtmlPath = @".\test.html";
+ public const int DefaultPaperWidth = 384;
+ public const int KitchenPaperWidth = 258;
+
+ #region Printer Creation
+
+ public static async Task CreateEpsonPrinterAsync(
+ string ip = DefaultEpsonIp,
+ int port = DefaultEpsonPort, int paperWidth = DefaultPaperWidth)
+ {
+ var printer = new EpsonPrinter();
+ await printer.ConnectAsync(ip, port);
+ return printer;
+ }
+
+ public static async Task CreateHtmlPrinterAsync(
+ string path = DefaultHtmlPath,
+ int paperWidth = DefaultPaperWidth)
+ {
+ var printer = new HtmlPrinter(path, paperWidth: paperWidth);
+ await printer.ConnectAsync("");
+ return printer;
+ }
+
+ #endregion
+
+ #region Receipt Builders
+
+ public static FinalReceipt BuildSampleFinalReceipt()
+ {
+ var receipt = new FinalReceipt
+ {
+ CompanyName = "Klingler Gastro AG",
+ Address1 = "Münzplatz 3",
+ Address2 = "CH-8001 Zürich",
+ Phone = "043 321 22 22",
+ ReceiptNumber = "1-81-202",
+ DateTime = new DateTime(2025, 12, 16, 14, 58, 0),
+ Guests = 2,
+ Total = 160.00m,
+ Currency = "CHF",
+ TotalInAlternateCurrency = 172.80m,
+ AlternateCurrency = "EUR",
+ PaymentMethod = "MASTER",
+ PaymentAmount = 160.00m,
+ WaiterName = "Yves",
+ Terminal = "Hauptkasse ZH",
+ TableNumber = "12",
+ VatNumber = "CHE-449.635.880 MWST",
+ ThankYouMessage = "Das Team bedankt sich herzlich für Ihren",
+ GoodbyeMessageLine1 = "Besuch.",
+ GoodbyeMessageLine2 = "Auf Wiedersehen.",
+ SplitPayments = new List
+ {
+ new() { PaymentMethod = "Cash", Amount = 50.00m, Currency = "CHF" },
+ new() { PaymentMethod = "Card", Amount = 110.00m, Currency = "CHF" }
+ },
+ TerminalReceipts = new List
+ {
+ new()
+ {
+ ReceiptType = "*** Kundenbeleg ***",
+ BookingType = "Buchung",
+ PaymentSystem = "TWINT",
+ TransactionNumber = "XXXXXXXXXXXXXXX1494",
+ TransactionDateTime = new DateTime(2025, 11, 11, 12, 34, 49),
+ TerminalId = "31108834",
+ AID = "A0000015749E",
+ TransactionSeqCount = "6127",
+ TransactionRefNo = "99036644599",
+ AuthCode = "0d3396",
+ AcquirerId = "2",
+ EftAmount = 67.00m,
+ TipAmount = 6.70m,
+ TotalEftAmount = 73.70m,
+ Currency = "CHF"
+ },
+ new()
+ {
+ ReceiptType = "*** Kundenbeleg ***",
+ BookingType = "Buchung",
+ PaymentSystem = "MASTER",
+ TransactionNumber = "XXXXXXXXXXXXXXX2587",
+ TransactionDateTime = new DateTime(2025, 11, 11, 12, 36, 12),
+ TerminalId = "31108834",
+ AID = "A0000000041010",
+ TransactionSeqCount = "6128",
+ TransactionRefNo = "99036644600",
+ AuthCode = "1a4b2c",
+ AcquirerId = "1",
+ EftAmount = 93.00m,
+ TipAmount = 0.00m,
+ TotalEftAmount = 93.00m,
+ Currency = "CHF"
+ }
+ }
+ };
+
+ // Add items
+ receipt.Items.Add(new FinalReceiptItem
+ {
+ Quantity = 1,
+ Description = "San Pellegrino 50cl",
+ UnitPrice = 6.50m,
+ TotalPrice = 6.50m,
+ TaxCategory = "A"
+ });
+
+ receipt.Items.Add(new FinalReceiptItem
+ {
+ Quantity = 1,
+ Description = "Panna 50cl",
+ UnitPrice = 6.50m,
+ TotalPrice = 6.50m,
+ TaxCategory = "A"
+ });
+
+ receipt.Items.Add(new FinalReceiptItem
+ {
+ Quantity = 1,
+ Description = "Granini Tomatensaft",
+ UnitPrice = 5.50m,
+ TotalPrice = 5.50m,
+ TaxCategory = "A"
+ });
+
+ receipt.Items.Add(new FinalReceiptItem
+ {
+ Quantity = 2,
+ Description = "Business Lunch Menu Seco",
+ UnitPrice = 44.00m,
+ TotalPrice = 88.00m,
+ TaxCategory = "A"
+ });
+
+ receipt.Items.Add(new FinalReceiptItem
+ {
+ Quantity = 2,
+ Description = "Brunello di Montalcino 1",
+ UnitPrice = 16.00m,
+ TotalPrice = 32.00m,
+ TaxCategory = "A"
+ });
+
+ receipt.Items.Add(new FinalReceiptItem
+ {
+ Quantity = 2,
+ Description = "Espresso",
+ UnitPrice = 5.50m,
+ TotalPrice = 11.00m,
+ TaxCategory = "A"
+ });
+
+ receipt.Items.Add(new FinalReceiptItem
+ {
+ Quantity = 1,
+ Description = "Tip",
+ UnitPrice = 10.50m,
+ TotalPrice = 10.50m,
+ TaxCategory = "B"
+ });
+
+ // Add tax breakdown
+ receipt.TaxBreakdown.Add(new TaxInfo
+ {
+ Category = "A",
+ Rate = 8.1m,
+ Gross = 149.50m,
+ Net = 138.30m,
+ TaxAmount = 11.20m,
+ Currency = "CHF"
+ });
+
+ receipt.TaxBreakdown.Add(new TaxInfo
+ {
+ Category = "B",
+ Rate = 0m,
+ Gross = 10.50m,
+ Net = 10.50m,
+ TaxAmount = 0.00m,
+ Currency = "CHF"
+ });
+
+ return receipt;
+ }
+
+ public static InvoiceReceipt BuildSampleInvoiceReceipt()
+ {
+ var receipt = new InvoiceReceipt
+ {
+ CompanyName = "Klingler Gastro AG",
+ Address1 = "Münzplatz 3",
+ Address2 = "CH-8001 Zürich",
+ Phone = "043 321 22 22",
+ ReceiptNumber = "1-81-202",
+ DateTime = new DateTime(2025, 12, 16, 14, 58, 0),
+ Guests = 2,
+ Total = 160.00m,
+ Currency = "CHF"
+ };
+
+ // Add items
+ receipt.Items.Add(new Inspectron.Epson.PrintServer.Printers.Utils.InvoiceReceipt.ReceiptItem
+ {
+ Quantity = 1,
+ Description = "San Pellegrino 50cl",
+ UnitPrice = 6.50m,
+ TotalPrice = 6.50m,
+ TaxCategory = "A"
+ });
+
+ receipt.Items.Add(new Inspectron.Epson.PrintServer.Printers.Utils.InvoiceReceipt.ReceiptItem
+ {
+ Quantity = 1,
+ Description = "Panna 50cl",
+ UnitPrice = 6.50m,
+ TotalPrice = 6.50m,
+ TaxCategory = "A"
+ });
+
+ receipt.Items.Add(new Inspectron.Epson.PrintServer.Printers.Utils.InvoiceReceipt.ReceiptItem
+ {
+ Quantity = 1,
+ Description = "Granini Tomatensaft",
+ UnitPrice = 5.50m,
+ TotalPrice = 5.50m,
+ TaxCategory = "A"
+ });
+
+ receipt.Items.Add(new Inspectron.Epson.PrintServer.Printers.Utils.InvoiceReceipt.ReceiptItem
+ {
+ Quantity = 2,
+ Description = "Business Lunch Menu Seco",
+ UnitPrice = 44.00m,
+ TotalPrice = 88.00m,
+ TaxCategory = "A"
+ });
+
+ receipt.Items.Add(new Inspectron.Epson.PrintServer.Printers.Utils.InvoiceReceipt.ReceiptItem
+ {
+ Quantity = 2,
+ Description = "Brunello di Montalcino 1",
+ UnitPrice = 16.00m,
+ TotalPrice = 32.00m,
+ TaxCategory = "A"
+ });
+
+ receipt.Items.Add(new Inspectron.Epson.PrintServer.Printers.Utils.InvoiceReceipt.ReceiptItem
+ {
+ Quantity = 2,
+ Description = "Espresso",
+ UnitPrice = 5.50m,
+ TotalPrice = 11.00m,
+ TaxCategory = "A"
+ });
+
+ receipt.Items.Add(new Inspectron.Epson.PrintServer.Printers.Utils.InvoiceReceipt.ReceiptItem
+ {
+ Quantity = 1,
+ Description = "Tip",
+ UnitPrice = 10.50m,
+ TotalPrice = 10.50m,
+ TaxCategory = "B"
+ });
+
+ return receipt;
+ }
+
+ public static KitchenReceipt BuildSampleKitchenReceipt()
+ {
+ var receipt = new KitchenReceipt
+ {
+ Title = "Warme Küche",
+ TransactionDateTime = new DateTime(2025, 10, 23, 12, 18, 0),
+ ReceiptNumber = "132018166",
+ WaiterName = "Mariano Amato",
+ WaiterId = "32 (VK Restaurant)",
+ TableNumber = "22"
+ };
+
+ receipt.Gangs.Add(new Gang(1, "Gang"));
+ receipt.Gangs.Add(new Gang(2, "Gang"));
+
+ receipt.Gangs[0].Dishes.Add(new Dish(1, "Avocado Sashimi")
+ {
+ Modifications = new DishModifications
+ {
+ Removed = new List { "Wasabi" },
+ Added = new List { "Extra Ginger" }
+ },
+ Comment = "No soy sauce"
+ });
+ receipt.Gangs[0].Dishes.Add(new Dish(1, "Baby Spinach Salad with Truffl"));
+ receipt.Gangs[0].Dishes.Add(new Dish(1, "Beef Tataki")
+ {
+ Modifications = new DishModifications
+ {
+ Removed = new List { "Onion" },
+ Added = new List { "Extra Sauce" }
+ },
+ Comment = "Medium rare"
+ });
+ receipt.Gangs[0].Dishes.Add(new Dish(1, "Salmon Taco")
+ {
+ Modifications = new DishModifications
+ {
+ Added = new List { "Extra Lime" }
+ }
+ });
+
+ receipt.Gangs[1].Dishes.Add(new Dish(1, "Avocado Sashimi"));
+ receipt.Gangs[1].Dishes.Add(new Dish(1, "Baby Spinach Salad with Truffl"));
+ receipt.Gangs[1].Dishes.Add(new Dish(1, "Beef Tataki"));
+ receipt.Gangs[1].Dishes.Add(new Dish(1, "Salmon Taco"));
+
+ return receipt;
+ }
+
+ public static KitchenReceipt BuildSampleKitchenReceiptNextDish()
+ {
+ var receipt = new KitchenReceipt
+ {
+ Title = "Warme Küche",
+ TransactionDateTime = new DateTime(2025, 10, 23, 12, 18, 0),
+ ReceiptNumber = "132018166",
+ WaiterName = "Mariano Amato",
+ WaiterId = "32 (VK Restaurant)",
+ TableNumber = "22",
+ SpecialInstruction = "Next dish"
+ };
+
+ receipt.Gangs.Add(new Gang(2, "Gang"));
+
+ receipt.Gangs[0].Dishes.Add(new Dish(1, "Avocado Sashimi")
+ {
+ Modifications = new DishModifications
+ {
+ Removed = new List { "Wasabi" },
+ Added = new List { "Extra Ginger" }
+ },
+ Comment = "No soy sauce"
+ });
+ receipt.Gangs[0].Dishes.Add(new Dish(1, "Baby Spinach Salad with Truffl"));
+ receipt.Gangs[0].Dishes.Add(new Dish(1, "Beef Tataki")
+ {
+ Modifications = new DishModifications
+ {
+ Removed = new List { "Onion" },
+ Added = new List { "Extra Sauce" }
+ },
+ Comment = "Medium rare"
+ });
+ receipt.Gangs[0].Dishes.Add(new Dish(1, "Salmon Taco")
+ {
+ Modifications = new DishModifications
+ {
+ Added = new List { "Extra Lime" }
+ }
+ });
+
+ return receipt;
+ }
+
+ public static OrderItemsReceipt BuildSampleOrderItemsReceipt()
+ {
+ return new OrderItemsReceipt
+ {
+ OrderNumber = "1",
+ QRInfo = "Margherita Pizza Classic longer text",
+ DateTime = new DateTime(2026, 1, 14, 14, 35, 47),
+ ClientNotes = "Some main note",
+ Items = new List
+ {
+ new()
+ {
+ Number = 1,
+ Name = "pappara",
+ Quantity = 1,
+ SubItems = new List { "pizza", "cola" },
+ Comment = "Cola zero please"
+ },
+ new()
+ {
+ Number = 2,
+ Name = "Classic Beef Burger",
+ Quantity = 1,
+ Modifications = new ItemModifications
+ {
+ Removed = new List { "Onion" },
+ Added = new List { "butter" }
+ },
+ Comment = "Medium rare please"
+ },
+ new()
+ {
+ Number = 3,
+ Name = "Margherita Pizza Classic",
+ Quantity = 2,
+ Size = "L"
+ }
+ }
+ };
+ }
+
+ #endregion
+
+ #region Print Helpers
+
+ public static async Task PrintCommandsToHtmlPrinterAsync(
+ HtmlPrinter printer,
+ IEnumerable commands,
+ string? logoPath = null,
+ int logoWidth = 300,
+ int logoXPosition = 42)
+ {
+ if (logoPath != null)
+ {
+ await printer.SetAbsolutePrintPosition(logoXPosition);
+ await printer.LoadImageAsync(logoPath, logoWidth);
+ await printer.PrintLoadedImage();
+ await printer.SetAbsolutePrintPosition(0);
+ }
+
+ await printer.SetCustomLineSpacing(22);
+
+ foreach (var command in commands)
+ {
+ if (command.IsBig)
+ await printer.SetFontSizeAsync(2, 1);
+ else
+ await printer.SetFontSizeAsync(1, 1);
+
+ await printer.SetEmphasized(command.IsBold);
+ await printer.PrintTextAsync(command.Text + "\n");
+ }
+ }
+
+ public static async Task PrintCommandsToEpsonPrinterAsync(
+ EpsonPrinter printer,
+ IEnumerable commands,
+ bool useDelay = true,
+ int delayMs = 500)
+ {
+ await printer.FeedLinesAsync(1);
+ await printer.SetCustomLineSpacing(22);
+
+ foreach (var command in commands)
+ {
+ await printer.SetBiggerFontTM220(command.IsBig, command.IsTall | command.IsBig, secondaryFont: false);
+ if (useDelay) await Task.Delay(delayMs);
+
+ await printer.SetRedColor(command.IsRed);
+ if (useDelay) await Task.Delay(delayMs);
+
+ await printer.SetEmphasized(command.IsBold);
+ if (useDelay) await Task.Delay(delayMs);
+
+ await printer.PrintTextAsync(command.Text + "\n");
+ if (useDelay) await Task.Delay(delayMs);
+ }
+
+ await printer.FeedLinesAsync(5);
+ if (useDelay) await Task.Delay(delayMs * 5);
+ await printer.CutAsync();
+ }
+
+ public static async Task PrintKitchenCommandsToHtmlPrinterAsync(
+ HtmlPrinter printer,
+ IEnumerable commands)
+ {
+ await printer.FeedLinesAsync(1);
+ await printer.SetCustomLineSpacing(22);
+
+ foreach (var command in commands)
+ {
+ if (command.IsBig)
+ await printer.SetFontSizeAsync(2, 1);
+ else
+ await printer.SetFontSizeAsync(1, 1);
+
+ await printer.SetRedColor(command.IsRed);
+ await printer.SetEmphasized(command.IsBold);
+ await printer.PrintTextAsync(command.Text + "\n");
+ }
+ }
+
+ #endregion
+
+ #region Console Output
+
+ public static void PrintCommandsToConsole(IEnumerable commands)
+ {
+ Console.WriteLine("=== PRINT COMMANDS ===\n");
+ foreach (var command in commands)
+ {
+ string attributes = "";
+ if (command.IsBig) attributes += "[BIG] ";
+ if (command.IsBold) attributes += "[BOLD] ";
+ if (command.IsRed) attributes += "[RED] ";
+
+ Console.WriteLine($"{attributes}{command.Text}");
+ }
+ }
+
+ #endregion
+}
diff --git a/Inspectron.Epson.Templates.Tests/Language/ParserTests.cs b/Inspectron.Epson.Templates.Tests/Language/ParserTests.cs
index a079aea..4e74997 100644
--- a/Inspectron.Epson.Templates.Tests/Language/ParserTests.cs
+++ b/Inspectron.Epson.Templates.Tests/Language/ParserTests.cs
@@ -134,7 +134,7 @@ public class ParserTests
var result = Parse("line1\n\nline2");
Assert.False(result.HasErrors);
- Assert.Contains(result.Template.ChildNodes, n => n is EmptyLineNode);
+ Assert.Contains(result.Template.ChildNodes, n => n is NewLineNode);
}
[Fact]
diff --git a/Inspectron.Epson.Templates/Interpreter/TemplateInterpreter.cs b/Inspectron.Epson.Templates/Interpreter/TemplateInterpreter.cs
index b5fd544..49bb967 100644
--- a/Inspectron.Epson.Templates/Interpreter/TemplateInterpreter.cs
+++ b/Inspectron.Epson.Templates/Interpreter/TemplateInterpreter.cs
@@ -73,38 +73,38 @@ public class TemplateInterpreter
// Styled text - flush buffer, emit styled content, continue accumulating
case StyledTextNode styledNode:
- FlushLineBuffer();
+
InterpretStyledText(styledNode, context, commands, style);
break;
// Block nodes - flush buffer first, then process
case SeparatorNode separatorNode:
- FlushLineBuffer();
+
InterpretSeparator(separatorNode, commands, style);
break;
- case EmptyLineNode:
+ case NewLineNode:
FlushLineBuffer();
commands.Add(CreateCommand(string.Empty, style));
break;
case IfNode ifNode:
- FlushLineBuffer();
+
InterpretIf(ifNode, context, commands, style);
break;
case ForeachNode foreachNode:
- FlushLineBuffer();
+
InterpretForeach(foreachNode, context, commands, style);
break;
case RowNode rowNode:
- FlushLineBuffer();
+
InterpretRow(rowNode, context, commands, style);
break;
case ColumnNode columnNode:
- FlushLineBuffer();
+
InterpretColumn(columnNode, context, commands, style);
break;
}
diff --git a/Inspectron.Epson.Templates/Language/Nodes/EmptyLineNode.cs b/Inspectron.Epson.Templates/Language/Nodes/NewLineNode.cs
similarity index 66%
rename from Inspectron.Epson.Templates/Language/Nodes/EmptyLineNode.cs
rename to Inspectron.Epson.Templates/Language/Nodes/NewLineNode.cs
index 13565c1..624b372 100644
--- a/Inspectron.Epson.Templates/Language/Nodes/EmptyLineNode.cs
+++ b/Inspectron.Epson.Templates/Language/Nodes/NewLineNode.cs
@@ -1,6 +1,6 @@
namespace Inspectron.Epson.Templates.Language.Nodes;
-public record EmptyLineNode(SourcePosition Position) : ITemplateNode
+public record NewLineNode(SourcePosition Position) : ITemplateNode
{
public IReadOnlyList Children => Array.Empty();
}
diff --git a/Inspectron.Epson.Templates/Language/Parser.cs b/Inspectron.Epson.Templates/Language/Parser.cs
index e13eb7d..b2a95c6 100644
--- a/Inspectron.Epson.Templates/Language/Parser.cs
+++ b/Inspectron.Epson.Templates/Language/Parser.cs
@@ -46,12 +46,10 @@ public class Parser
{
case TokenType.NewLine:
Advance();
- // Check if this was an empty line (previous was also newline or start)
- if (_position >= 2 && _tokens[_position - 2].Type == TokenType.NewLine)
- {
- return new EmptyLineNode(token.Position);
- }
- return null;
+ if(token.Position.Column==1)
+ return new NewLineNode(token.Position);
+ else
+ return null;
case TokenType.Text:
return ParseText();
diff --git a/Inspectron.Epson.Templates/Validation/TemplateValidator.cs b/Inspectron.Epson.Templates/Validation/TemplateValidator.cs
index 0ebed22..46b7a72 100644
--- a/Inspectron.Epson.Templates/Validation/TemplateValidator.cs
+++ b/Inspectron.Epson.Templates/Validation/TemplateValidator.cs
@@ -139,7 +139,7 @@ public class TemplateValidator
case TextNode:
case SeparatorNode:
- case EmptyLineNode:
+ case NewLineNode:
// No additional validation needed
break;
}
diff --git a/Inspectron.Epson/PrintServer/Printers/TM-U220IITranslated.cs b/Inspectron.Epson/PrintServer/Printers/TM-U220IITranslated.cs
index 3d1d89c..e1a2248 100644
--- a/Inspectron.Epson/PrintServer/Printers/TM-U220IITranslated.cs
+++ b/Inspectron.Epson/PrintServer/Printers/TM-U220IITranslated.cs
@@ -35,7 +35,7 @@ public class TM_U220IITranslated : IPrinter
{
foreach (var command in commands)
{
- await _printer.SetBiggerFontTM220(command.IsBig);
+ await _printer.SetBiggerFontTM220(command.IsBig, command.IsTall | command.IsBig);
await Task.Delay(200);
await _printer.SetRedColor(command.IsRed);
await Task.Delay(200);
diff --git a/Inspectron.Epson/PrintServer/Printers/Utils/FinalReceipt/Models.cs b/Inspectron.Epson/PrintServer/Printers/Utils/FinalReceipt/Models.cs
index d37457a..c07299e 100644
--- a/Inspectron.Epson/PrintServer/Printers/Utils/FinalReceipt/Models.cs
+++ b/Inspectron.Epson/PrintServer/Printers/Utils/FinalReceipt/Models.cs
@@ -9,7 +9,7 @@ public class FinalReceipt
public string ReceiptNumber { get; set; }
public DateTime DateTime { get; set; }
public int Guests { get; set; }
- public List Items { get; set; } = new List();
+ public List Items { get; set; } = new List();
public decimal Total { get; set; }
public string Currency { get; set; }
public decimal? TotalInAlternateCurrency { get; set; }
@@ -28,7 +28,7 @@ public class FinalReceipt
public List TerminalReceipts { get; set; } = new List();
}
-public class ReceiptItem
+public class FinalReceiptItem
{
public int Quantity { get; set; }
public string Description { get; set; }
diff --git a/Inspectron.Epson/PrintServer/Printers/Utils/InvoiceReceipt/InvoiceReceiptConverter.cs b/Inspectron.Epson/PrintServer/Printers/Utils/InvoiceReceipt/InvoiceReceiptConverter.cs
new file mode 100644
index 0000000..f8e174b
--- /dev/null
+++ b/Inspectron.Epson/PrintServer/Printers/Utils/InvoiceReceipt/InvoiceReceiptConverter.cs
@@ -0,0 +1,22 @@
+using System.Text.Json;
+
+namespace Inspectron.Epson.PrintServer.Printers.Utils.InvoiceReceipt;
+
+public class InvoiceReceiptConverter : IReceiptConverter
+{
+ private readonly int _lineWidth;
+ private readonly int _bigFontLineWidth;
+
+ public InvoiceReceiptConverter(int lineWidth, int bigFontLineWidth)
+ {
+ _lineWidth = lineWidth;
+ _bigFontLineWidth = bigFontLineWidth;
+ }
+
+ public List Convert(string jsonContent)
+ {
+ var receipt = JsonSerializer.Deserialize(jsonContent);
+ var converter = new ReceiptConverter(_lineWidth, _bigFontLineWidth);
+ return converter.ConvertToPrintCommands(receipt);
+ }
+}
diff --git a/Inspectron.Epson/PrintServer/Printers/Utils/InvoiceReceipt/Models.cs b/Inspectron.Epson/PrintServer/Printers/Utils/InvoiceReceipt/Models.cs
new file mode 100644
index 0000000..e9e114e
--- /dev/null
+++ b/Inspectron.Epson/PrintServer/Printers/Utils/InvoiceReceipt/Models.cs
@@ -0,0 +1,24 @@
+namespace Inspectron.Epson.PrintServer.Printers.Utils.InvoiceReceipt;
+
+public class InvoiceReceipt
+{
+ public string CompanyName { get; set; }
+ public string Address1 { get; set; }
+ public string Address2 { get; set; }
+ public string Phone { get; set; }
+ public string ReceiptNumber { get; set; }
+ public DateTime DateTime { get; set; }
+ public int Guests { get; set; }
+ public List Items { get; set; } = new List();
+ public decimal Total { get; set; }
+ public string Currency { get; set; }
+}
+
+public class ReceiptItem
+{
+ public int Quantity { get; set; }
+ public string Description { get; set; }
+ public decimal UnitPrice { get; set; }
+ public decimal TotalPrice { get; set; }
+ public string TaxCategory { get; set; }
+}
diff --git a/Inspectron.Epson/PrintServer/Printers/Utils/InvoiceReceipt/ReceiptConverter.cs b/Inspectron.Epson/PrintServer/Printers/Utils/InvoiceReceipt/ReceiptConverter.cs
new file mode 100644
index 0000000..833bdf0
--- /dev/null
+++ b/Inspectron.Epson/PrintServer/Printers/Utils/InvoiceReceipt/ReceiptConverter.cs
@@ -0,0 +1,69 @@
+namespace Inspectron.Epson.PrintServer.Printers.Utils.InvoiceReceipt;
+
+public class ReceiptConverter
+{
+ private readonly int _lineWidth;
+ private readonly int _bigFontLineWidth;
+
+ public ReceiptConverter(int lineWidth = 42, int bigFontLineWidth = 21)
+ {
+ _lineWidth = lineWidth;
+ _bigFontLineWidth = bigFontLineWidth;
+ }
+
+ public List ConvertToPrintCommands(InvoiceReceipt invoiceReceipt)
+ {
+ var commands = new List();
+
+ // Header - Company info
+ commands.Add(new PrintCommand(Center(invoiceReceipt.CompanyName, false)));
+ commands.Add(new PrintCommand(Center(invoiceReceipt.Address1, false)));
+ commands.Add(new PrintCommand(Center(invoiceReceipt.Address2, false)));
+ commands.Add(new PrintCommand(Center(invoiceReceipt.Phone, false)));
+ commands.Add(new PrintCommand(""));
+ commands.Add(new PrintCommand(""));
+
+ // InvoiceReceipt info
+ string receiptLine = $"Rechnung Nr. {invoiceReceipt.ReceiptNumber}".PadRight(_lineWidth/2)+$"{invoiceReceipt.DateTime:HH:mm dd.MM.yyyy}".PadLeft(_lineWidth/2);
+ commands.Add(new PrintCommand(receiptLine,isBold:true));
+ commands.Add(new PrintCommand($"Guests: {invoiceReceipt.Guests}"));
+ commands.Add(new PrintCommand(""));
+
+ // Items
+ foreach (var item in invoiceReceipt.Items)
+ {
+ string quantityDesc = $"{item.Quantity}x {item.Description}";
+ string prices = $"{item.UnitPrice:F2}"+$"{item.TotalPrice:F2}".PadLeft(7)+$" {item.TaxCategory}";
+
+ // Calculate spacing to align prices to the right
+ int spacesNeeded = _lineWidth - quantityDesc.Length - prices.Length;
+ if (spacesNeeded < 1) spacesNeeded = 1;
+
+ string itemLine = quantityDesc + new string(' ', spacesNeeded) + prices;
+ commands.Add(new PrintCommand(itemLine));
+ }
+
+ commands.Add(new PrintCommand(""));
+ commands.Add(new PrintCommand("---------".PadLeft(_lineWidth)));
+ commands.Add(new PrintCommand(""));
+
+ // Total
+ string totalLine = $"Summe: {invoiceReceipt.Total:F2} {invoiceReceipt.Currency}";
+ commands.Add(new PrintCommand(Center(totalLine, true), true, true));
+
+ return commands;
+ }
+
+ private string Center(string text, bool isBigFont)
+ {
+ int effectiveLineWidth = isBigFont ? _bigFontLineWidth : _lineWidth;
+
+ if (string.IsNullOrEmpty(text) || text.Length >= effectiveLineWidth)
+ return text;
+
+ int totalPadding = effectiveLineWidth - text.Length;
+ int leftPadding = totalPadding / 2;
+
+ return new string(' ', leftPadding) + text;
+ }
+}
diff --git a/Inspectron.Epson/PrintServer/Printers/Utils/ReceiptConverterFactory.cs b/Inspectron.Epson/PrintServer/Printers/Utils/ReceiptConverterFactory.cs
index 085ae5e..e6c7c18 100644
--- a/Inspectron.Epson/PrintServer/Printers/Utils/ReceiptConverterFactory.cs
+++ b/Inspectron.Epson/PrintServer/Printers/Utils/ReceiptConverterFactory.cs
@@ -1,4 +1,5 @@
using Inspectron.Epson.PrintServer.Printers.Utils.BarReceipt;
+using Inspectron.Epson.PrintServer.Printers.Utils.InvoiceReceipt;
using Inspectron.Epson.PrintServer.Printers.Utils.OrderItems;
namespace Inspectron.Epson.PrintServer.Printers.Utils;
@@ -17,14 +18,17 @@ public class ReceiptConverterFactory : IReceiptConverterFactory
},
EReceiptType.NextCourse => new KitchenReceipt.KitchenReceiptConverterAdapter(33, 20),
EReceiptType.OrdersOverview => new OrderItemsReceiptConverter(48, 24),
+ EReceiptType.Invoice => new InvoiceReceiptConverter(48, 24),
_ => throw new ArgumentException($"Unknown receipt type: {receiptType}")
};
}
+
public enum EReceiptType
{
Receipt,
WorkareaTicket,
NextCourse,
- OrdersOverview
+ OrdersOverview,
+ Invoice
}
}