namespace Inspectron.Epson.PrintServer.Printers.Utils.KitchenReceipt; public class KitchenReceiptConverterKlinglers { private readonly int _lineWidth; private readonly int _BigLineWidth; public KitchenReceiptConverterKlinglers(int lineWidth = 42, int bigLineWidth = 22) { _BigLineWidth = bigLineWidth; _lineWidth = lineWidth; } public List ConvertToPrintCommands(KitchenReceipt kitchenReceipt) { var commands = new List(); // Header - Restaurant name in red commands.Add(new PrintCommand(Center(kitchenReceipt.Title, true)) { IsRed = true, IsBig = true, IsTall = true }); commands.Add(new PrintCommand(CreateDashedLine())); commands.Add(new PrintCommand("")); // Transaction info string dateTimeLine = $"{kitchenReceipt.TransactionDateTime:dd-MMM-yy HH:mm} Nr.:{kitchenReceipt.ReceiptNumber}"; commands.Add(new PrintCommand(Center(dateTimeLine, false))); string serverLine = $"{kitchenReceipt.WaiterName}"; commands.Add(new PrintCommand(Center(serverLine, false))); //string serverIdLine = $"{kitchenReceipt.WaiterId}"; //commands.Add(new PrintCommand(Center(serverIdLine, false))); 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())); // Gangs foreach (Gang gang in kitchenReceipt.Gangs) { commands.Add(new PrintCommand(Center($"{gang.Id}. {gang.Name}", true)) { IsRed = true, IsBig = true, IsTall = true }); PrintGroupedDishes(gang.Dishes, commands); if (gang != kitchenReceipt.Gangs.Last()) { commands.Add(new PrintCommand("") { IsCut = true }); commands.Add(new PrintCommand("")); commands.Add(new PrintCommand("")); } } if (kitchenReceipt.Gangs.Count > 0) { commands.Add(new PrintCommand(CreateDashedLine())); } PrintGroupedDishes(kitchenReceipt.Dishes, commands); if (kitchenReceipt.Dishes != null && kitchenReceipt.Dishes.Any()) { commands.Add(new PrintCommand("")); commands.Add(new PrintCommand(CreateDashedLine())); commands.Add(new PrintCommand("")); } //// Additional info section //if (kitchenReceipt.AdditionalInfo != null && kitchenReceipt.AdditionalInfo.Count > 0) //{ // commands.Add(new PrintCommand(CreateAsterisksLine())); // commands.Add(new PrintCommand("Info über zugehörige Artikel")); // commands.Add(new PrintCommand(CreateAsterisksLine())); // foreach (var info in kitchenReceipt.AdditionalInfo) // { // commands.Add(new PrintCommand(info)); // } // commands.Add(new PrintCommand("")); //} return commands; } private static bool IsGroupable(Dish dish) { if (!string.IsNullOrEmpty(dish.Size)) return false; if (!string.IsNullOrEmpty(dish.Comment)) return false; if (dish.Modifications != null && (dish.Modifications.Removed.Any() || dish.Modifications.Added.Any())) return false; if (dish.Price != null) return false; return true; } private void PrintGroupedDishes(List dishes, List commands) { var groupable = dishes.Where(IsGroupable).ToList(); var individual = dishes.Where(d => !IsGroupable(d)).ToList(); // Print grouped dishes var groups = groupable .GroupBy(d => d.Name) .ToList(); foreach (var group in groups) { int totalQuantity = group.Sum(d => d.Number); var guestIds = group .Where(d => d.GuestId.HasValue) .SelectMany(d => Enumerable.Repeat(d.GuestId!.Value, d.Number)) .OrderBy(id => id) .ToList(); PrintDishLine($"{totalQuantity}x ", group.Key, null, null, commands); if (guestIds.Any()) { string guestLine = $"({string.Join(",", guestIds)})"; commands.Add(new PrintCommand(guestLine, isBold: true) { IsTall = true }); } } // Print individual dishes (have size, modifications, or comment) foreach (var dish in individual) { PrintDishLine($"{dish.Number}x ", dish.Name, dish.Size, dish.Price, commands); if (dish.GuestId.HasValue) { string guestLine = $"({dish.GuestId.Value})"; commands.Add(new PrintCommand(guestLine, isBold: true) { IsTall = true }); } 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) { IsTall = true }); } foreach (var added in dish.Modifications.Added) { commands.Add(new PrintCommand($" + {added}", isBold: true) { IsTall = true }); } } if (!string.IsNullOrEmpty(dish.Comment)) { commands.Add(new PrintCommand($"Comment: {dish.Comment}", isBold: true) { IsTall = true }); } } } private void PrintDishLine(string quantityPrefix, string dishName, string? size, decimal? price, List commands) { string? priceStr = price != null ? price.Value.ToString("0.00") : null; string nameWithSize = dishName; if (!string.IsNullOrEmpty(size)) { nameWithSize += $" ({size})"; } int firstLineNameWidth = _lineWidth - quantityPrefix.Length - 6; if (priceStr != null) { firstLineNameWidth -= priceStr.Length + 1; } int continuationNameWidth = _lineWidth - quantityPrefix.Length - 6; // Simple case: name fits on first line if (nameWithSize.Length <= firstLineNameWidth || string.IsNullOrEmpty(dishName)) { string line = quantityPrefix + nameWithSize; if (priceStr != null) { int padding = _lineWidth - line.Length - priceStr.Length; line += new string(' ', Math.Max(1, padding)) + priceStr; } commands.Add(new PrintCommand(line) { IsTall = true }); return; } if (firstLineNameWidth <= 0) { string line = quantityPrefix + nameWithSize; if (priceStr != null) line += " " + priceStr; commands.Add(new PrintCommand(line) { IsTall = true }); return; } // Word wrap var words = nameWithSize.Split(' '); var lines = new List(); string currentLine = ""; int currentMaxWidth = firstLineNameWidth; foreach (var word in words) { if (currentLine.Length == 0) { currentLine = word; } else if (currentLine.Length + 1 + word.Length <= currentMaxWidth) { currentLine += " " + word; } else { lines.Add(currentLine); currentLine = word; currentMaxWidth = continuationNameWidth; } } if (currentLine.Length > 0) { lines.Add(currentLine); } // First line with prefix and optional right-aligned price string firstLine = quantityPrefix + lines[0]; if (priceStr != null) { int padding = _lineWidth - firstLine.Length - priceStr.Length; firstLine += new string(' ', Math.Max(1, padding)) + priceStr; } commands.Add(new PrintCommand(firstLine) { IsTall = true }); // Continuation lines string indent = new string(' ', quantityPrefix.Length); for (int i = 1; i < lines.Count; i++) { commands.Add(new PrintCommand(indent + lines[i]) { IsTall = true }); } } private string Center(string text, bool isBigFont) { var actualLineWidth = isBigFont ? _BigLineWidth : _lineWidth; if (string.IsNullOrEmpty(text) || text.Length >= actualLineWidth) return text; int totalPadding = actualLineWidth - text.Length; int leftPadding = totalPadding / 2; return new string(' ', leftPadding) + text; } private string CreateDashedLine() { return new string('-', _lineWidth); } private string CreateAsterisksLine() { return new string('*', _lineWidth); } }