Files
Print_server/Inspectron.Epson/PrintServer/Printers/Utils/KitchenReceipt/KitchenReceiptConverterKlinglers.cs
2026-02-25 10:35:20 +01:00

269 lines
9.1 KiB
C#

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<PrintCommand> ConvertToPrintCommands(KitchenReceipt kitchenReceipt)
{
var commands = new List<PrintCommand>();
// 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<Dish> dishes, List<PrintCommand> 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<PrintCommand> 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>();
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);
}
}