klinglers special
This commit is contained in:
@@ -44,9 +44,9 @@ using System.Text.Json;
|
|||||||
// INVOICE RECEIPT - HTML PRINTER
|
// INVOICE RECEIPT - HTML PRINTER
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
//var receipt = TestHelpers.BuildSampleInvoiceReceipt();
|
//var receipt = TestHelpers.BuildSampleInvoiceReceipt();
|
||||||
////var serializedReceipt = JsonSerializer.Serialize(receipt, new JsonSerializerOptions { WriteIndented = true });
|
//var serializedReceipt = JsonSerializer.Serialize(receipt, new JsonSerializerOptions { WriteIndented = true });
|
||||||
//var fileContent = File.ReadAllText("invoice.json");
|
////var fileContent = File.ReadAllText("invoice.json");
|
||||||
//var serializedReceipt = JsonSerializer.Deserialize<string>(fileContent);
|
////var serializedReceipt = JsonSerializer.Deserialize<string>(fileContent);
|
||||||
//var converter = new InvoiceReceiptConverter(lineWidth: 48, bigFontLineWidth: 24);
|
//var converter = new InvoiceReceiptConverter(lineWidth: 48, bigFontLineWidth: 24);
|
||||||
//var printCommands = converter.Convert(serializedReceipt);
|
//var printCommands = converter.Convert(serializedReceipt);
|
||||||
|
|
||||||
|
|||||||
@@ -251,7 +251,7 @@ public static class TestHelpers
|
|||||||
receipt.Items.Add(new Inspectron.Epson.PrintServer.Printers.Utils.InvoiceReceipt.ReceiptItem
|
receipt.Items.Add(new Inspectron.Epson.PrintServer.Printers.Utils.InvoiceReceipt.ReceiptItem
|
||||||
{
|
{
|
||||||
Quantity = 1,
|
Quantity = 1,
|
||||||
Description = "Granini Tomatensaft",
|
Description = "Granini Tomatensaft with something long to cause line wrapping more and more",
|
||||||
UnitPrice = 5.50m,
|
UnitPrice = 5.50m,
|
||||||
TotalPrice = 5.50m,
|
TotalPrice = 5.50m,
|
||||||
TaxCategory = "A"
|
TaxCategory = "A"
|
||||||
@@ -312,7 +312,7 @@ public static class TestHelpers
|
|||||||
receipt.Gangs.Add(new Gang(1, "Gang"));
|
receipt.Gangs.Add(new Gang(1, "Gang"));
|
||||||
receipt.Gangs.Add(new Gang(2, "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 with some addition to cause line wrapping")
|
||||||
{
|
{
|
||||||
Size = "XL",
|
Size = "XL",
|
||||||
Modifications = new DishModifications
|
Modifications = new DishModifications
|
||||||
@@ -321,10 +321,11 @@ public static class TestHelpers
|
|||||||
Added = new List<string> { "Extra Ginger" }
|
Added = new List<string> { "Extra Ginger" }
|
||||||
},
|
},
|
||||||
Comment = "No soy sauce",
|
Comment = "No soy sauce",
|
||||||
GuestId = 1
|
GuestId = 1,
|
||||||
|
Price = 123.45m
|
||||||
});
|
});
|
||||||
receipt.Gangs[0].Dishes.Add(new Dish(2, "Avocado Sashimi") { GuestId = 2 });
|
receipt.Gangs[0].Dishes.Add(new Dish(2, "Avocado Sashimi with some addition to cause line wrapping") { GuestId = 2 });
|
||||||
receipt.Gangs[0].Dishes.Add(new Dish(1, "Avocado Sashimi") { GuestId = 3 });
|
receipt.Gangs[0].Dishes.Add(new Dish(1, "Avocado Sashimi with some addition to cause line wrapping") { GuestId = 3 });
|
||||||
receipt.Gangs[0].Dishes.Add(new Dish(1, "Baby Spinach Salad with Truffl"){GuestId = 2});
|
receipt.Gangs[0].Dishes.Add(new Dish(1, "Baby Spinach Salad with Truffl"){GuestId = 2});
|
||||||
//receipt.Gangs[0].Dishes.Add(new Dish(1, "Beef Tataki")
|
//receipt.Gangs[0].Dishes.Add(new Dish(1, "Beef Tataki")
|
||||||
//{
|
//{
|
||||||
|
|||||||
@@ -43,24 +43,7 @@ public class ReceiptConverter
|
|||||||
// Items
|
// Items
|
||||||
foreach (var item in invoiceReceipt.Items)
|
foreach (var item in invoiceReceipt.Items)
|
||||||
{
|
{
|
||||||
string quantityDesc = $"{item.Quantity}x {item.Description}";
|
PrintItem(item, commands);
|
||||||
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));
|
|
||||||
|
|
||||||
// SubItems
|
|
||||||
if (item.SubItems != null)
|
|
||||||
{
|
|
||||||
foreach (var subItem in item.SubItems)
|
|
||||||
{
|
|
||||||
commands.Add(new PrintCommand($" - {subItem}"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
commands.Add(new PrintCommand(""));
|
commands.Add(new PrintCommand(""));
|
||||||
@@ -70,12 +53,96 @@ public class ReceiptConverter
|
|||||||
// Total
|
// Total
|
||||||
string totalLine = $"Summe: {invoiceReceipt.Total:F2} {invoiceReceipt.Currency}";
|
string totalLine = $"Summe: {invoiceReceipt.Total:F2} {invoiceReceipt.Currency}";
|
||||||
commands.Add(new PrintCommand(Center(totalLine, true), true, true));
|
commands.Add(new PrintCommand(Center(totalLine, true), true, true));
|
||||||
|
commands.Add(new PrintCommand(""));
|
||||||
commands.Add(new PrintCommand(Center($"Tisch: {invoiceReceipt.TableNumber}",false), false));
|
commands.Add(new PrintCommand(Center($"Tisch: {invoiceReceipt.TableNumber}",false), false));
|
||||||
commands.Add(new PrintCommand(Center(invoiceReceipt.ThankYouMessage, false)));
|
commands.Add(new PrintCommand(Center(invoiceReceipt.ThankYouMessage, false)));
|
||||||
|
commands.Add(new PrintCommand(""));
|
||||||
|
commands.Add(new PrintCommand(Center("Zwischenrechnung", false),isBold:true));
|
||||||
|
|
||||||
return commands;
|
return commands;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void PrintItem(ReceiptItem item, List<PrintCommand> commands)
|
||||||
|
{
|
||||||
|
string quantityPrefix = $"{item.Quantity}x ";
|
||||||
|
string prices = $"{item.UnitPrice:F2}" + $"{item.TotalPrice:F2}".PadLeft(7) + $" {item.TaxCategory}";
|
||||||
|
string fullLine = quantityPrefix + item.Description;
|
||||||
|
|
||||||
|
int spacesNeeded = _lineWidth - fullLine.Length - prices.Length;
|
||||||
|
|
||||||
|
if (spacesNeeded >= 1 || string.IsNullOrEmpty(item.Description))
|
||||||
|
{
|
||||||
|
if (spacesNeeded < 1) spacesNeeded = 1;
|
||||||
|
commands.Add(new PrintCommand(fullLine + new string(' ', spacesNeeded) + prices));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int descriptionAvailable = _lineWidth - quantityPrefix.Length - prices.Length - 1;
|
||||||
|
|
||||||
|
if (descriptionAvailable <= 0)
|
||||||
|
{
|
||||||
|
commands.Add(new PrintCommand(fullLine));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var words = item.Description.Split(' ');
|
||||||
|
var lines = new List<string>();
|
||||||
|
string currentLine = "";
|
||||||
|
|
||||||
|
foreach (var word in words)
|
||||||
|
{
|
||||||
|
if (currentLine.Length == 0)
|
||||||
|
{
|
||||||
|
currentLine = word;
|
||||||
|
}
|
||||||
|
else if (currentLine.Length + 1 + word.Length <= descriptionAvailable)
|
||||||
|
{
|
||||||
|
currentLine += " " + word;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lines.Add(currentLine);
|
||||||
|
currentLine = word;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentLine.Length > 0)
|
||||||
|
{
|
||||||
|
lines.Add(currentLine);
|
||||||
|
}
|
||||||
|
|
||||||
|
// First line with prefix and right-aligned prices
|
||||||
|
string firstLineText = quantityPrefix + lines[0];
|
||||||
|
int firstSpaces = _lineWidth - firstLineText.Length - prices.Length;
|
||||||
|
if (firstSpaces >= 1)
|
||||||
|
{
|
||||||
|
commands.Add(new PrintCommand(firstLineText + new string(' ', firstSpaces) + prices));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
commands.Add(new PrintCommand(firstLineText));
|
||||||
|
commands.Add(new PrintCommand(prices.PadLeft(_lineWidth)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Continuation lines indented to align with description
|
||||||
|
string continuationIndent = new string(' ', quantityPrefix.Length);
|
||||||
|
for (int i = 1; i < lines.Count; i++)
|
||||||
|
{
|
||||||
|
commands.Add(new PrintCommand(continuationIndent + lines[i]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SubItems
|
||||||
|
if (item.SubItems != null)
|
||||||
|
{
|
||||||
|
foreach (var subItem in item.SubItems)
|
||||||
|
{
|
||||||
|
commands.Add(new PrintCommand($" - {subItem}"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private string Center(string text, bool isBigFont)
|
private string Center(string text, bool isBigFont)
|
||||||
{
|
{
|
||||||
int effectiveLineWidth = isBigFont ? _bigFontLineWidth : _lineWidth;
|
int effectiveLineWidth = isBigFont ? _bigFontLineWidth : _lineWidth;
|
||||||
|
|||||||
@@ -99,6 +99,7 @@ public class KitchenReceiptConverterKlinglers
|
|||||||
if (!string.IsNullOrEmpty(dish.Size)) return false;
|
if (!string.IsNullOrEmpty(dish.Size)) return false;
|
||||||
if (!string.IsNullOrEmpty(dish.Comment)) 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.Modifications != null && (dish.Modifications.Removed.Any() || dish.Modifications.Added.Any())) return false;
|
||||||
|
if (dish.Price != null) return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -117,11 +118,11 @@ public class KitchenReceiptConverterKlinglers
|
|||||||
int totalQuantity = group.Sum(d => d.Number);
|
int totalQuantity = group.Sum(d => d.Number);
|
||||||
var guestIds = group
|
var guestIds = group
|
||||||
.Where(d => d.GuestId.HasValue)
|
.Where(d => d.GuestId.HasValue)
|
||||||
.Select(d => d.GuestId.Value)
|
.SelectMany(d => Enumerable.Repeat(d.GuestId!.Value, d.Number))
|
||||||
.OrderBy(id => id)
|
.OrderBy(id => id)
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
PrintDishLine($"{totalQuantity}x ", group.Key, null, commands);
|
PrintDishLine($"{totalQuantity}x ", group.Key, null, null, commands);
|
||||||
|
|
||||||
if (guestIds.Any())
|
if (guestIds.Any())
|
||||||
{
|
{
|
||||||
@@ -133,7 +134,7 @@ public class KitchenReceiptConverterKlinglers
|
|||||||
// Print individual dishes (have size, modifications, or comment)
|
// Print individual dishes (have size, modifications, or comment)
|
||||||
foreach (var dish in individual)
|
foreach (var dish in individual)
|
||||||
{
|
{
|
||||||
PrintDishLine($"{dish.Number}x ", dish.Name, dish.Size, commands);
|
PrintDishLine($"{dish.Number}x ", dish.Name, dish.Size, dish.Price, commands);
|
||||||
|
|
||||||
if (dish.GuestId.HasValue)
|
if (dish.GuestId.HasValue)
|
||||||
{
|
{
|
||||||
@@ -160,67 +161,88 @@ public class KitchenReceiptConverterKlinglers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PrintDishLine(string quantityPrefix, string dishName, string? size, List<PrintCommand> commands)
|
private void PrintDishLine(string quantityPrefix, string dishName, string? size, decimal? price, List<PrintCommand> commands)
|
||||||
{
|
{
|
||||||
string fullLine = quantityPrefix + dishName;
|
string? priceStr = price != null ? price.Value.ToString("0.00") : null;
|
||||||
|
|
||||||
|
string nameWithSize = dishName;
|
||||||
if (!string.IsNullOrEmpty(size))
|
if (!string.IsNullOrEmpty(size))
|
||||||
{
|
{
|
||||||
fullLine += $" ({size})";
|
nameWithSize += $" ({size})";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fullLine.Length <= _lineWidth || string.IsNullOrEmpty(dishName))
|
int firstLineNameWidth = _lineWidth - quantityPrefix.Length - 6;
|
||||||
|
if (priceStr != null)
|
||||||
{
|
{
|
||||||
commands.Add(new PrintCommand(fullLine) { IsTall = true });
|
firstLineNameWidth -= priceStr.Length + 1;
|
||||||
}
|
}
|
||||||
else
|
int continuationNameWidth = _lineWidth - quantityPrefix.Length - 6;
|
||||||
|
|
||||||
|
// Simple case: name fits on first line
|
||||||
|
if (nameWithSize.Length <= firstLineNameWidth || string.IsNullOrEmpty(dishName))
|
||||||
{
|
{
|
||||||
int availableWidth = _lineWidth - quantityPrefix.Length;
|
string line = quantityPrefix + nameWithSize;
|
||||||
if (availableWidth <= 0)
|
if (priceStr != null)
|
||||||
{
|
{
|
||||||
commands.Add(new PrintCommand(fullLine) { IsTall = true });
|
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
|
else
|
||||||
{
|
{
|
||||||
string nameWithSize = dishName;
|
lines.Add(currentLine);
|
||||||
if (!string.IsNullOrEmpty(size))
|
currentLine = word;
|
||||||
{
|
currentMaxWidth = continuationNameWidth;
|
||||||
nameWithSize += $" ({size})";
|
|
||||||
}
|
|
||||||
var words = nameWithSize.Split(' ');
|
|
||||||
var lines = new List<string>();
|
|
||||||
string currentLine = "";
|
|
||||||
|
|
||||||
foreach (var word in words)
|
|
||||||
{
|
|
||||||
if (currentLine.Length == 0)
|
|
||||||
{
|
|
||||||
currentLine = word;
|
|
||||||
}
|
|
||||||
else if (currentLine.Length + 1 + word.Length <= availableWidth)
|
|
||||||
{
|
|
||||||
currentLine += " " + word;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
lines.Add(currentLine);
|
|
||||||
currentLine = word;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentLine.Length > 0)
|
|
||||||
{
|
|
||||||
lines.Add(currentLine);
|
|
||||||
}
|
|
||||||
|
|
||||||
commands.Add(new PrintCommand(quantityPrefix + lines[0]) { IsTall = true });
|
|
||||||
string indent = new string(' ', quantityPrefix.Length);
|
|
||||||
for (int i = 1; i < lines.Count; i++)
|
|
||||||
{
|
|
||||||
commands.Add(new PrintCommand(indent + lines[i]) { IsTall = true });
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
private string Center(string text, bool isBigFont)
|
||||||
|
|||||||
@@ -84,6 +84,7 @@
|
|||||||
|
|
||||||
public DishModifications Modifications { get; set; } = new DishModifications();
|
public DishModifications Modifications { get; set; } = new DishModifications();
|
||||||
public string? Comment { get; set; }
|
public string? Comment { get; set; }
|
||||||
|
public decimal? Price { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class DishModifications
|
public class DishModifications
|
||||||
|
|||||||
Reference in New Issue
Block a user