Sichtbeleg Anpassung für Zeilendopplung etc

MailSession - Logerweiterung für AzurePortale
This commit is contained in:
Developer01
2026-06-23 11:36:48 +02:00
parent aca6bcbc2b
commit 7377a9176e
7 changed files with 624 additions and 17 deletions

View File

@@ -199,7 +199,10 @@ Public Class XRechnungViewDocument
End Sub
Private Sub CheckAndCreateNewPageIfNeeded(context As PdfRenderContext)
If context.YPosition >= PAGE_HEIGHT_LIMIT Then
' ← NEU: Prüfe BEIDE Positionen
Dim maxY As Integer = Math.Max(context.YPosition, context.YDynamic)
If maxY >= PAGE_HEIGHT_LIMIT Then
Dim status As GdPictureStatus = context.PDF.NewPage(PdfPageSizes.PdfPageSizeA4)
If status <> GdPictureStatus.OK Then
_logger.Warn($"Could not create a second page. The error was: {status}")
@@ -209,6 +212,7 @@ Public Class XRechnungViewDocument
DrawHeader(context.PDF)
DrawFooter(context.PDF, context.CreatedString)
context.YPosition = MARGIN_TOP + 30
context.YDynamic = context.YPosition ' ← WICHTIG: Reset YDynamic!
End If
End Sub
@@ -263,7 +267,6 @@ Public Class XRechnungViewDocument
#Region "Area-Switch Handling"
Private Sub HandleAreaSwitch(context As PdfRenderContext, itemData As InvoiceItemData)
' WICHTIG: CurrentArea speichert die NORMALISIERTE Area
context.CurrentArea = itemData.NormalizedArea
context.CreateTextBox = False
_logger.Debug($"Area-Switch to: {context.CurrentArea}")
@@ -271,6 +274,14 @@ Public Class XRechnungViewDocument
' Area-Header zeichnen - ÜBERGIBT itemData komplett
Dim areaCaption As String = GetAreaCaption(context, itemData)
If Not String.IsNullOrEmpty(areaCaption) Then
' ← NEU: VORHER prüfen ob genug Platz für Header + minimale Inhalte (3 Zeilen = 15mm)
Dim requiredSpace As Integer = 15 ' Header (3x LINE_HEIGHT) + mindestens 1 Inhalt-Zeile
If (context.YPosition + requiredSpace) >= PAGE_HEIGHT_LIMIT Then
CreateNewPage(context)
_logger.Debug($"Area-Switch [{context.CurrentArea}]: Page break BEFORE header! New YPosition: {context.YPosition}")
End If
DrawAreaHeader(context, areaCaption)
DrawAreaSpecificHeaders(context)
End If
@@ -341,6 +352,7 @@ Public Class XRechnungViewDocument
Private Sub DrawAreaHeader(context As PdfRenderContext, caption As String)
context.YPosition += LINE_HEIGHT
_logger.Debug($"Drawing area header for [{context.CurrentArea}] with caption [{caption}] at YPosition={context.YPosition}")
context.PDF.DrawLine(MARGIN_LEFT, context.YPosition, LINE_WIDTH, context.YPosition)
context.YPosition += LINE_HEIGHT
context.PDF.DrawText(fontResNameBold, MARGIN_LEFT, context.YPosition, caption)
@@ -399,6 +411,7 @@ Public Class XRechnungViewDocument
' KEIN Increment hier - wird in Follow-Up gemacht
context.YDynamic = 0
context.YPosition += LINE_HEIGHT ' Neue Zeile für erste Position
context.CurrentPositionStartY = context.YPosition
context.PDF.DrawText(fontResName, COL_POS_NUMBER, context.YPosition, "1") ' Erste Position ist immer 1
context.PDF.DrawText(fontResName, COL_POS_AMOUNT, context.YPosition, itemData.Value)
context.PositionCount = 1 ' Zähler auf 1 setzen statt increment
@@ -530,6 +543,9 @@ Public Class XRechnungViewDocument
' WICHTIG: Neue Zeile für jede neue Position!
context.YPosition += LINE_HEIGHT
' ← NEU: Start-Y der aktuellen Position speichern
context.CurrentPositionStartY = context.YPosition
context.PDF.DrawText(fontResName, COL_POS_NUMBER, context.YPosition, context.PositionCount.ToString())
If itemData.SpecName = "INVOICE_POSITION_AMOUNT" Then
@@ -561,6 +577,7 @@ Public Class XRechnungViewDocument
If Not descriptionFollowup Then
context.YPlus = 0
End If
If context.YDynamic = 0 Then
context.YDynamic = context.YPosition
End If
@@ -571,6 +588,10 @@ Public Class XRechnungViewDocument
End If
RenderMultiLineText(context, itemData.Value, xPos, MAX_TEXT_LENGTH_POSITION)
' ← NEU: YPosition auf den höchsten erreichten Wert setzen
context.YPosition = Math.Max(context.YPosition, context.YDynamic)
itemData.Display = False
End Sub
@@ -578,22 +599,32 @@ Public Class XRechnungViewDocument
If context.YDynamic = 0 Then
context.YDynamic = context.YPosition
End If
RenderMultiLineText(context, itemData.Value, COL_POS_TEXT, MAX_TEXT_LENGTH_NOTE)
' ← NEU: YPosition synchronisieren
context.YPosition = Math.Max(context.YPosition, context.YDynamic)
itemData.Display = False
End Sub
Private Sub HandleTaxRateFollowUp(context As PdfRenderContext, itemData As InvoiceItemData)
context.PDF.DrawText(fontResName, COL_POS_TAX, context.YPosition, $"{itemData.Value} %")
' ← VERWENDE die Start-Y-Position der aktuellen Position!
Dim yPos As Integer = context.CurrentPositionStartY
_logger.Debug($"Handling Tax Rate Follow-Up: Value=[{itemData.Value}] at YPos={yPos}")
context.PDF.DrawText(fontResName, COL_POS_TAX, yPos, $"{itemData.Value} %")
itemData.Display = False
End Sub
Private Sub HandlePositionTaxAmountFollowUp(context As PdfRenderContext, itemData As InvoiceItemData)
Dim yPos As Double = context.YPosition - 3.5
Dim yPos As Integer = context.CurrentPositionStartY
Dim yPosAdjusted As Double = yPos - 3.5
Dim taxTerm As String = FormatCurrency(itemData.Value, context.CurrencySymbol)
context.PDF.DrawTextBox(fontResName, 177, yPos, 198, YCoo_TextBoxPlus5(yPos),
TextAlignment.TextAlignmentFar, TextAlignment.TextAlignmentNear,
taxTerm)
itemData.Display = False ' WICHTIG: Display auf False setzen!
_logger.Debug($"Handling Position Tax Amount Follow-Up: Value=[{itemData.Value}] Formatted=[{taxTerm}] at YPos={yPos}, Adjusted YPos={yPosAdjusted}")
context.PDF.DrawTextBox(fontResName, 177, yPosAdjusted, 198, YCoo_TextBoxPlus5(yPosAdjusted),
TextAlignment.TextAlignmentFar, TextAlignment.TextAlignmentNear,
taxTerm)
itemData.Display = False
End Sub
Private Sub HandleHeadFollowUp(itemData As InvoiceItemData)
@@ -701,11 +732,24 @@ Public Class XRechnungViewDocument
End Sub
Private Sub RenderMultiLineText(context As PdfRenderContext, text As String, xPos As Integer, maxLength As Integer)
' ERST nach echten Zeilenumbrüchen aufteilen
Dim partsNL As List(Of String) = StringFunctions.SplitTextByNewLine(text)
For Each linePart As String In partsNL
' DANN jede Zeile bei maxLength umbrechen
Dim parts As List(Of String) = StringFunctions.SplitText_Length(linePart, maxLength)
For Each part As String In parts
' ← NEU: VOR jedem Rendering prüfen, ob neue Seite nötig!
If context.YDynamic >= PAGE_HEIGHT_LIMIT Then
' Neue Seite erstellen
CreateNewPage(context)
' YDynamic auf neue Startposition setzen (nach Header)
context.YDynamic = context.YPosition
_logger.Debug($"RenderMultiLineText: Page break! New YDynamic: {context.YDynamic}")
End If
_logger.Debug($"RenderMultiLineText: Rendering part: [{part}] at Y position: {context.YDynamic}")
context.PDF.DrawText(fontResName, xPos, context.YDynamic, part)
context.YDynamic += LINE_HEIGHT
context.YPlus += LINE_HEIGHT
@@ -778,7 +822,8 @@ Public Class XRechnungViewDocument
Public Property CreateTextBox As Boolean
Public Property CreatedString As String
Public Property TaxPosText As String
Public Property IsFirstTaxPosDisplay As Boolean ' ← NEU
Public Property IsFirstTaxPosDisplay As Boolean
Public Property CurrentPositionStartY As Integer
Public Sub New(pdf As GdPicturePDF, createdString As String)
Me.PDF = pdf
@@ -792,7 +837,8 @@ Public Class XRechnungViewDocument
YPlus = 0
CreateTextBox = False
TaxPosText = ""
IsFirstTaxPosDisplay = False ' ← NEU
IsFirstTaxPosDisplay = False
CurrentPositionStartY = 0
End Sub
End Class