test run works
This commit is contained in:
@@ -12,6 +12,7 @@ public class PrinterDiscoveryBackgroundTask
|
||||
private readonly IDiscoveryService _discoveryService;
|
||||
private readonly IDiscoveredPrintersReceiver _receiver;
|
||||
private readonly ILogger _logger;
|
||||
private readonly PrintServer _printServer;
|
||||
private readonly TimeSpan _interval;
|
||||
private readonly TimeSpan _discoveryTimeout;
|
||||
|
||||
@@ -21,11 +22,13 @@ public class PrinterDiscoveryBackgroundTask
|
||||
public PrinterDiscoveryBackgroundTask(
|
||||
IDiscoveryService discoveryService,
|
||||
IDiscoveredPrintersReceiver receiver,
|
||||
ILogger logger)
|
||||
ILogger logger,
|
||||
PrintServer printServer)
|
||||
{
|
||||
_discoveryService = discoveryService;
|
||||
_receiver = receiver;
|
||||
_logger = logger;
|
||||
_printServer = printServer;
|
||||
_interval = TimeSpan.FromSeconds(30);
|
||||
_discoveryTimeout = TimeSpan.FromSeconds(3);
|
||||
}
|
||||
@@ -67,13 +70,14 @@ public class PrinterDiscoveryBackgroundTask
|
||||
try
|
||||
{
|
||||
var printers = await _discoveryService.DiscoverPrintersAsync(_discoveryTimeout);
|
||||
printers.Add(new DiscoveredPrinter()
|
||||
{
|
||||
IPAddress = "127.0.0.1",
|
||||
ModelName = "TM-T30III",
|
||||
});
|
||||
|
||||
var currentIps = printers.Select(p => p.IPAddress).ToHashSet();
|
||||
|
||||
foreach (string currentIp in currentIps)
|
||||
{
|
||||
_printServer.RegisterPrinter(currentIp);
|
||||
}
|
||||
|
||||
if (HasConfigurationChanged(currentIps))
|
||||
{
|
||||
_logger.LogInformation("Discovered printer configuration changed: {Count} printer(s)", printers.Count);
|
||||
|
||||
@@ -10,6 +10,7 @@ using Inspectron.Epson.PrintServer.ConfigurationSources;
|
||||
using Inspectron.Epson.PrintServer.JobSources;
|
||||
using Inspectron.Epson.PrintServer.PrinterAssinment;
|
||||
using Inspectron.Epson.PrintServer.Printers;
|
||||
using Inspectron.Epson.PrintServer.Printers.Utils;
|
||||
using Inspectron.Epson.PrintServer.PrintServices;
|
||||
using EpsonPrintService;
|
||||
|
||||
@@ -40,6 +41,7 @@ kernel.Bind<ILogger>().ToMethod(ctx =>
|
||||
kernel.Bind<IAssignedPrinterRepository>().ToConstant(config);
|
||||
kernel.Bind<IWrapperPrinterFactory>().To<PrinterWrapperFactory>().InSingletonScope();
|
||||
kernel.Bind<IPrinterConfigurationSource>().To<FixedConfigurationSource>();
|
||||
kernel.Bind<IReceiptConverterFactory>().To<ReceiptConverterFactory>().InSingletonScope();
|
||||
kernel.Bind<PrintServer>().ToSelf().InSingletonScope();
|
||||
kernel.Bind<IDiscoveredPrintersReceiver>().To<JamesDiscoveredPrintersReceiver>().InSingletonScope();
|
||||
kernel.Bind<PrinterDiscoveryBackgroundTask>().ToSelf().InSingletonScope();
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"GroupId": "64a3d9f0876bc5d1704bce43",
|
||||
"RestaurantId": "64a3d9f0876bc5d1704bce43",
|
||||
"ApiKey": "LBOACMlvFEgDbZqt24uW0LjiFv0LKU5DT94g0JDoBnI=",
|
||||
"GroupId": "63e37295bd6f26dbd36164c0",
|
||||
"RestaurantId": "63e37295bd6f26dbd36164c0",
|
||||
"ApiKey": "Pd8X/VtXLWgl5Djy4ksjdHC3xboeoh5Jig3Qo4277GQ=",
|
||||
"PrinterConfigurations": {}
|
||||
}
|
||||
@@ -8,6 +8,7 @@ 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.OrderItems;
|
||||
using FinalReceipt = Inspectron.Epson.PrintServer.Printers.Utils.FinalRecipe.FinalReceipt;
|
||||
|
||||
@@ -189,8 +190,8 @@ using FinalReceipt = Inspectron.Epson.PrintServer.Printers.Utils.FinalRecipe.Fin
|
||||
//var serializedReceipt = JsonSerializer.Serialize(receipt, new JsonSerializerOptions { WriteIndented = true });
|
||||
//var deserializedReceipt = JsonSerializer.Deserialize<FinalReceipt>(serializedReceipt);
|
||||
//// Convert to print commands
|
||||
//var converter = new ReceiptConverter(lineWidth: 48, bigFontLineWidth: 24);
|
||||
//var printCommands = converter.ConvertToPrintCommands(deserializedReceipt);
|
||||
//var converter = new FinalReceiptConverter(lineWidth: 48, bigFontLineWidth: 24);
|
||||
//var printCommands = converter.Convert(serializedReceipt);
|
||||
|
||||
|
||||
|
||||
@@ -248,10 +249,32 @@ using FinalReceipt = Inspectron.Epson.PrintServer.Printers.Utils.FinalRecipe.Fin
|
||||
//receipt.Gangs.Add(new Gang(1, "Gang"));
|
||||
//receipt.Gangs.Add(new Gang(2, "Gang"));
|
||||
|
||||
//receipt.Gangs[0].Dishes.Add(new Dish(1, "Avocado Sashimi"));
|
||||
//receipt.Gangs[0].Dishes.Add(new Dish(1, "Avocado Sashimi")
|
||||
//{
|
||||
// Modifications = new DishModifications
|
||||
// {
|
||||
// Removed = new List<string> { "Wasabi" },
|
||||
// Added = new List<string> { "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"));
|
||||
//receipt.Gangs[0].Dishes.Add(new Dish(1, "Salmon Taco"));
|
||||
//receipt.Gangs[0].Dishes.Add(new Dish(1, "Beef Tataki")
|
||||
//{
|
||||
// Modifications = new DishModifications
|
||||
// {
|
||||
// Removed = new List<string> { "Onion" },
|
||||
// Added = new List<string> { "Extra Sauce" }
|
||||
// },
|
||||
// Comment = "Medium rare"
|
||||
//});
|
||||
//receipt.Gangs[0].Dishes.Add(new Dish(1, "Salmon Taco")
|
||||
//{
|
||||
// Modifications = new DishModifications
|
||||
// {
|
||||
// Added = new List<string> { "Extra Lime" }
|
||||
// }
|
||||
//});
|
||||
|
||||
|
||||
//receipt.Gangs[1].Dishes.Add(new Dish(1, "Avocado Sashimi"));
|
||||
@@ -308,11 +331,98 @@ using FinalReceipt = Inspectron.Epson.PrintServer.Printers.Utils.FinalRecipe.Fin
|
||||
|
||||
//}
|
||||
|
||||
|
||||
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<string> { "Wasabi" },
|
||||
Added = new List<string> { "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<string> { "Onion" },
|
||||
Added = new List<string> { "Extra Sauce" }
|
||||
},
|
||||
Comment = "Medium rare"
|
||||
});
|
||||
receipt.Gangs[0].Dishes.Add(new Dish(1, "Salmon Taco")
|
||||
{
|
||||
Modifications = new DishModifications
|
||||
{
|
||||
Added = new List<string> { "Extra Lime" }
|
||||
}
|
||||
});
|
||||
|
||||
// Add additional info
|
||||
|
||||
var serializedReceipt = JsonSerializer.Serialize(receipt, new JsonSerializerOptions { WriteIndented = true });
|
||||
var deserializedReceipt = JsonSerializer.Deserialize<KitchenReceipt>(serializedReceipt);
|
||||
KitchenReceiptConverter 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] ";
|
||||
|
||||
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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
//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
|
||||
//// Order Items Receipt Test
|
||||
//var orderItemsReceipt = new OrderItemsReceipt
|
||||
//{
|
||||
// OrderNumber = "1",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System.Reflection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Inspectron.Epson.PrintServer.Printers;
|
||||
using Inspectron.Epson.PrintServer.Printers.Utils;
|
||||
|
||||
namespace Inspectron.Epson.PrintServer.PrintServices;
|
||||
|
||||
@@ -10,13 +10,15 @@ public class EpsonPrintService: IPrintService
|
||||
private readonly IPrinterFactory _printerFactory;
|
||||
private readonly IWrapperPrinterFactory _wrapperPrinterFactory;
|
||||
private readonly IPrinterConfigurationSource _printerConfigurationSource;
|
||||
private readonly IReceiptConverterFactory _receiptConverterFactory;
|
||||
|
||||
public EpsonPrintService(ILogger logger, IPrinterFactory printerFactory, IWrapperPrinterFactory wrapperPrinterFactory, IPrinterConfigurationSource printerConfigurationSource)
|
||||
public EpsonPrintService(ILogger logger, IPrinterFactory printerFactory, IWrapperPrinterFactory wrapperPrinterFactory, IPrinterConfigurationSource printerConfigurationSource, IReceiptConverterFactory receiptConverterFactory)
|
||||
{
|
||||
_logger = logger;
|
||||
_printerFactory = printerFactory;
|
||||
_wrapperPrinterFactory = wrapperPrinterFactory;
|
||||
_printerConfigurationSource = printerConfigurationSource;
|
||||
_receiptConverterFactory = receiptConverterFactory;
|
||||
}
|
||||
|
||||
public async Task<bool> PrintAsync(string printerIp, PrintJob job)
|
||||
@@ -25,19 +27,8 @@ public class EpsonPrintService: IPrintService
|
||||
{
|
||||
var configuration = _printerConfigurationSource.GetConfiguration(printerIp);
|
||||
await using var epsonPrinter = _printerFactory.CreatePrinter();
|
||||
string address;
|
||||
string address = printerIp;
|
||||
int port = 9100;
|
||||
var printerAddress = configuration.Address;
|
||||
if (printerAddress.Contains(":"))
|
||||
{
|
||||
var parts = printerAddress.Split(':');
|
||||
address = parts[0];
|
||||
port = int.Parse(parts[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
address = printerAddress;
|
||||
}
|
||||
|
||||
await epsonPrinter.ConnectAsync(address, port);
|
||||
|
||||
@@ -90,7 +81,10 @@ public class EpsonPrintService: IPrintService
|
||||
|
||||
await printerAdapter.SetFontSizeAsync(configuration.FontSize);
|
||||
|
||||
await printerAdapter.PrintTextAsync(job.Document.Content);
|
||||
// Convert receipt content to print commands using the factory
|
||||
var converter = _receiptConverterFactory.Create(job.Document.ReceiptType, lineWidth: 48, bigFontLineWidth: 24);
|
||||
var commands = converter.Convert(job.Document.Content);
|
||||
await printerAdapter.PrintAsync(commands);
|
||||
await Task.Delay(200);
|
||||
status = await epsonPrinter.GetPrinterStatusAsync();
|
||||
if (!status.IsOnline)
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
namespace Inspectron.Epson.PrintServer.PrintServices;
|
||||
using Inspectron.Epson.PrintServer.Printers.Utils;
|
||||
|
||||
namespace Inspectron.Epson.PrintServer.PrintServices;
|
||||
|
||||
public interface IPrinter
|
||||
{
|
||||
public Task InitAsync();
|
||||
public Task PrintImageAsync(string path);
|
||||
public Task SetFontSizeAsync(int fontSize);
|
||||
public Task PrintTextAsync(string text);
|
||||
public Task PrintAsync(List<PrintCommand> commands);
|
||||
public Task Cut();
|
||||
}
|
||||
@@ -1,10 +1,9 @@
|
||||
using Inspectron.Epson.PrintServer.PrintServices;
|
||||
using System.Net.NetworkInformation;
|
||||
using System.Reflection;
|
||||
using Inspectron.Epson.PrintServer.Printers.Utils;
|
||||
using Inspectron.Epson.PrintServer.PrintServices;
|
||||
|
||||
namespace Inspectron.Epson.PrintServer.Printers;
|
||||
|
||||
public class TM_T30III:IPrinter
|
||||
public class TM_T30III : IPrinter
|
||||
{
|
||||
private readonly EpsonPrinter _printer;
|
||||
|
||||
@@ -33,11 +32,25 @@ public class TM_T30III:IPrinter
|
||||
await _printer.SetFontSizeAsync(fontSize, fontSize);
|
||||
}
|
||||
|
||||
public async Task PrintTextAsync(string text)
|
||||
public async Task PrintAsync(List<PrintCommand> commands)
|
||||
{
|
||||
await _printer.PrintTextAsync(text);
|
||||
foreach (var command in commands)
|
||||
{
|
||||
if (command.IsBig)
|
||||
{
|
||||
await _printer.SetFontSizeAsync(2, 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
await _printer.SetFontSizeAsync(1, 1);
|
||||
}
|
||||
|
||||
await _printer.SetRedColor(command.IsRed);
|
||||
await _printer.SetEmphasized(command.IsBold);
|
||||
await _printer.PrintTextAsync(command.Text + "\n");
|
||||
}
|
||||
|
||||
await _printer.FeedLinesAsync(5);
|
||||
var status = await _printer.GetPrinterStatusAsync();
|
||||
}
|
||||
|
||||
public async Task Cut()
|
||||
|
||||
@@ -1,13 +1,9 @@
|
||||
using Inspectron.Epson.PrintServer.Printers.Utils;
|
||||
using Inspectron.Epson.PrintServer.Printers.Utils.FinalRecipe;
|
||||
using Inspectron.Epson.PrintServer.Printers.Utils;
|
||||
using Inspectron.Epson.PrintServer.PrintServices;
|
||||
using System.Reflection;
|
||||
using System.Text.Json;
|
||||
using FinalReceipt = Inspectron.Epson.PrintServer.Printers.Utils.FinalRecipe.FinalReceipt;
|
||||
|
||||
namespace Inspectron.Epson.PrintServer.Printers;
|
||||
|
||||
public class TM_T30IIITranslated:IPrinter
|
||||
public class TM_T30IIITranslated : IPrinter
|
||||
{
|
||||
private readonly IEpsonPrinter _printer;
|
||||
|
||||
@@ -40,31 +36,12 @@ public class TM_T30IIITranslated:IPrinter
|
||||
//await _printer.SetFontSizeAsync(fontSize, fontSize);
|
||||
}
|
||||
|
||||
public async Task PrintTextAsync(string text)
|
||||
public async Task PrintAsync(List<PrintCommand> commands)
|
||||
{
|
||||
FinalReceipt? receipt;
|
||||
try
|
||||
{
|
||||
receipt = JsonSerializer.Deserialize<FinalReceipt>(text);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Fallback to kitchen receipt
|
||||
await PrintKitchen(text);
|
||||
return;
|
||||
}
|
||||
var converter = new ReceiptConverter(lineWidth: 48, bigFontLineWidth: 24);
|
||||
var printCommands = converter.ConvertToPrintCommands(receipt);
|
||||
await _printer.SetCustomLineSpacing(22);
|
||||
|
||||
foreach (var command in printCommands)
|
||||
foreach (var command in commands)
|
||||
{
|
||||
string attributes = "";
|
||||
if (command.IsBig) attributes += "[BIG]\n";
|
||||
if (command.IsBold) attributes += "[BOLD]\n";
|
||||
|
||||
Console.WriteLine($"{attributes}{command.Text}");
|
||||
|
||||
if (command.IsBig)
|
||||
{
|
||||
await _printer.SetFontSizeAsync(2, 1);
|
||||
@@ -73,11 +50,11 @@ public class TM_T30IIITranslated:IPrinter
|
||||
{
|
||||
await _printer.SetFontSizeAsync(1, 1);
|
||||
}
|
||||
|
||||
await _printer.SetEmphasized(command.IsBold);
|
||||
|
||||
await _printer.PrintTextAsync(command.Text + "\n");
|
||||
|
||||
|
||||
await _printer.SetRedColor(command.IsRed);
|
||||
await _printer.SetEmphasized(command.IsBold);
|
||||
await _printer.PrintTextAsync(command.Text + "\n");
|
||||
}
|
||||
|
||||
await _printer.SetDefaultLineSpacing();
|
||||
@@ -85,37 +62,6 @@ public class TM_T30IIITranslated:IPrinter
|
||||
await Task.Delay(200);
|
||||
}
|
||||
|
||||
private async Task PrintKitchen(string text)
|
||||
{
|
||||
ReceiptTranslator translator = new ReceiptTranslator();
|
||||
var ast = translator.ParseReceipt(text);
|
||||
KitchenReceiptPrinter printer = new KitchenReceiptPrinter(lineWidth: 33, 21);
|
||||
var commands = printer.ConvertToCommands((TranslatedKitchenReceipt)ast);
|
||||
foreach (KitchenPrintCommand command in commands)
|
||||
{
|
||||
if (command.IsBig)
|
||||
{
|
||||
await _printer.SetFontSizeAsync(2,2);
|
||||
}
|
||||
else
|
||||
{
|
||||
await _printer.SetFontSizeAsync(1, 1);
|
||||
}
|
||||
|
||||
|
||||
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.FeedLinesAsync(10);
|
||||
await Task.Delay(1000);
|
||||
}
|
||||
|
||||
public async Task Cut()
|
||||
{
|
||||
await _printer.CutAsync();
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
using Inspectron.Epson.PrintServer.PrintServices;
|
||||
using System.Reflection;
|
||||
using Inspectron.Epson.PrintServer.Printers.Utils;
|
||||
using Inspectron.Epson.PrintServer.PrintServices;
|
||||
|
||||
namespace Inspectron.Epson.PrintServer.Printers;
|
||||
|
||||
public class TM_U220II:IPrinter
|
||||
public class TM_U220II : IPrinter
|
||||
{
|
||||
private readonly EpsonPrinter _printer;
|
||||
|
||||
@@ -31,14 +31,20 @@ public class TM_U220II:IPrinter
|
||||
await Task.Delay(200);
|
||||
}
|
||||
|
||||
public async Task PrintTextAsync(string text)
|
||||
public async Task PrintAsync(List<PrintCommand> commands)
|
||||
{
|
||||
await _printer.PrintTextAsync(text);
|
||||
var lines = text.Split('\n').Length;
|
||||
for (int i = 0; i < lines; i++)
|
||||
foreach (var 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.FeedLinesAsync(5);
|
||||
await Task.Delay(200);
|
||||
}
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
using Inspectron.Epson.PrintServer.Printers.Utils;
|
||||
using Inspectron.Epson.PrintServer.Printers.Utils.KitchenReceipt;
|
||||
using Inspectron.Epson.PrintServer.Printers.Utils;
|
||||
using Inspectron.Epson.PrintServer.PrintServices;
|
||||
using System.Reflection;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace Inspectron.Epson.PrintServer.Printers;
|
||||
|
||||
public class TM_U220IITranslated:IPrinter
|
||||
public class TM_U220IITranslated : IPrinter
|
||||
{
|
||||
private readonly IEpsonPrinter _printer;
|
||||
|
||||
@@ -34,11 +31,8 @@ public class TM_U220IITranslated:IPrinter
|
||||
//await Task.Delay(200);
|
||||
}
|
||||
|
||||
public async Task PrintTextAsync(string text)
|
||||
public async Task PrintAsync(List<PrintCommand> commands)
|
||||
{
|
||||
var deserializedReceipt = JsonSerializer.Deserialize<KitchenReceipt>(text);
|
||||
KitchenReceiptConverter translator = new KitchenReceiptConverter(bigLineWidth: 20, lineWidth: 33);
|
||||
var commands = translator.ConvertToPrintCommands(deserializedReceipt);
|
||||
foreach (var command in commands)
|
||||
{
|
||||
await _printer.SetBiggerFontTM220(command.IsBig);
|
||||
@@ -50,7 +44,7 @@ public class TM_U220IITranslated:IPrinter
|
||||
await _printer.PrintTextAsync(command.Text + "\n");
|
||||
await Task.Delay(200);
|
||||
}
|
||||
|
||||
|
||||
await _printer.FeedLinesAsync(10);
|
||||
await Task.Delay(1000);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
using System.Text.Json;
|
||||
|
||||
namespace Inspectron.Epson.PrintServer.Printers.Utils.FinalReceipt;
|
||||
|
||||
public class FinalReceiptConverter : IReceiptConverter
|
||||
{
|
||||
private readonly int _lineWidth;
|
||||
private readonly int _bigFontLineWidth;
|
||||
|
||||
public FinalReceiptConverter(int lineWidth, int bigFontLineWidth)
|
||||
{
|
||||
_lineWidth = lineWidth;
|
||||
_bigFontLineWidth = bigFontLineWidth;
|
||||
}
|
||||
|
||||
public List<PrintCommand> Convert(string jsonContent)
|
||||
{
|
||||
var receipt = JsonSerializer.Deserialize<FinalRecipe.FinalReceipt>(jsonContent);
|
||||
var converter = new FinalRecipe.ReceiptConverter(_lineWidth, _bigFontLineWidth);
|
||||
return converter.ConvertToPrintCommands(receipt);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace Inspectron.Epson.PrintServer.Printers.Utils;
|
||||
|
||||
public interface IReceiptConverter
|
||||
{
|
||||
List<PrintCommand> Convert(string jsonContent);
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace Inspectron.Epson.PrintServer.Printers.Utils;
|
||||
|
||||
public interface IReceiptConverterFactory
|
||||
{
|
||||
IReceiptConverter Create(int receiptType, int lineWidth, int bigFontLineWidth);
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
namespace Inspectron.Epson.PrintServer.Printers.Utils;
|
||||
|
||||
public class KitchenPrintCommand
|
||||
{
|
||||
public bool IsBig { get; set; }
|
||||
public bool IsBold { get; set; }
|
||||
public bool IsRed { get; set; }
|
||||
public string Text { get; set; }
|
||||
}
|
||||
@@ -33,6 +33,13 @@ public class KitchenReceiptConverter
|
||||
string tableLine = $"Tisch: {kitchenReceipt.TableNumber}";
|
||||
commands.Add(new PrintCommand(Center(tableLine, true), true, true));
|
||||
|
||||
if (!string.IsNullOrEmpty(kitchenReceipt.SpecialInstruction))
|
||||
{
|
||||
commands.Add(new PrintCommand(""));
|
||||
commands.Add(new PrintCommand(Center(kitchenReceipt.SpecialInstruction, true), true,true));
|
||||
commands.Add(new PrintCommand(""));
|
||||
}
|
||||
|
||||
commands.Add(new PrintCommand(CreateDashedLine()));
|
||||
|
||||
|
||||
@@ -46,8 +53,7 @@ public class KitchenReceiptConverter
|
||||
commands.Add(new PrintCommand(Center($"{gang.Id}. {gang.Name}", false)) { IsRed = true });
|
||||
foreach (var dish in gang.Dishes)
|
||||
{
|
||||
string dishLine = $"{dish.Number}x {dish.Name}";
|
||||
commands.Add(new PrintCommand(dishLine));
|
||||
PrintDish(dish, commands);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,15 +64,17 @@ public class KitchenReceiptConverter
|
||||
|
||||
foreach (var dish in kitchenReceipt.Dishes)
|
||||
{
|
||||
string dishLine = $"{dish.Number}x {dish.Name}";
|
||||
commands.Add(new PrintCommand(dishLine));
|
||||
PrintDish(dish, commands);
|
||||
}
|
||||
|
||||
if (kitchenReceipt.Dishes != null && kitchenReceipt.Dishes.Any())
|
||||
{
|
||||
commands.Add(new PrintCommand(""));
|
||||
commands.Add(new PrintCommand(CreateDashedLine()));
|
||||
commands.Add(new PrintCommand(""));
|
||||
}
|
||||
|
||||
|
||||
commands.Add(new PrintCommand(""));
|
||||
commands.Add(new PrintCommand(CreateDashedLine()));
|
||||
commands.Add(new PrintCommand(""));
|
||||
|
||||
//// Additional info section
|
||||
//if (kitchenReceipt.AdditionalInfo != null && kitchenReceipt.AdditionalInfo.Count > 0)
|
||||
//{
|
||||
@@ -85,6 +93,33 @@ public class KitchenReceiptConverter
|
||||
return commands;
|
||||
}
|
||||
|
||||
private static void PrintDish(Dish dish, List<PrintCommand> commands)
|
||||
{
|
||||
string dishLine = $"{dish.Number}x {dish.Name}";
|
||||
commands.Add(new PrintCommand(dishLine));
|
||||
// Modifications
|
||||
if (dish.Modifications != null && (dish.Modifications.Removed.Any() || dish.Modifications.Added.Any()))
|
||||
{
|
||||
foreach (var removed in dish.Modifications.Removed)
|
||||
{
|
||||
commands.Add(new PrintCommand($" - {removed}", isBold:true));
|
||||
}
|
||||
|
||||
foreach (var added in dish.Modifications.Added)
|
||||
{
|
||||
commands.Add(new PrintCommand($" + {added}", isBold: true));
|
||||
}
|
||||
}
|
||||
|
||||
// SpecialInstruction
|
||||
if (!string.IsNullOrEmpty(dish.Comment))
|
||||
{
|
||||
commands.Add(new PrintCommand($" Comment: {dish.Comment}", isBold: true));
|
||||
}
|
||||
|
||||
//commands.Add(new PrintCommand($""));
|
||||
}
|
||||
|
||||
private string Center(string text, bool isBigFont)
|
||||
{
|
||||
var actualLineWidth = isBigFont ? _BigLineWidth : _lineWidth;
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
using System.Text.Json;
|
||||
|
||||
namespace Inspectron.Epson.PrintServer.Printers.Utils.KitchenReceipt;
|
||||
|
||||
public class KitchenReceiptConverterAdapter : IReceiptConverter
|
||||
{
|
||||
private readonly int _lineWidth;
|
||||
private readonly int _bigFontLineWidth;
|
||||
|
||||
public KitchenReceiptConverterAdapter(int lineWidth, int bigFontLineWidth)
|
||||
{
|
||||
_lineWidth = lineWidth;
|
||||
_bigFontLineWidth = bigFontLineWidth;
|
||||
}
|
||||
|
||||
public List<PrintCommand> Convert(string jsonContent)
|
||||
{
|
||||
var receipt = JsonSerializer.Deserialize<KitchenReceipt>(jsonContent);
|
||||
var converter = new KitchenReceiptConverter(_lineWidth, _bigFontLineWidth);
|
||||
return converter.ConvertToPrintCommands(receipt);
|
||||
}
|
||||
}
|
||||
@@ -33,8 +33,9 @@
|
||||
/// <summary>
|
||||
/// Table number
|
||||
/// </summary>
|
||||
public int TableNumber { get; set; }
|
||||
public string TableNumber { get; set; }
|
||||
|
||||
public string SpecialInstruction { get; set; }
|
||||
|
||||
public List<Gang> Gangs { get; set; } = new List<Gang>();
|
||||
|
||||
@@ -77,12 +78,22 @@
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
public Dish(){}
|
||||
|
||||
public Dish(int number, string name)
|
||||
{
|
||||
Number = number;
|
||||
Name = name;
|
||||
}
|
||||
|
||||
public DishModifications Modifications { get; set; } = new DishModifications();
|
||||
public string? Comment { get; set; }
|
||||
}
|
||||
|
||||
public class DishModifications
|
||||
{
|
||||
public List<string> Removed { get; set; } = new List<string>();
|
||||
public List<string> Added { get; set; } = new List<string>();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,95 +0,0 @@
|
||||
namespace Inspectron.Epson.PrintServer.Printers.Utils;
|
||||
|
||||
public class KitchenReceiptPrinter
|
||||
{
|
||||
private readonly int _lineWidth;
|
||||
private readonly int _bigFontLineWidth;
|
||||
|
||||
public KitchenReceiptPrinter(int lineWidth = 42, int bigFontLineWidth = 21)
|
||||
{
|
||||
_lineWidth = lineWidth;
|
||||
_bigFontLineWidth = bigFontLineWidth;
|
||||
}
|
||||
|
||||
public List<KitchenPrintCommand> ConvertToCommands(TranslatedKitchenReceipt receipt)
|
||||
{
|
||||
var commands = new List<KitchenPrintCommand>();
|
||||
|
||||
// Header: "Warme Küche" - Big, Bold, Red, Centered
|
||||
commands.Add(new KitchenPrintCommand
|
||||
{
|
||||
Text = Center(receipt.Location, isBigFont: true),
|
||||
IsBig = true,
|
||||
IsBold = true,
|
||||
IsRed = true
|
||||
});
|
||||
|
||||
commands.Add(Separator());
|
||||
|
||||
// Date and Owner info - Normal, Left-aligned
|
||||
commands.Add(new KitchenPrintCommand { Text = Center(receipt.Date,false) });
|
||||
var ownerLines = receipt.Owner.Split('\n');
|
||||
foreach (var line in ownerLines)
|
||||
{
|
||||
commands.Add(new KitchenPrintCommand { Text = Center(line, false) });
|
||||
}
|
||||
|
||||
// Table number - Big, Bold, Centered
|
||||
commands.Add(new KitchenPrintCommand
|
||||
{
|
||||
Text = Center($"Tisch: {receipt.Tisch}", isBigFont: true),
|
||||
IsBig = true,
|
||||
IsBold = true
|
||||
});
|
||||
|
||||
commands.Add(Separator());
|
||||
|
||||
// Items - Left-aligned
|
||||
foreach (var item in receipt.items)
|
||||
{
|
||||
if (item is KitchenProduct kp)
|
||||
{
|
||||
commands.Add(new KitchenPrintCommand
|
||||
{
|
||||
Text = $"{kp.Amount}x {item.Name}"
|
||||
});
|
||||
}
|
||||
if(item is KitchenGang kg)
|
||||
{
|
||||
commands.Add(new KitchenPrintCommand
|
||||
{
|
||||
IsRed = true,
|
||||
IsBig = true,
|
||||
IsBold = true,
|
||||
Text = Center(item.Name,true)
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
commands.Add(Separator());
|
||||
|
||||
return commands;
|
||||
}
|
||||
|
||||
private KitchenPrintCommand Separator()
|
||||
{
|
||||
return new KitchenPrintCommand
|
||||
{
|
||||
Text = new string('-', _lineWidth)
|
||||
};
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
using System.Text.Json;
|
||||
|
||||
namespace Inspectron.Epson.PrintServer.Printers.Utils.OrderItems;
|
||||
|
||||
public class OrderItemsReceiptConverter : IReceiptConverter
|
||||
{
|
||||
private readonly int _lineWidth;
|
||||
private readonly int _bigFontLineWidth;
|
||||
|
||||
public OrderItemsReceiptConverter(int lineWidth, int bigFontLineWidth)
|
||||
{
|
||||
_lineWidth = lineWidth;
|
||||
_bigFontLineWidth = bigFontLineWidth;
|
||||
}
|
||||
|
||||
public List<PrintCommand> Convert(string jsonContent)
|
||||
{
|
||||
var receipt = JsonSerializer.Deserialize<OrderItemsReceipt>(jsonContent);
|
||||
var converter = new ReceiptConverter(_lineWidth, _bigFontLineWidth);
|
||||
return converter.ConvertToPrintCommands(receipt);
|
||||
}
|
||||
}
|
||||
@@ -159,10 +159,10 @@ public class ReceiptConverter
|
||||
}
|
||||
}
|
||||
|
||||
// Comment
|
||||
// SpecialInstruction
|
||||
if (!string.IsNullOrEmpty(item.Comment))
|
||||
{
|
||||
commands.Add(new PrintCommand($" Comment: {item.Comment}"));
|
||||
commands.Add(new PrintCommand($" SpecialInstruction: {item.Comment}"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
using Inspectron.Epson.PrintServer.Printers.Utils.OrderItems;
|
||||
|
||||
namespace Inspectron.Epson.PrintServer.Printers.Utils;
|
||||
|
||||
public class ReceiptConverterFactory : IReceiptConverterFactory
|
||||
{
|
||||
public IReceiptConverter Create(int receiptType, int lineWidth, int bigFontLineWidth)
|
||||
{
|
||||
return (EReceiptType)receiptType switch
|
||||
{
|
||||
EReceiptType.Receipt => new FinalReceipt.FinalReceiptConverter(lineWidth, bigFontLineWidth),
|
||||
EReceiptType.WorkareaTicket => new KitchenReceipt.KitchenReceiptConverterAdapter(33, 20),
|
||||
EReceiptType.NextCourse => new KitchenReceipt.KitchenReceiptConverterAdapter(33, 20),
|
||||
EReceiptType.OrdersOverview => new OrderItemsReceiptConverter(lineWidth, bigFontLineWidth),
|
||||
_ => throw new ArgumentException($"Unknown receipt type: {receiptType}")
|
||||
};
|
||||
}
|
||||
public enum EReceiptType
|
||||
{
|
||||
Receipt,
|
||||
WorkareaTicket,
|
||||
NextCourse,
|
||||
OrdersOverview
|
||||
}
|
||||
}
|
||||
@@ -1,206 +0,0 @@
|
||||
namespace Inspectron.Epson.PrintServer.Printers.Utils;
|
||||
|
||||
|
||||
public record TranslatedKitchenReceipt(string Location, string Date, string Owner, string Tisch, List<KitchenItem> items) :ASTNode;
|
||||
public record KitchenItem(string Name) : ASTNode;
|
||||
public record KitchenProduct(int Amount, string Name) : KitchenItem(Name);
|
||||
public record KitchenGang(string Name) : KitchenItem(Name);
|
||||
|
||||
public record FinalReceipt(string Location, string Phone, string URL, string Date, List<FinalReceiptItem> items, string total, string MWST, string Comment, string Thanks) : ASTNode;
|
||||
public record FinalReceiptItem(string Name, int Amount, string Price, string Total) : ASTNode;
|
||||
|
||||
|
||||
public class ReceiptTranslator
|
||||
{
|
||||
public ASTNode ParseReceipt(string receiptText)
|
||||
{
|
||||
// Determine receipt type based on content
|
||||
bool isFinalReceipt = receiptText.Contains("http") ||
|
||||
receiptText.Contains("+41") ||
|
||||
receiptText.Contains("Summe CHF") ||
|
||||
receiptText.Contains("MWST") ||
|
||||
receiptText.Contains("Thank you");
|
||||
|
||||
bool isKitchenReceipt = receiptText.Contains("TISCH:");
|
||||
|
||||
if (isKitchenReceipt && !isFinalReceipt)
|
||||
{
|
||||
return ParseKitchenReceipt(receiptText);
|
||||
}
|
||||
else if (isFinalReceipt)
|
||||
{
|
||||
return ParseFinalReceipt(receiptText);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Default to kitchen receipt if unclear
|
||||
return ParseKitchenReceipt(receiptText);
|
||||
}
|
||||
}
|
||||
|
||||
public static FinalReceipt ParseFinalReceipt(string receiptText)
|
||||
{
|
||||
var lines = receiptText.Split('\n', StringSplitOptions.RemoveEmptyEntries)
|
||||
.Select(l => l.Trim())
|
||||
.ToList();
|
||||
|
||||
// Extract header information
|
||||
string location = lines[0];
|
||||
string phone = lines[1];
|
||||
string url = lines[2];
|
||||
|
||||
// Find and extract date
|
||||
var dateLine = lines.FirstOrDefault(l => l.StartsWith("Datum:"));
|
||||
string date = dateLine?.Replace("Datum:", "").Trim() ?? "";
|
||||
|
||||
// Find total line
|
||||
var totalLine = lines.FirstOrDefault(l => l.Contains("Summe CHF :"));
|
||||
string total = totalLine?.Split(':').Last().Trim() ?? "";
|
||||
|
||||
// Find MWST line (comes after "TOTAL MWST" header)
|
||||
var mwstLineIndex = lines.FindIndex(l => l.StartsWith("TOTAL") && l.Contains("MWST"));
|
||||
string mwst = mwstLineIndex >= 0 && mwstLineIndex + 1 < lines.Count
|
||||
? lines[mwstLineIndex + 1].Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).LastOrDefault() ?? ""
|
||||
: "";
|
||||
|
||||
// Extract comment (line after MWST values)
|
||||
string comment = mwstLineIndex >= 0 && mwstLineIndex + 2 < lines.Count
|
||||
? lines[mwstLineIndex + 2]
|
||||
: "";
|
||||
|
||||
// Extract thank you message (last non-separator line)
|
||||
string thanks = lines.LastOrDefault(l => !l.Contains("--")) ?? "";
|
||||
|
||||
// Parse items
|
||||
var items = new List<FinalReceiptItem>();
|
||||
var startIndex = lines.FindIndex(l => l.StartsWith("Datum:")) + 2; // Skip date and separator
|
||||
var endIndex = lines.FindIndex(l => l.Contains("Summe CHF"));
|
||||
|
||||
for (int i = startIndex; i < endIndex; i++)
|
||||
{
|
||||
var line = lines[i];
|
||||
|
||||
// Skip separator lines and empty lines
|
||||
if (line.Contains("---") || string.IsNullOrWhiteSpace(line))
|
||||
continue;
|
||||
|
||||
// Check if line contains item data (has * separator)
|
||||
if (line.Contains("*"))
|
||||
{
|
||||
// Parse format: "Name Amount * Price Total"
|
||||
var parts = line.Split('*');
|
||||
if (parts.Length == 2)
|
||||
{
|
||||
var leftPart = parts[0].Trim();
|
||||
var rightPart = parts[1].Trim();
|
||||
|
||||
// Extract name and amount from left part
|
||||
var leftTokens = leftPart.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
var amount = int.Parse(leftTokens.Last());
|
||||
var name = string.Join(" ", leftTokens.Take(leftTokens.Length - 1));
|
||||
|
||||
// Extract price and total from right part
|
||||
var rightTokens = rightPart.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
var price = rightTokens.Length > 0 ? rightTokens[0] : "";
|
||||
var itemTotal = rightTokens.Length > 1 ? rightTokens[1] : "";
|
||||
|
||||
items.Add(new FinalReceiptItem(name, amount, price, itemTotal));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new FinalReceipt(location, phone, url, date, items, total, mwst, comment, thanks);
|
||||
}
|
||||
|
||||
public static TranslatedKitchenReceipt ParseKitchenReceipt(string receiptText)
|
||||
{
|
||||
var lines = receiptText.Split('\n', StringSplitOptions.RemoveEmptyEntries)
|
||||
.Select(l => l.Trim())
|
||||
.ToList();
|
||||
|
||||
int currentIndex = 0;
|
||||
|
||||
// Skip optional "*** KOPIE ***" header
|
||||
if (lines[currentIndex].Contains("***"))
|
||||
{
|
||||
currentIndex++;
|
||||
}
|
||||
|
||||
// Extract location (can be any phrase)
|
||||
string location = lines[currentIndex];
|
||||
currentIndex++;
|
||||
|
||||
// Skip separator line
|
||||
while (currentIndex < lines.Count && lines[currentIndex].Contains("---"))
|
||||
{
|
||||
currentIndex++;
|
||||
}
|
||||
|
||||
// Extract date line
|
||||
string date = lines[currentIndex];
|
||||
currentIndex++;
|
||||
|
||||
// Extract owner
|
||||
string owner = "";
|
||||
do
|
||||
{
|
||||
if (owner != "")
|
||||
{
|
||||
owner += "/n";
|
||||
}
|
||||
owner += lines[currentIndex];
|
||||
currentIndex++;
|
||||
} while (!lines[currentIndex].ToLower().Contains("tisch:"));
|
||||
|
||||
|
||||
// Extract table (extract text after "TISCH:")
|
||||
string tisch = lines[currentIndex].Replace("TISCH:", "").Trim();
|
||||
currentIndex++;
|
||||
|
||||
// Skip empty lines and separators until we reach items
|
||||
while (currentIndex < lines.Count &&
|
||||
(string.IsNullOrWhiteSpace(lines[currentIndex]) || lines[currentIndex].Contains("-")))
|
||||
{
|
||||
currentIndex++;
|
||||
}
|
||||
|
||||
// Parse items
|
||||
var items = new List<KitchenItem>();
|
||||
while (currentIndex < lines.Count)
|
||||
{
|
||||
var line = lines[currentIndex];
|
||||
|
||||
// Stop at separator or end
|
||||
if (line.Contains("---") || string.IsNullOrWhiteSpace(line))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (line.ToLower().Contains(". gang"))
|
||||
{
|
||||
items.Add(new KitchenGang(line.Trim()));
|
||||
currentIndex++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Parse format: "1x Espresso" or " 1x Espresso"
|
||||
var trimmedLine = line.Trim();
|
||||
if (trimmedLine.Contains("x"))
|
||||
{
|
||||
var parts = trimmedLine.Split('x', 2);
|
||||
if (parts.Length == 2 && int.TryParse(parts[0].Trim(), out int amount))
|
||||
{
|
||||
var itemName = parts[1].Trim();
|
||||
items.Add(new KitchenProduct(amount, itemName));
|
||||
}
|
||||
}
|
||||
|
||||
currentIndex++;
|
||||
}
|
||||
|
||||
return new TranslatedKitchenReceipt(location, date, owner, tisch, items);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user