1320 lines
48 KiB
C#
1320 lines
48 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using PdfSharp;
|
|
using PdfSharp.Drawing;
|
|
using PdfSharp.Fonts;
|
|
using PdfSharp.Pdf;
|
|
|
|
namespace Logof_Client;
|
|
|
|
public class PdfBuilder
|
|
{
|
|
private readonly PdfExportSettings _settings;
|
|
private readonly XFont _boldFont;
|
|
private readonly XFont _regularFont;
|
|
private readonly XFont _smallFont;
|
|
|
|
public PdfBuilder(PdfExportSettings? settings = null)
|
|
{
|
|
try
|
|
{
|
|
EnsureFontResolverRegistered();
|
|
_settings = settings ?? new PdfExportSettings();
|
|
|
|
// Select first font from build output fonts folder (AppContext.BaseDirectory/fonts)
|
|
var chosenFamily = "Arial";
|
|
try
|
|
{
|
|
if (Directory.Exists(Global._instance.font_path))
|
|
{
|
|
var first = Directory.EnumerateFiles(Global._instance.font_path, "*.ttf").FirstOrDefault();
|
|
if (!string.IsNullOrEmpty(first))
|
|
chosenFamily = StripStyleSuffix(Path.GetFileNameWithoutExtension(first)) ?? chosenFamily;
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Logger.Log($"Error while searching for fonts: {ex.Message}",Logger.LogType.Error);
|
|
chosenFamily = "Arial";
|
|
}
|
|
|
|
_boldFont = new XFont(chosenFamily, _settings.fontSize, XFontStyleEx.Bold);
|
|
_regularFont = new XFont(chosenFamily, _settings.fontSize, XFontStyleEx.Regular);
|
|
_smallFont = new XFont(chosenFamily, _settings.smallFontSize, XFontStyleEx.Regular);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Logger.Log($"Error while font resolving: {ex.Message}",Logger.LogType.Error);
|
|
}
|
|
|
|
|
|
}
|
|
|
|
private static void EnsureFontResolverRegistered()
|
|
{
|
|
try
|
|
{
|
|
if (GlobalFontSettings.FontResolver != null) return;
|
|
//var fontsDir = Path.Combine(AppContext.BaseDirectory, "fonts");
|
|
GlobalFontSettings.FontResolver = new StableFontResolver(Global._instance.font_path);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Logger.Log($"Error while ensuring font resolver register state: {ex.Message}",Logger.LogType.Error);
|
|
}
|
|
|
|
}
|
|
|
|
private static string StripStyleSuffix(string name)
|
|
{
|
|
try
|
|
{
|
|
if (string.IsNullOrEmpty(name)) return name;
|
|
var idx = name.IndexOf('-');
|
|
if (idx < 0) idx = name.IndexOf('_');
|
|
if (idx > 0)
|
|
return name.Substring(0, idx);
|
|
return name;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Logger.Log($"Error while stripping style suffix: {ex.Message}",Logger.LogType.Error);
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Creates a PDF document with address stickers from an AddressSet with a placeholder in the first cell.
|
|
/// </summary>
|
|
/// <param name="addressSetId">The ID of the AddressSet to use</param>
|
|
/// <param name="placeholderText">Text for the first cell (top-left)</param>
|
|
/// <param name="outputPath">Path where the PDF should be saved</param>
|
|
public void CreateAddressLabelPdfFromAddressSetWithPlaceholder(int addressSetId, string placeholderText,
|
|
string outputPath)
|
|
{
|
|
try
|
|
{
|
|
// Find the AddressSet by ID
|
|
var addressSet = Settings._instance.addressSets.GetAddressSetByID(addressSetId);
|
|
// foreach (var pers in addressSet.KasPersons)
|
|
// {
|
|
// AddressCreator.CreateFinalMarkdownString(pers.id);
|
|
// }
|
|
// addressSet.KasPersons = addressSet.KasPersons.OrderBy(x => x.IsGermany()).ThenBy(y => y.used_plz).ToList();
|
|
|
|
if (addressSet == null)
|
|
throw new ArgumentException($"AddressSet with ID {addressSetId} not found");
|
|
|
|
if (addressSet.KasPersons == null || addressSet.KasPersons.Count == 0)
|
|
throw new ArgumentException($"AddressSet with ID {addressSetId} contains no addresses");
|
|
|
|
// Generate markdown addresses from all KasPersons in the set
|
|
//var addresses = new string?[addressSet.KasPersons.Count];
|
|
var addresses_german = new List<string>();
|
|
var addresses_inter = new List<string>();
|
|
|
|
// find customer (owner) to include sender_address
|
|
string senderLine = null;
|
|
try
|
|
{
|
|
var owner = Settings._instance.customers.customers.FirstOrDefault(c => c.ID == addressSet.owner_id);
|
|
if (owner != null && !string.IsNullOrWhiteSpace(owner.sender_address))
|
|
senderLine = "<font6>" + owner.sender_address.Replace("\n", " ").Trim() + "\\n";
|
|
}
|
|
catch
|
|
{
|
|
senderLine = null;
|
|
}
|
|
|
|
// national addresses
|
|
for (var i = 0; i < addressSet.KasPersons.Count; i++)
|
|
{
|
|
string senderLineID = senderLine;
|
|
if (!addressSet.KasPersons[i].IsGermany()) continue;
|
|
var addr = AddressCreator.CreateFinalMarkdownString(addressSet.KasPersons[i].id);
|
|
if (string.IsNullOrWhiteSpace(addr)) continue;
|
|
if (addressSet.KasPersons[i].refsid != null || addressSet.KasPersons[i].refsid != 0)
|
|
senderLineID += $"ID: {addressSet.KasPersons[i].refsid}\n</font6>";
|
|
else
|
|
senderLineID += "\n</font6>";
|
|
if (!string.IsNullOrEmpty(senderLineID))
|
|
addresses_german.Add(senderLineID + (addr ?? ""));
|
|
else
|
|
addresses_german.Add(addr);
|
|
}
|
|
|
|
// international addresses
|
|
for (var i = 0; i < addressSet.KasPersons.Count; i++)
|
|
{
|
|
string senderLineID = senderLine;
|
|
if (addressSet.KasPersons[i].IsGermany()) continue;
|
|
var addr = AddressCreator.CreateFinalMarkdownString(addressSet.KasPersons[i].id);
|
|
if (string.IsNullOrWhiteSpace(addr)) continue;
|
|
if (addressSet.KasPersons[i].refsid != null || addressSet.KasPersons[i].refsid != 0)
|
|
senderLineID += $"ID: {addressSet.KasPersons[i].refsid}\n</font6>";
|
|
else
|
|
senderLineID += "\n</font6>";
|
|
if (!string.IsNullOrEmpty(senderLineID))
|
|
addresses_inter.Add(senderLineID + (addr ?? ""));
|
|
else
|
|
addresses_inter.Add(addr);
|
|
}
|
|
|
|
|
|
|
|
if (addresses_german.Count == 0 && addresses_inter.Count == 0)
|
|
{
|
|
MessageBox.Show(MainWindow._instance, "Keine validen Adressen konnten generiert werden. Abbruch.", "Fehler");
|
|
return;
|
|
}
|
|
|
|
string output_inter = outputPath.Replace(".pdf", "-international.pdf");
|
|
|
|
if(addresses_german.Count > 0) CreateAddressLabelPdfWithPlaceholder(addresses_german, placeholderText, outputPath);
|
|
if(addresses_inter.Count > 0) CreateAddressLabelPdfWithPlaceholder(addresses_inter, placeholderText, output_inter);
|
|
|
|
if (_settings.exportRunningSheets)
|
|
{
|
|
ExportRunningSheets(addressSetId, outputPath);
|
|
}
|
|
//CreateAddressLabelPdfWithPlaceholder(addresses_german, placeholderText, outputPath);
|
|
//CreateAddressLabelPdfWithPlaceholder(addresses_inter, placeholderText, output_inter);
|
|
|
|
|
|
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Logger.Log($"Error while creating address label pdf from address set with placeholder: {ex.Message}",Logger.LogType.Error);
|
|
}
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates a PDF document with a single placeholder cell for other information.
|
|
/// </summary>
|
|
/// <param name="addresses">Array of addresses</param>
|
|
/// <param name="placeholderText">Text for the first cell (top-left)</param>
|
|
/// <param name="outputPath">Path where the PDF should be saved</param>
|
|
public void CreateAddressLabelPdfWithPlaceholder(List<string> addresses, string placeholderText, string outputPath)
|
|
{
|
|
try
|
|
{
|
|
if (addresses == null || addresses.Count == 0)
|
|
throw new ArgumentException("Addresses array cannot be null or empty");
|
|
|
|
var document = new PdfDocument();
|
|
|
|
var addressIndex = 0;
|
|
var isFirstCell = true;
|
|
|
|
while (addressIndex < addresses.Count || isFirstCell)
|
|
{
|
|
var page = document.AddPage();
|
|
page.Size = PageSize.A4;
|
|
|
|
using (var gfx = XGraphics.FromPdfPage(page))
|
|
{
|
|
DrawPageWithPlaceholder(gfx, addresses, ref addressIndex, ref isFirstCell, placeholderText);
|
|
}
|
|
}
|
|
|
|
document.Save(outputPath);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Logger.Log($"Error while creating address label pdf with placeholder: {ex.Message}",Logger.LogType.Error);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
private void DrawPageWithPlaceholder(XGraphics gfx, List<string> addresses, ref int addressIndex,
|
|
ref bool isFirstCell, string placeholderText)
|
|
{
|
|
try
|
|
{
|
|
for (var row = 0; row < _settings.rowsPerPage; row++)
|
|
for (var col = 0; col < _settings.columnsPerPage; col++)
|
|
{
|
|
var x = MmToPoints(_settings.pageMarginLeftMm + col * GetCellWidthMm());
|
|
var y = MmToPoints(_settings.pageMarginTopMm + row * GetCellHeightMm());
|
|
|
|
// First cell: placeholder
|
|
if (isFirstCell)
|
|
{
|
|
DrawCell(gfx, x, y, placeholderText);
|
|
isFirstCell = false;
|
|
}
|
|
else if (addressIndex < addresses.Count)
|
|
{
|
|
DrawCell(gfx, x, y, addresses[addressIndex]);
|
|
addressIndex++;
|
|
}
|
|
else
|
|
{
|
|
DrawEmptyCell(gfx, x, y);
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Logger.Log($"Error while drawing page with placholder: {ex.Message}",Logger.LogType.Error);
|
|
}
|
|
|
|
}
|
|
|
|
private void DrawCell(XGraphics gfx, double x, double y, string? address)
|
|
{
|
|
try
|
|
{
|
|
var cellWidthPoints = MmToPoints(GetCellWidthMm());
|
|
var cellHeightPoints = MmToPoints(GetCellHeightMm());
|
|
|
|
// Draw cell border
|
|
var rect = new XRect(x, y, cellWidthPoints, cellHeightPoints);
|
|
gfx.DrawRectangle(XPens.Black, rect);
|
|
|
|
// Draw address content if available
|
|
if (!string.IsNullOrEmpty(address)) DrawMarkdownText(gfx, address, x, y, cellWidthPoints, cellHeightPoints);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Logger.Log($"Error while drawing cell: {ex.Message}",Logger.LogType.Error);
|
|
}
|
|
|
|
}
|
|
|
|
private void DrawEmptyCell(XGraphics gfx, double x, double y)
|
|
{
|
|
try
|
|
{
|
|
var cellWidthPoints = MmToPoints(GetCellWidthMm());
|
|
var cellHeightPoints = MmToPoints(GetCellHeightMm());
|
|
|
|
var rect = new XRect(x, y, cellWidthPoints, cellHeightPoints);
|
|
gfx.DrawRectangle(XPens.Black, rect);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Logger.Log($"Error while drawing empty cell: {ex.Message}",Logger.LogType.Error);
|
|
}
|
|
|
|
}
|
|
|
|
private enum TextStyle
|
|
{
|
|
Regular,
|
|
Bold,
|
|
Small
|
|
}
|
|
|
|
private sealed class TextToken
|
|
{
|
|
public string Text { get; }
|
|
public TextStyle Style { get; }
|
|
public bool LineBreak { get; }
|
|
|
|
public TextToken(string text, TextStyle style, bool lineBreak = false)
|
|
{
|
|
Text = text;
|
|
Style = style;
|
|
LineBreak = lineBreak;
|
|
}
|
|
}
|
|
|
|
private sealed class TextRun
|
|
{
|
|
public string Text { get; set; } = "";
|
|
public XFont Font { get; set; } = null!;
|
|
public bool LineBreakAfter { get; set; }
|
|
}
|
|
|
|
private void DrawMarkdownText(XGraphics gfx, string text, double x, double y, double cellWidth, double cellHeight)
|
|
{
|
|
try
|
|
{
|
|
var paddingLeftPoints = MmToPoints(_settings.cellPaddingLeftMm);
|
|
var paddingRightPoints = MmToPoints(_settings.cellPaddingRightMm);
|
|
var paddingTopPoints = MmToPoints(_settings.cellPaddingTopMm);
|
|
var paddingBottomPoints = MmToPoints(_settings.cellPaddingBottomMm);
|
|
|
|
var maxWidth = Math.Max(0, cellWidth - paddingLeftPoints - paddingRightPoints);
|
|
var maxHeight = Math.Max(0, cellHeight - paddingTopPoints - paddingBottomPoints);
|
|
|
|
var runs = ParseStyledText(text);
|
|
var lines = WrapRunsToLines(gfx, runs, maxWidth);
|
|
|
|
var currentY = y + paddingTopPoints;
|
|
var bottomLimit = y + paddingTopPoints + maxHeight;
|
|
|
|
foreach (var line in lines)
|
|
{
|
|
var lineHeight = GetLineHeightForRuns(line);
|
|
|
|
if (currentY + lineHeight > bottomLimit + 0.001)
|
|
break;
|
|
|
|
DrawLineRuns(gfx, line, x + paddingLeftPoints, currentY);
|
|
currentY += lineHeight;
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Logger.Log($"Error while drawing markdown text: {ex.Message}", Logger.LogType.Error);
|
|
}
|
|
}
|
|
|
|
private List<TextToken> ParseStyledText(string text)
|
|
{
|
|
var tokens = new List<TextToken>();
|
|
if (string.IsNullOrEmpty(text))
|
|
return tokens;
|
|
|
|
var i = 0;
|
|
var style = TextStyle.Regular;
|
|
var buffer = new System.Text.StringBuilder();
|
|
|
|
void FlushBuffer()
|
|
{
|
|
if (buffer.Length > 0)
|
|
{
|
|
tokens.Add(new TextToken(buffer.ToString(), style));
|
|
buffer.Clear();
|
|
}
|
|
}
|
|
|
|
while (i < text.Length)
|
|
{
|
|
if (text[i] == '\r')
|
|
{
|
|
i++;
|
|
continue;
|
|
}
|
|
|
|
if (text[i] == '\n')
|
|
{
|
|
FlushBuffer();
|
|
tokens.Add(new TextToken("", style, lineBreak: true));
|
|
i++;
|
|
continue;
|
|
}
|
|
|
|
if (i <= text.Length - 7 && text.Substring(i, 7) == "<font6>")
|
|
{
|
|
FlushBuffer();
|
|
style = TextStyle.Small;
|
|
i += 7;
|
|
continue;
|
|
}
|
|
|
|
if (i <= text.Length - 8 && text.Substring(i, 8) == "</font6>")
|
|
{
|
|
FlushBuffer();
|
|
style = TextStyle.Regular;
|
|
i += 8;
|
|
continue;
|
|
}
|
|
|
|
if (i < text.Length - 1 && text[i] == '*' && text[i + 1] == '*')
|
|
{
|
|
FlushBuffer();
|
|
style = style == TextStyle.Bold ? TextStyle.Regular : TextStyle.Bold;
|
|
i += 2;
|
|
continue;
|
|
}
|
|
|
|
if (i < text.Length - 1 && text[i] == '\\' && text[i + 1] == 'n')
|
|
{
|
|
FlushBuffer();
|
|
tokens.Add(new TextToken("", style, lineBreak: true));
|
|
i += 2;
|
|
continue;
|
|
}
|
|
|
|
buffer.Append(text[i]);
|
|
i++;
|
|
}
|
|
|
|
FlushBuffer();
|
|
return tokens;
|
|
}
|
|
|
|
private double GetLineHeightForRuns(IEnumerable<TextRun> line)
|
|
{
|
|
double max = 0;
|
|
|
|
foreach (var run in line)
|
|
{
|
|
if (run.Font != null)
|
|
{
|
|
var h = run.Font.GetHeight();
|
|
if (h > max) max = h;
|
|
}
|
|
}
|
|
|
|
return max > 0 ? max * 0.8 : _regularFont.GetHeight();
|
|
}
|
|
|
|
private List<List<TextRun>> WrapRunsToLines(XGraphics gfx, List<TextToken> tokens, double maxWidth)
|
|
{
|
|
var lines = new List<List<TextRun>>();
|
|
var currentLine = new List<TextRun>();
|
|
double currentWidth = 0;
|
|
|
|
void PushLine()
|
|
{
|
|
lines.Add(currentLine);
|
|
currentLine = new List<TextRun>();
|
|
currentWidth = 0;
|
|
}
|
|
|
|
foreach (var token in tokens)
|
|
{
|
|
if (token.LineBreak)
|
|
{
|
|
PushLine();
|
|
continue;
|
|
}
|
|
|
|
var font = token.Style switch
|
|
{
|
|
TextStyle.Bold => _boldFont,
|
|
TextStyle.Small => _smallFont,
|
|
_ => _regularFont
|
|
};
|
|
|
|
var parts = token.Text.Split('\n');
|
|
|
|
for (int p = 0; p < parts.Length; p++)
|
|
{
|
|
var part = parts[p];
|
|
if (part.Length > 0)
|
|
{
|
|
var remaining = part;
|
|
|
|
while (!string.IsNullOrEmpty(remaining))
|
|
{
|
|
var available = maxWidth - currentWidth;
|
|
if (available <= 0.001)
|
|
{
|
|
PushLine();
|
|
available = maxWidth;
|
|
}
|
|
|
|
var fit = FitTextToWidth(gfx, remaining, font, available);
|
|
if (string.IsNullOrEmpty(fit))
|
|
{
|
|
PushLine();
|
|
continue;
|
|
}
|
|
|
|
currentLine.Add(new TextRun
|
|
{
|
|
Text = fit,
|
|
Font = font
|
|
});
|
|
|
|
currentWidth += gfx.MeasureString(fit, font).Width;
|
|
remaining = remaining.Substring(fit.Length);
|
|
|
|
if (!string.IsNullOrEmpty(remaining))
|
|
PushLine();
|
|
}
|
|
}
|
|
|
|
if (p < parts.Length - 1)
|
|
PushLine();
|
|
}
|
|
}
|
|
|
|
if (currentLine.Count > 0 || lines.Count == 0)
|
|
lines.Add(currentLine);
|
|
|
|
return lines;
|
|
}
|
|
|
|
private void DrawLineRuns(XGraphics gfx, List<TextRun> line, double x, double y)
|
|
{
|
|
try
|
|
{
|
|
var currentX = x;
|
|
|
|
foreach (var run in line)
|
|
{
|
|
if (string.IsNullOrEmpty(run.Text))
|
|
continue;
|
|
|
|
gfx.DrawString(
|
|
run.Text,
|
|
run.Font,
|
|
XBrushes.Black,
|
|
new XRect(currentX, y, 10000, run.Font.Size * 1.2),
|
|
XStringFormats.TopLeft);
|
|
|
|
currentX += gfx.MeasureString(run.Text, run.Font).Width;
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Logger.Log($"Error while drawing markdown line: {ex.Message}", Logger.LogType.Error);
|
|
}
|
|
}
|
|
|
|
private string FitTextToWidth(XGraphics gfx, string text, XFont font, double maxWidth)
|
|
{
|
|
if (string.IsNullOrEmpty(text))
|
|
return "";
|
|
|
|
if (gfx.MeasureString(text, font).Width <= maxWidth)
|
|
return text;
|
|
|
|
var lo = 0;
|
|
var hi = text.Length;
|
|
while (lo < hi)
|
|
{
|
|
var mid = (lo + hi + 1) / 2;
|
|
var candidate = text.Substring(0, mid);
|
|
if (gfx.MeasureString(candidate, font).Width <= maxWidth)
|
|
lo = mid;
|
|
else
|
|
hi = mid - 1;
|
|
}
|
|
|
|
return lo > 0 ? text.Substring(0, lo) : "";
|
|
}
|
|
private string TruncateTextToWidth(XGraphics gfx, string text, XFont font, double maxWidth)
|
|
{
|
|
try
|
|
{
|
|
if (string.IsNullOrEmpty(text))
|
|
return text;
|
|
|
|
for (var len = text.Length; len > 0; len--)
|
|
{
|
|
var truncated = text.Substring(0, len);
|
|
var measured = gfx.MeasureString(truncated, font);
|
|
if (measured.Width <= maxWidth)
|
|
return truncated;
|
|
}
|
|
|
|
return string.Empty;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Logger.Log($"Error while truncating text to width: {ex.Message}",Logger.LogType.Error);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Converts millimeters to points (1 mm = 2.834645669 points)
|
|
/// </summary>
|
|
private double MmToPoints(double mm)
|
|
{
|
|
return mm * 2.834645669;
|
|
}
|
|
|
|
private double GetCellWidthMm()
|
|
{
|
|
var availableWidthMm = 210d - _settings.pageMarginLeftMm - _settings.pageMarginRightMm;
|
|
return availableWidthMm / _settings.columnsPerPage;
|
|
}
|
|
|
|
private double GetCellHeightMm()
|
|
{
|
|
var availableHeightMm = 297d - _settings.pageMarginTopMm - _settings.pageMarginBottomMm;
|
|
return availableHeightMm / _settings.rowsPerPage;
|
|
}
|
|
|
|
|
|
public void ExportRunningSheets(int setID, string path)
|
|
{
|
|
string international_path = path;
|
|
if (path.EndsWith(".pdf"))
|
|
{
|
|
path = path.Substring(0, path.Length - 4);
|
|
international_path = path;
|
|
path = path + "-Laufzettel.pdf";
|
|
international_path = international_path + "-Laufzettel-International.pdf";
|
|
}
|
|
else
|
|
{
|
|
path = path + "-Laufzettel.pdf";
|
|
international_path = international_path + "-Laufzettel-International.pdf";
|
|
}
|
|
|
|
CreateGermanyRunningSheets(setID, path);
|
|
CreateInternationalRunningSheets(setID, international_path);
|
|
|
|
}
|
|
|
|
|
|
public void CreateGermanyRunningSheets(int setID, string path)
|
|
{
|
|
KasAddressList list = Settings._instance.addressSets.GetAddressSetByID(setID);
|
|
var document = new PdfDocument();
|
|
document.Info.Title = $"Laufzettel für {list.Name}";
|
|
document.Info.Subject = "powered by logofclient";
|
|
document.Info.Author = "logofclient";
|
|
|
|
var grouped_nums = GroupAddresses(setID).ToList();
|
|
|
|
// Zwei Tabellen pro A4-Seite
|
|
int sheets = (grouped_nums.Count + 1) / 2;
|
|
|
|
// Layout
|
|
double marginX = 20;
|
|
double marginY = 20;
|
|
double gapY = 12;
|
|
|
|
for (int pageIndex = 0; pageIndex < sheets; pageIndex++)
|
|
{
|
|
var page = document.AddPage();
|
|
page.Size = PageSize.A4;
|
|
var gfx = XGraphics.FromPdfPage(page);
|
|
|
|
double pageW = page.Width.Point;
|
|
double pageH = page.Height.Point;
|
|
|
|
double usableW = pageW - 2 * marginX;
|
|
double usableH = pageH - 2 * marginY;
|
|
double tableH = (usableH - gapY) / 2.0;
|
|
|
|
double top1 = marginY;
|
|
double top2 = marginY + tableH + gapY;
|
|
|
|
var fontLabel = new XFont("Arial", 6, XFontStyleEx.Bold);
|
|
var fontText = new XFont("Arial", 6, XFontStyleEx.Regular);
|
|
var fontBig = new XFont("Arial", 30, XFontStyleEx.Bold);
|
|
|
|
int firstIndex = pageIndex * 2;
|
|
int palletNumber =
|
|
Settings._instance.pdfExport.rsPalNr +
|
|
(firstIndex / Settings._instance.pdfExport.rsBundNrPal);
|
|
|
|
int bundleOnPallet =
|
|
(firstIndex % Settings._instance.pdfExport.rsBundNrPal) + 1;
|
|
|
|
DrawGermanyRunningSheet(
|
|
gfx,
|
|
marginX,
|
|
top1,
|
|
usableW,
|
|
tableH,
|
|
list,
|
|
grouped_nums[firstIndex],
|
|
grouped_nums,
|
|
fontLabel,
|
|
fontText,
|
|
fontBig,
|
|
palletNumber,
|
|
bundleOnPallet,
|
|
firstIndex + 1
|
|
);
|
|
|
|
int secondIndex = firstIndex + 1;
|
|
|
|
int palletNumber2 =
|
|
Settings._instance.pdfExport.rsPalNr +
|
|
(secondIndex / Settings._instance.pdfExport.rsBundNrPal);
|
|
|
|
int bundleOnPallet2 =
|
|
(secondIndex % Settings._instance.pdfExport.rsBundNrPal) + 1;
|
|
|
|
if (firstIndex + 1 < grouped_nums.Count)
|
|
{
|
|
DrawGermanyRunningSheet(
|
|
gfx,
|
|
marginX,
|
|
top2,
|
|
usableW,
|
|
tableH,
|
|
list,
|
|
grouped_nums[secondIndex],
|
|
grouped_nums,
|
|
fontLabel,
|
|
fontText,
|
|
fontBig,
|
|
palletNumber2,
|
|
bundleOnPallet2,
|
|
secondIndex + 1
|
|
);
|
|
}
|
|
}
|
|
|
|
document.Save(path);
|
|
}
|
|
|
|
private void DrawGermanyRunningSheet(
|
|
XGraphics gfx,
|
|
double x,
|
|
double y,
|
|
double w,
|
|
double h,
|
|
KasAddressList list,
|
|
dynamic result,
|
|
List<(int,string,string,string,int)> grouped_nums,
|
|
XFont fontLabel,
|
|
XFont fontText,
|
|
XFont fontBig,
|
|
int pal_nr,
|
|
int bundleOnPallet,
|
|
int totalBundleNumber){
|
|
double line = 1.0;
|
|
|
|
string sender = Customer.GetCustomerByID(list.owner_id)?.sender_address ?? "[Absender]";
|
|
string customerName = Customer.GetCustomerByID(list.owner_id)?.name ?? "[Kunde]";
|
|
string start = result.Item3?.ToString() ?? "[Start]";
|
|
string end = result.Item4?.ToString() ?? "[Ende]";
|
|
string amount = result.Item5?.ToString() ?? "[Anzahl]";
|
|
string groupNo = result.Item2?.ToString() ?? "[PLZ]";
|
|
string fraction = result.Item1?.ToString() ?? "[Fraktion]";
|
|
|
|
var options = Settings._instance.pdfExport;
|
|
|
|
int total_frac = 0;
|
|
foreach (var item in grouped_nums)
|
|
{
|
|
if (item.Item2 == result.Item2) total_frac++;
|
|
}
|
|
|
|
// Outer border
|
|
gfx.DrawRectangle(XPens.Black, x, y, w, h);
|
|
|
|
// Row heights
|
|
double r1 = h * 0.1;
|
|
double r2 = h * 0.1;
|
|
double r3 = h * 0.54;
|
|
double r4 = h * 0.30;
|
|
|
|
// Main horizontal lines
|
|
gfx.DrawLine(XPens.Black, x, y + r1, x + w, y + r1);
|
|
gfx.DrawLine(XPens.Black, x, y + r1 + r2, x + w, y + r1 + r2);
|
|
gfx.DrawLine(XPens.Black, x, y + r1 + r2 + r3, x + w, y + r1 + r2 + r3);
|
|
|
|
// Top row columns
|
|
double c1 = w * 0.39;
|
|
double c2 = w * 0.20;
|
|
double c3 = w * 0.26;
|
|
double c4 = w * 0.15;
|
|
|
|
gfx.DrawLine(XPens.Black, x + c1, y, x + c1, y + r1);
|
|
gfx.DrawLine(XPens.Black, x + c1 + c2, y, x + c1 + c2, y + r1);
|
|
gfx.DrawLine(XPens.Black, x + c1 + c2 + c3, y, x + c1 + c2 + c3, y + r1);
|
|
|
|
// Second row columns
|
|
gfx.DrawLine(XPens.Black, x + c1, y + r1, x + c1, y + r1 + r2);
|
|
gfx.DrawLine(XPens.Black, x + c1 + c2, y + r1, x + c1 + c2, y + r1 + r2);
|
|
gfx.DrawLine(XPens.Black, x + c1 + c2 + c3, y + r1, x + c1 + c2 + c3, y + r1 + r2);
|
|
|
|
// Middle large area split
|
|
double midSplit = x + w * 0.55;
|
|
gfx.DrawLine(XPens.Black, midSplit, y + r1 + r2, midSplit, y + r1 + r2 + r3);
|
|
|
|
// Bottom section split
|
|
double leftBottomW = w * 0.42;
|
|
gfx.DrawLine(XPens.Black, x + leftBottomW, y + r1 + r2 + r3, x + leftBottomW, y + h);
|
|
|
|
// Bottom left rows
|
|
double blY1 = y + r1 + r2 + r3 + (r4 * 0.14);
|
|
double blY2 = y + r1 + r2 + r3 + (r4 * 0.28);
|
|
double blY3 = y + r1 + r2 + r3 + (r4 * 0.42);
|
|
double blY4 = y + r1 + r2 + r3 + (r4 * 0.56);
|
|
double blY5 = y + r1 + r2 + r3 + (r4 * 0.70);
|
|
|
|
gfx.DrawLine(XPens.Black, x, blY1, x + leftBottomW, blY1);
|
|
gfx.DrawLine(XPens.Black, x, blY2, x + leftBottomW, blY2);
|
|
gfx.DrawLine(XPens.Black, x, blY3, x + leftBottomW, blY3);
|
|
gfx.DrawLine(XPens.Black, x, blY4, x + leftBottomW, blY4);
|
|
gfx.DrawLine(XPens.Black, x, blY5, x + leftBottomW, blY5);
|
|
|
|
// Labels top row
|
|
gfx.DrawString("Absender:", fontLabel, XBrushes.Black, new XRect(x + 5, y + 4, c1 - 10, 14), XStringFormats.TopLeft);
|
|
gfx.DrawString("Kunden-Nr. Absender:", fontLabel, XBrushes.Black, new XRect(x + c1 + 5, y + 4, c2 - 10, 14), XStringFormats.TopLeft);
|
|
gfx.DrawString("ZKZ/Titel:", fontLabel, XBrushes.Black, new XRect(x + c1 + c2 + 5, y + 4, c3 - 10, 14), XStringFormats.TopLeft);
|
|
gfx.DrawString("Anzahl Sendungen:", fontLabel, XBrushes.Black, new XRect(x + c1 + c2 + c3 + 5, y + 4, c4 - 10, 14), XStringFormats.TopLeft);
|
|
|
|
// Values top row
|
|
gfx.DrawString(sender, fontText, XBrushes.Black, new XRect(x + 5, y + 20, c1 - 10, r1 - 22), XStringFormats.TopLeft);
|
|
gfx.DrawString(options.rsKNrAbs, fontText, XBrushes.Black, new XRect(x + c1 + 5, y + 20, c2 - 10, r1 - 22), XStringFormats.TopLeft);
|
|
gfx.DrawString(options.rsZKZ, fontText, XBrushes.Black, new XRect(x + c1 + c2 + 5, y + 20, c3 - 10, r1 - 22), XStringFormats.TopLeft);
|
|
gfx.DrawString(amount, fontText, XBrushes.Black, new XRect(x + c1 + c2 + c3 + 5, y + 20, c4 - 10, r1 - 22), XStringFormats.TopLeft);
|
|
|
|
// Second row labels
|
|
gfx.DrawString("Einlieferer:", fontLabel, XBrushes.Black, new XRect(x + 5, y + r1 + 4, c1 - 10, 14), XStringFormats.TopLeft);
|
|
gfx.DrawString("Kunden-Nr. Einlieferer:", fontLabel, XBrushes.Black, new XRect(x + c1 + 5, y + r1 + 4, c2 - 10, 14), XStringFormats.TopLeft);
|
|
gfx.DrawString("Interne Vermerke:", fontLabel, XBrushes.Black, new XRect(x + c1 + c2 + 5, y + r1 + 4, c3 - 10, 14), XStringFormats.TopLeft);
|
|
gfx.DrawString("Laufzeit", fontLabel, XBrushes.Black, new XRect(x + c1 + c2 + c3 + 5, y + r1 + 4, c4 - 10, 14), XStringFormats.TopLeft);
|
|
|
|
// Second row values
|
|
gfx.DrawString(customerName, fontText, XBrushes.Black, new XRect(x + 5, y + r1 + 20, c1 - 10, r2 - 22), XStringFormats.TopLeft);
|
|
gfx.DrawString(options.rsKNrEmp, fontText, XBrushes.Black, new XRect(x + c1 + 5, y + r1 + 20, c2 - 10, r2 - 22), XStringFormats.TopLeft);
|
|
gfx.DrawString(options.rsIntVer, fontText, XBrushes.Black, new XRect(x + c1 + c2 + 5, y + r1 + 20, c3 - 10, r2 - 22), XStringFormats.TopLeft);
|
|
gfx.DrawString(options.rsLaufz, fontText, XBrushes.Black, new XRect(x + c1 + c2 + c3 + 5, y + r1 + 20, c4 - 10, r2 - 22), XStringFormats.TopLeft);
|
|
|
|
// Middle area
|
|
gfx.DrawString(groupNo, fontBig, XBrushes.Black,
|
|
new XRect(x + 5, y + r1 + r2 + 5, w * 0.50 - 10, r3 - 10),
|
|
XStringFormats.Center);
|
|
|
|
gfx.DrawString("PRESSE/ELN", fontBig, XBrushes.Black,
|
|
new XRect(x + 5, y + r1 + r2 + 5, w * 0.50 - 10, r3 - 90),
|
|
XStringFormats.Center);
|
|
|
|
gfx.DrawString($"Fraktion {fraction}/{total_frac}", fontText, XBrushes.Black,
|
|
new XRect(x + 5, y + r1 + r2 + r3 - 18, w * 0.50 - 10, 14),
|
|
XStringFormats.CenterLeft);
|
|
|
|
gfx.DrawString("Bereich für postalische Zwecke:", fontLabel, XBrushes.Black,
|
|
new XRect(midSplit + 5, y + r1 + r2 + 4, w - (midSplit - x) - 10, 14),
|
|
XStringFormats.TopLeft);
|
|
|
|
// Bottom left labels
|
|
// Bottom left labels
|
|
gfx.DrawString("Einlieferungsdatum:", fontLabel, XBrushes.Black,
|
|
new XRect(x + 5, y + r1 + r2 + r3 + 4, leftBottomW - 10, 14),
|
|
XStringFormats.TopLeft);
|
|
|
|
gfx.DrawString("AM-Auftragsnummer:", fontLabel, XBrushes.Black,
|
|
new XRect(x + 5, blY1 + 4, leftBottomW - 10, 14),
|
|
XStringFormats.TopLeft);
|
|
|
|
gfx.DrawString("Bundgewicht:", fontLabel, XBrushes.Black,
|
|
new XRect(x + 5, blY2 + 4, leftBottomW - 10, 14),
|
|
XStringFormats.TopLeft);
|
|
|
|
gfx.DrawString("Paletten-Nr.:", fontLabel, XBrushes.Black,
|
|
new XRect(x + 5, blY3 + 4, leftBottomW - 10, 14),
|
|
XStringFormats.TopLeft);
|
|
|
|
gfx.DrawString("Bund-Nr./Bunde auf Palette:", fontLabel, XBrushes.Black,
|
|
new XRect(x + 5, blY4 + 4, leftBottomW - 10, 14),
|
|
XStringFormats.TopLeft);
|
|
|
|
gfx.DrawString("Bund-Nr. von Gesamtanzahl:", fontLabel, XBrushes.Black,
|
|
new XRect(x + 5, blY5 + 4, leftBottomW - 10, 14),
|
|
XStringFormats.TopLeft);
|
|
|
|
// Bottom placeholders rechts daneben, gleiche Zeile
|
|
double valueX = x + leftBottomW * 0.55;
|
|
double valueW = leftBottomW - (valueX - x) - 5;
|
|
|
|
gfx.DrawString(options.rsEinldat, fontText, XBrushes.Black,
|
|
new XRect(valueX, y + r1 + r2 + r3 + 4, valueW, 14),
|
|
XStringFormats.TopRight);
|
|
|
|
gfx.DrawString(options.rsAMANr, fontText, XBrushes.Black,
|
|
new XRect(valueX, blY1 + 4, valueW, 14),
|
|
XStringFormats.TopRight);
|
|
|
|
if (options.rsBundNrPal == null) goto nopal;
|
|
gfx.DrawString(pal_nr.ToString(), fontText, XBrushes.Black,
|
|
new XRect(valueX, blY3 + 4, valueW, 14),
|
|
XStringFormats.TopRight);
|
|
|
|
|
|
gfx.DrawString(
|
|
$"{bundleOnPallet}/{Settings._instance.pdfExport.rsBundNrPal}",
|
|
fontText,
|
|
XBrushes.Black,
|
|
new XRect(valueX, blY4 + 4, valueW, 14),
|
|
XStringFormats.TopRight);
|
|
|
|
nopal:
|
|
gfx.DrawString(
|
|
$"{totalBundleNumber}/{grouped_nums.Count}",
|
|
fontText,
|
|
XBrushes.Black,
|
|
new XRect(valueX, blY5 + 4, valueW, 14),
|
|
XStringFormats.TopRight);
|
|
|
|
|
|
// Right bottom postal area label
|
|
gfx.DrawString("Feld für Palettenlabel/NVE:", fontLabel, XBrushes.Black,
|
|
new XRect(x + leftBottomW + 5, y + r1 + r2 + r3 + 4, w - leftBottomW - 10, 14),
|
|
XStringFormats.TopLeft);
|
|
}
|
|
|
|
|
|
|
|
public void CreateInternationalRunningSheets(int setID, string path)
|
|
{
|
|
KasAddressList list = Settings._instance.addressSets.GetAddressSetByID(setID);
|
|
|
|
var document = new PdfDocument();
|
|
document.Info.Title = $"Laufzettel für {list.Name}";
|
|
document.Info.Subject = "powered by logofclient";
|
|
document.Info.Author = "logofclient";
|
|
|
|
var grouped_nums = GroupAddressesInternational(setID).ToList();
|
|
|
|
int sheets = (grouped_nums.Count + 1) / 2;
|
|
|
|
double marginX = 20;
|
|
double marginY = 20;
|
|
double gapY = 12;
|
|
|
|
for (int pageIndex = 0; pageIndex < sheets; pageIndex++)
|
|
{
|
|
var page = document.AddPage();
|
|
page.Size = PageSize.A4;
|
|
|
|
var gfx = XGraphics.FromPdfPage(page);
|
|
|
|
double pageW = page.Width.Point;
|
|
double pageH = page.Height.Point;
|
|
|
|
double usableW = pageW - 2 * marginX;
|
|
double usableH = pageH - 2 * marginY;
|
|
double tableH = (usableH - gapY) / 2.0;
|
|
|
|
double top1 = marginY;
|
|
double top2 = marginY + tableH + gapY;
|
|
|
|
var fontLabel = new XFont("Arial", 6, XFontStyleEx.Bold);
|
|
var fontText = new XFont("Arial", 6, XFontStyleEx.Regular);
|
|
var fontBig = new XFont("Arial", 30, XFontStyleEx.Bold);
|
|
|
|
int firstIndex = pageIndex * 2;
|
|
|
|
int palletNumber =
|
|
Settings._instance.pdfExport.rsPalNr +
|
|
(firstIndex / Settings._instance.pdfExport.rsBundNrPal);
|
|
|
|
int bundleOnPallet =
|
|
(firstIndex % Settings._instance.pdfExport.rsBundNrPal) + 1;
|
|
|
|
|
|
|
|
DrawInternationalRunningSheet(
|
|
gfx,
|
|
marginX,
|
|
top1,
|
|
usableW,
|
|
tableH,
|
|
list,
|
|
grouped_nums[firstIndex],
|
|
grouped_nums,
|
|
fontLabel,
|
|
fontText,
|
|
fontBig,
|
|
palletNumber,
|
|
bundleOnPallet,
|
|
firstIndex + 1
|
|
);
|
|
|
|
if (firstIndex + 1 < grouped_nums.Count)
|
|
{
|
|
int secondIndex = firstIndex + 1;
|
|
|
|
int palletNumber2 =
|
|
Settings._instance.pdfExport.rsPalNr +
|
|
(secondIndex / Settings._instance.pdfExport.rsBundNrPal);
|
|
|
|
int bundleOnPallet2 =
|
|
(secondIndex % Settings._instance.pdfExport.rsBundNrPal) + 1;
|
|
|
|
DrawInternationalRunningSheet(
|
|
gfx,
|
|
marginX,
|
|
top2,
|
|
usableW,
|
|
tableH,
|
|
list,
|
|
grouped_nums[secondIndex],
|
|
grouped_nums,
|
|
fontLabel,
|
|
fontText,
|
|
fontBig,
|
|
palletNumber2,
|
|
bundleOnPallet2,
|
|
secondIndex + 1
|
|
);
|
|
}
|
|
}
|
|
|
|
document.Save(path);
|
|
}
|
|
private void DrawInternationalRunningSheet(
|
|
XGraphics gfx,
|
|
double x,
|
|
double y,
|
|
double w,
|
|
double h,
|
|
KasAddressList list,
|
|
dynamic result,
|
|
List<(int,string,string,string,int)> grouped_nums,
|
|
XFont fontLabel,
|
|
XFont fontText,
|
|
XFont fontBig,
|
|
int pal_nr,
|
|
int bundleOnPallet,
|
|
int totalBundleNumber,
|
|
string category = "ECONOMY Non-EU")
|
|
{
|
|
double line = 1.0;
|
|
|
|
string sender = Customer.GetCustomerByID(list.owner_id)?.sender_address ?? "[Absender]";
|
|
string customerName = Customer.GetCustomerByID(list.owner_id)?.name ?? "[Kunde]";
|
|
string start = result.Item3?.ToString() ?? "[Start]";
|
|
string end = result.Item4?.ToString() ?? "[Ende]";
|
|
string amount = result.Item5?.ToString() ?? "[Anzahl]";
|
|
string groupNo = result.Item2?.ToString() ?? "[PLZ]";
|
|
string fraction = result.Item1?.ToString() ?? "[Fraktion]";
|
|
|
|
var options = Settings._instance.pdfExport;
|
|
|
|
int total_frac = 0;
|
|
foreach (var item in grouped_nums)
|
|
{
|
|
if (item.Item2 == result.Item2) total_frac++;
|
|
}
|
|
|
|
// Outer border
|
|
gfx.DrawRectangle(XPens.Black, x, y, w, h);
|
|
|
|
// Row heights
|
|
double r1 = h * 0.1;
|
|
double r2 = h * 0.1;
|
|
double r3 = h * 0.54;
|
|
double r4 = h * 0.30;
|
|
|
|
// Main horizontal lines
|
|
gfx.DrawLine(XPens.Black, x, y + r1, x + w, y + r1);
|
|
gfx.DrawLine(XPens.Black, x, y + r1 + r2, x + w, y + r1 + r2);
|
|
gfx.DrawLine(XPens.Black, x, y + r1 + r2 + r3, x + w, y + r1 + r2 + r3);
|
|
|
|
// Top row columns
|
|
double c1 = w * 0.39;
|
|
double c2 = w * 0.20;
|
|
double c3 = w * 0.26;
|
|
double c4 = w * 0.15;
|
|
|
|
gfx.DrawLine(XPens.Black, x + c1, y, x + c1, y + r1);
|
|
gfx.DrawLine(XPens.Black, x + c1 + c2, y, x + c1 + c2, y + r1);
|
|
gfx.DrawLine(XPens.Black, x + c1 + c2 + c3, y, x + c1 + c2 + c3, y + r1);
|
|
|
|
// Second row columns
|
|
gfx.DrawLine(XPens.Black, x + c1, y + r1, x + c1, y + r1 + r2);
|
|
gfx.DrawLine(XPens.Black, x + c1 + c2, y + r1, x + c1 + c2, y + r1 + r2);
|
|
gfx.DrawLine(XPens.Black, x + c1 + c2 + c3, y + r1, x + c1 + c2 + c3, y + r1 + r2);
|
|
|
|
// Middle large area split
|
|
double midSplit = x + w * 0.55;
|
|
gfx.DrawLine(XPens.Black, midSplit, y + r1 + r2, midSplit, y + r1 + r2 + r3);
|
|
|
|
// Bottom section split
|
|
double leftBottomW = w * 0.42;
|
|
gfx.DrawLine(XPens.Black, x + leftBottomW, y + r1 + r2 + r3, x + leftBottomW, y + h);
|
|
|
|
// Bottom left rows
|
|
double blY1 = y + r1 + r2 + r3 + (r4 * 0.14);
|
|
double blY2 = y + r1 + r2 + r3 + (r4 * 0.28);
|
|
double blY3 = y + r1 + r2 + r3 + (r4 * 0.42);
|
|
double blY4 = y + r1 + r2 + r3 + (r4 * 0.56);
|
|
double blY5 = y + r1 + r2 + r3 + (r4 * 0.70);
|
|
|
|
gfx.DrawLine(XPens.Black, x, blY1, x + leftBottomW, blY1);
|
|
gfx.DrawLine(XPens.Black, x, blY2, x + leftBottomW, blY2);
|
|
gfx.DrawLine(XPens.Black, x, blY3, x + leftBottomW, blY3);
|
|
gfx.DrawLine(XPens.Black, x, blY4, x + leftBottomW, blY4);
|
|
gfx.DrawLine(XPens.Black, x, blY5, x + leftBottomW, blY5);
|
|
|
|
// Labels top row
|
|
gfx.DrawString("Absender:", fontLabel, XBrushes.Black, new XRect(x + 5, y + 4, c1 - 10, 14), XStringFormats.TopLeft);
|
|
gfx.DrawString("Kunden-Nr. Absender:", fontLabel, XBrushes.Black, new XRect(x + c1 + 5, y + 4, c2 - 10, 14), XStringFormats.TopLeft);
|
|
gfx.DrawString("ZKZ/Titel:", fontLabel, XBrushes.Black, new XRect(x + c1 + c2 + 5, y + 4, c3 - 10, 14), XStringFormats.TopLeft);
|
|
gfx.DrawString("Anzahl Sendungen:", fontLabel, XBrushes.Black, new XRect(x + c1 + c2 + c3 + 5, y + 4, c4 - 10, 14), XStringFormats.TopLeft);
|
|
|
|
// Values top row
|
|
gfx.DrawString(sender, fontText, XBrushes.Black, new XRect(x + 5, y + 20, c1 - 10, r1 - 22), XStringFormats.TopLeft);
|
|
gfx.DrawString(options.rsKNrAbs, fontText, XBrushes.Black, new XRect(x + c1 + 5, y + 20, c2 - 10, r1 - 22), XStringFormats.TopLeft);
|
|
gfx.DrawString(options.rsZKZ, fontText, XBrushes.Black, new XRect(x + c1 + c2 + 5, y + 20, c3 - 10, r1 - 22), XStringFormats.TopLeft);
|
|
gfx.DrawString(amount, fontText, XBrushes.Black, new XRect(x + c1 + c2 + c3 + 5, y + 20, c4 - 10, r1 - 22), XStringFormats.TopLeft);
|
|
|
|
// Second row labels
|
|
gfx.DrawString("Einlieferer:", fontLabel, XBrushes.Black, new XRect(x + 5, y + r1 + 4, c1 - 10, 14), XStringFormats.TopLeft);
|
|
gfx.DrawString("Kunden-Nr. Einlieferer:", fontLabel, XBrushes.Black, new XRect(x + c1 + 5, y + r1 + 4, c2 - 10, 14), XStringFormats.TopLeft);
|
|
gfx.DrawString("Interne Vermerke:", fontLabel, XBrushes.Black, new XRect(x + c1 + c2 + 5, y + r1 + 4, c3 - 10, 14), XStringFormats.TopLeft);
|
|
gfx.DrawString("Laufzeit", fontLabel, XBrushes.Black, new XRect(x + c1 + c2 + c3 + 5, y + r1 + 4, c4 - 10, 14), XStringFormats.TopLeft);
|
|
|
|
// Second row values
|
|
gfx.DrawString(customerName, fontText, XBrushes.Black, new XRect(x + 5, y + r1 + 20, c1 - 10, r2 - 22), XStringFormats.TopLeft);
|
|
gfx.DrawString(options.rsKNrEmp, fontText, XBrushes.Black, new XRect(x + c1 + 5, y + r1 + 20, c2 - 10, r2 - 22), XStringFormats.TopLeft);
|
|
gfx.DrawString(options.rsIntVer, fontText, XBrushes.Black, new XRect(x + c1 + c2 + 5, y + r1 + 20, c3 - 10, r2 - 22), XStringFormats.TopLeft);
|
|
gfx.DrawString(options.rsLaufz, fontText, XBrushes.Black, new XRect(x + c1 + c2 + c3 + 5, y + r1 + 20, c4 - 10, r2 - 22), XStringFormats.TopLeft);
|
|
|
|
// Middle area
|
|
gfx.DrawString(groupNo, fontBig, XBrushes.Black,
|
|
new XRect(x + 5, y + r1 + r2 + 5, w * 0.50 - 10, r3 - 10),
|
|
XStringFormats.Center);
|
|
|
|
gfx.DrawString("PRESSE/ELN", fontBig, XBrushes.Black,
|
|
new XRect(x + 5, y + r1 + r2 + 5, w * 0.50 - 10, r3 - 90),
|
|
XStringFormats.Center);
|
|
|
|
gfx.DrawString($"Fraktion {fraction}/{total_frac}", fontText, XBrushes.Black,
|
|
new XRect(x + 5, y + r1 + r2 + r3 - 18, w * 0.50 - 10, 14),
|
|
XStringFormats.CenterLeft);
|
|
|
|
gfx.DrawString("Bereich für postalische Zwecke:", fontLabel, XBrushes.Black,
|
|
new XRect(midSplit + 5, y + r1 + r2 + 4, w - (midSplit - x) - 10, 14),
|
|
XStringFormats.TopLeft);
|
|
|
|
// Bottom left labels
|
|
// Bottom left labels
|
|
gfx.DrawString("Einlieferungsdatum:", fontLabel, XBrushes.Black,
|
|
new XRect(x + 5, y + r1 + r2 + r3 + 4, leftBottomW - 10, 14),
|
|
XStringFormats.TopLeft);
|
|
|
|
gfx.DrawString("AM-Auftragsnummer:", fontLabel, XBrushes.Black,
|
|
new XRect(x + 5, blY1 + 4, leftBottomW - 10, 14),
|
|
XStringFormats.TopLeft);
|
|
|
|
gfx.DrawString("Bundgewicht:", fontLabel, XBrushes.Black,
|
|
new XRect(x + 5, blY2 + 4, leftBottomW - 10, 14),
|
|
XStringFormats.TopLeft);
|
|
|
|
gfx.DrawString("Paletten-Nr.:", fontLabel, XBrushes.Black,
|
|
new XRect(x + 5, blY3 + 4, leftBottomW - 10, 14),
|
|
XStringFormats.TopLeft);
|
|
|
|
gfx.DrawString("Bund-Nr./Bunde auf Palette:", fontLabel, XBrushes.Black,
|
|
new XRect(x + 5, blY4 + 4, leftBottomW - 10, 14),
|
|
XStringFormats.TopLeft);
|
|
|
|
gfx.DrawString("Bund-Nr. von Gesamtanzahl:", fontLabel, XBrushes.Black,
|
|
new XRect(x + 5, blY5 + 4, leftBottomW - 10, 14),
|
|
XStringFormats.TopLeft);
|
|
|
|
// Bottom placeholders rechts daneben, gleiche Zeile
|
|
double valueX = x + leftBottomW * 0.55;
|
|
double valueW = leftBottomW - (valueX - x) - 5;
|
|
|
|
gfx.DrawString(options.rsEinldat, fontText, XBrushes.Black,
|
|
new XRect(valueX, y + r1 + r2 + r3 + 4, valueW, 14),
|
|
XStringFormats.TopRight);
|
|
|
|
gfx.DrawString(options.rsAMANr, fontText, XBrushes.Black,
|
|
new XRect(valueX, blY1 + 4, valueW, 14),
|
|
XStringFormats.TopRight);
|
|
|
|
gfx.DrawString(options.rsBundGew, fontText, XBrushes.Black,
|
|
new XRect(valueX, blY2 + 4, valueW, 14),
|
|
XStringFormats.TopRight);
|
|
|
|
if (options.rsBundNrPal == 0) goto nopal;
|
|
gfx.DrawString(pal_nr.ToString(), fontText, XBrushes.Black,
|
|
new XRect(valueX, blY3 + 4, valueW, 14),
|
|
XStringFormats.TopRight);
|
|
|
|
|
|
gfx.DrawString(
|
|
$"{bundleOnPallet}/{Settings._instance.pdfExport.rsBundNrPal}",
|
|
fontText,
|
|
XBrushes.Black,
|
|
new XRect(valueX, blY4 + 4, valueW, 14),
|
|
XStringFormats.TopRight);
|
|
|
|
nopal:
|
|
gfx.DrawString(
|
|
$"{totalBundleNumber}/{grouped_nums.Count}",
|
|
fontText,
|
|
XBrushes.Black,
|
|
new XRect(valueX, blY5 + 4, valueW, 14),
|
|
XStringFormats.TopRight);
|
|
|
|
|
|
// Right bottom postal area label
|
|
gfx.DrawString("Feld für Palettenlabel/NVE:", fontLabel, XBrushes.Black,
|
|
new XRect(x + leftBottomW + 5, y + r1 + r2 + r3 + 4, w - leftBottomW - 10, 14),
|
|
XStringFormats.TopLeft);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Calculates address groups to summarize for the single pages of the running sheets.
|
|
/// </summary>
|
|
/// <param name="setID"></param>
|
|
/// <returns>List of quadruples consisting of a number and the starting of the plz, as well as first, last plz and total amount of addresses</returns>
|
|
public List<(int, string, string, string, int)> GroupAddresses(int setID)
|
|
{
|
|
int grpcount = Settings._instance.pdfExport.rsNumGrouped; // Amount of addresses per group
|
|
int stpoint = Settings._instance.pdfExport.rsPlzStartpoint; // group starting point (first n characters of the plz)
|
|
KasAddressList list = Settings._instance.addressSets.GetAddressSetByID(setID);
|
|
if (list == null)
|
|
throw new Exception("AddressSet nicht gefunden");
|
|
|
|
List<(int, string, string, string, int)> output = new();
|
|
|
|
List<IGrouping<string, KasPerson>> sorted_list = list.KasPersons
|
|
.Where(x => !string.IsNullOrEmpty(x?.used_plz) &&
|
|
x.used_plz.Length >= stpoint && x.IsGermany())
|
|
.OrderBy(x => x.used_plz)
|
|
.GroupBy(x => x.used_plz.Substring(0, stpoint))
|
|
.ToList();
|
|
|
|
foreach (var group in sorted_list)
|
|
{
|
|
string start = group.Key;
|
|
int fraktion = 0;
|
|
|
|
for (int count = 0; count < group.Count(); count += grpcount)
|
|
{
|
|
fraktion++;
|
|
|
|
int currentGroupSize = Math.Min(grpcount, group.Count() - count);
|
|
|
|
string first = group.ElementAt(count).used_plz;
|
|
string last = group.ElementAt(count + currentGroupSize - 1).used_plz;
|
|
|
|
output.Add((fraktion, start, first, last, currentGroupSize));
|
|
}
|
|
}
|
|
|
|
return output;
|
|
}
|
|
|
|
public List<(int, string, string, string, int)> GroupAddressesInternational(int setID)
|
|
{
|
|
int grpcount = Settings._instance.pdfExport.rsNumGrouped; // Amount of addresses per group
|
|
KasAddressList list = Settings._instance.addressSets.GetAddressSetByID(setID);
|
|
if (list == null)
|
|
throw new Exception("AddressSet nicht gefunden");
|
|
|
|
List<(int, string, string, string, int)> output = new();
|
|
|
|
List<IGrouping<string, KasPerson>> sorted_list = list.KasPersons
|
|
.Where(x => !string.IsNullOrEmpty(x?.used_plz) && !x.IsGermany())
|
|
.OrderBy(x => x.used_plz)
|
|
.GroupBy(x => x.land)
|
|
.ToList();
|
|
|
|
foreach (var group in sorted_list)
|
|
{
|
|
string start = group.Key;
|
|
int fraktion = 0;
|
|
|
|
for (int count = 0; count < group.Count(); count += grpcount)
|
|
{
|
|
fraktion++;
|
|
|
|
int currentGroupSize = Math.Min(grpcount, group.Count() - count);
|
|
|
|
string first = group.ElementAt(count).used_plz;
|
|
string last = group.ElementAt(count + currentGroupSize - 1).used_plz;
|
|
|
|
output.Add((fraktion, start, first, last, currentGroupSize));
|
|
}
|
|
}
|
|
|
|
return output;
|
|
}
|
|
}
|