fix(dkv): correct invoice date extraction; add Exchange IsRead filter + mark-as-read
Tessera CI/CD / Lint & Type Check (push) Successful in 44s
Tessera CI/CD / Tests (push) Successful in 44s
Tessera CI/CD / Build & Publish Images (push) Successful in 21s

Date fix: previous regex matched payment-due date ("10 Tage nach Rechnungsdatum...
10.04.2026") instead of actual Rechnungsdatum. New approach anchors on the
invoice number line (DD/DDDDDDDDD/DDD) and takes the date on the next line,
which is always the actual Rechnungsdatum in DKV PDFs.

Exchange dedup: FindItem now filters IsRead=false (combined with sender filter
via <t:And>), so already-processed emails are skipped automatically.
After downloading attachments, UpdateItem marks the message as read
(using ItemId + ChangeKey from GetItem response), mirroring IMAP \Seen behavior.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-30 09:47:17 +02:00
parent 66ffad149e
commit a44e40f101
2 changed files with 48 additions and 15 deletions
+8 -10
View File
@@ -69,17 +69,15 @@ export class DkvParserService {
return m ? m[1] : null;
}
/** Extract invoice date ("DD.MM.YYYY") appearing near "Rechnungsdatum" in PDF text. */
/** Extract invoice date ("DD.MM.YYYY") from PDF text.
* DKV PDFs always print the date on the line immediately after the invoice
* number (DD/DDDDDDDDD/DDD), so we anchor on the number → date pairing.
* The old "Rechnungsdatum[:\s]*date" approach picked up the payment-due date
* ("10 Tage nach Rechnungsdatum. Die Abbuchung erfolgt am: 10.04.2026").
*/
private extractRechnungsdatum(text: string): string | null {
// "Rechnungsdatum" is followed (within ~200 chars) by a date string
const m = text.match(/Rechnungsdatum[:\s\t]*(\d{2}\.\d{2}\.\d{4})/);
if (m) return m[1];
// Fallback: second line after "Rechnungsdatum:" marker
const idx = text.indexOf('Rechnungsdatum');
if (idx === -1) return null;
const after = text.slice(idx, idx + 200);
const dm = after.match(/(\d{2}\.\d{2}\.\d{4})/);
return dm ? dm[1] : null;
const m = text.match(/\d{2}\/\d{9}\/\d{3}\s+(\d{2}\.\d{2}\.\d{4})/);
return m ? m[1] : null;
}
// ─── Private: PDF text extraction ──────────────────────────────────────────