From 79874bf54fb137be00f8a4b2e239c74c51e5c97d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20P=C3=B6ttker?= Date: Sat, 23 May 2026 14:41:01 +0200 Subject: [PATCH] fix: harden AgrarmonitorWebService error handling and date parsing Co-Authored-By: Claude Sonnet 4.6 --- .../agrarmonitor/agrarmonitor-web.service.ts | 78 ++++++++++--------- 1 file changed, 43 insertions(+), 35 deletions(-) diff --git a/paperless-backend/src/agrarmonitor/agrarmonitor-web.service.ts b/paperless-backend/src/agrarmonitor/agrarmonitor-web.service.ts index 02daa4b..da50743 100644 --- a/paperless-backend/src/agrarmonitor/agrarmonitor-web.service.ts +++ b/paperless-backend/src/agrarmonitor/agrarmonitor-web.service.ts @@ -32,7 +32,11 @@ export class AgrarmonitorWebService { async eingangsrechnungenLivesearch(suchstring: string): Promise { const client = await this.agrarmonitorService.getClient(); - await client.http.get('/'); + try { + await client.http.get('/'); + } catch (err: any) { + this.logger.warn(`Session-Refresh fehlgeschlagen: ${err?.message}`); + } const searchUrl = `/module/dateien/livesearch.php?suchstring=${encodeURIComponent(suchstring)}` + `&stammdatum_typ=-1&mobil=-1&sensibel=-1&firma=0&itemsperpage=100000&seite=1`; @@ -94,16 +98,12 @@ export class AgrarmonitorWebService { if (receivedEl) { const eingangsText = receivedEl.text.trim(); - if (eingangsText !== 'Nicht empfangen' && eingangsText.length > 13) { - eingangsDatum = this.parseGermanDate(eingangsText.substring(13)); - } + const eingangsMatch = eingangsText.match(/Empfangen am (\d{2}\.\d{2}\.\d{2,4})/); + if (eingangsMatch) eingangsDatum = this.parseGermanDate(eingangsMatch[1]); const parentText = receivedEl.parentNode?.text ?? ''; - const dashIdx = parentText.lastIndexOf('-'); - const buchenText = dashIdx >= 0 ? parentText.substring(dashIdx + 1).trim() : ''; - if (buchenText !== 'Nicht gebucht' && buchenText.length > 11) { - buchungsDatum = this.parseGermanDate(buchenText.substring(11)); - } + const buchenMatch = parentText.match(/Gebucht am (\d{2}\.\d{2}\.\d{2,4})/); + if (buchenMatch) buchungsDatum = this.parseGermanDate(buchenMatch[1]); } results.push({ eingangId, belegNummer, interneBelegNummer, kundenId, betriebId, buchungsDatum, eingangsDatum }); @@ -112,7 +112,7 @@ export class AgrarmonitorWebService { return results; } - async setEingangsdatum(eingangId: number, _belegNummer: string, datum: Date): Promise { + async setEingangsdatum(eingangId: number, datum: Date): Promise { const client = await this.agrarmonitorService.getClient(); const params = new URLSearchParams(); params.append('datum', this.formatGermanDate(datum)); @@ -138,31 +138,36 @@ export class AgrarmonitorWebService { async setLieferscheinNummer(eingangId: number, lieferscheinNummer: string): Promise { const client = await this.agrarmonitorService.getClient(); - const { data: editHtml } = await client.http.get( - `/module/eingangsrechnungen/api/eingangsrechnungen.php?id=edit&rechnungId=${eingangId}`, - { responseType: 'text' }, - ); - const editRoot = parse(editHtml); - - const rechnungsnummer = - editRoot.querySelector('input[name="rechnungsnummer"]')?.getAttribute('value') ?? ''; - const rechnungsdatum = - editRoot.querySelector('input[name="rechnungsdatum"]')?.getAttribute('value') ?? ''; - const rgempf = - editRoot - .querySelector('select[name="rgempf"] option[selected]') - ?.getAttribute('value') ?? ''; - const addressName = - editRoot.querySelector('input[name="addressName"]')?.getAttribute('value') ?? ''; - - const params = new URLSearchParams(); - params.append('lieferscheinnummer', lieferscheinNummer); - params.append('rechnungsnummer', rechnungsnummer); - params.append('rechnungsdatum', rechnungsdatum); - params.append('rgempf', rgempf); - params.append('adresstext', addressName); - try { + const { data: editHtml } = await client.http.get( + `/module/eingangsrechnungen/api/eingangsrechnungen.php?id=edit&rechnungId=${eingangId}`, + { responseType: 'text' }, + ); + const editRoot = parse(editHtml); + + const rechnungsnummer = + editRoot.querySelector('input[name="rechnungsnummer"]')?.getAttribute('value') ?? ''; + const rechnungsdatum = + editRoot.querySelector('input[name="rechnungsdatum"]')?.getAttribute('value') ?? ''; + const rgempf = + editRoot + .querySelector('select[name="rgempf"] option[selected]') + ?.getAttribute('value') ?? ''; + const addressName = + editRoot.querySelector('input[name="addressName"]')?.getAttribute('value') ?? ''; + + if (!rgempf) { + this.logger.warn(`setLieferscheinNummer(${eingangId}): kein Empfänger im Formular, übersprungen`); + return false; + } + + const params = new URLSearchParams(); + params.append('lieferscheinnummer', lieferscheinNummer); + params.append('rechnungsnummer', rechnungsnummer); + params.append('rechnungsdatum', rechnungsdatum); + params.append('rgempf', rgempf); + params.append('adresstext', addressName); + const res = await client.http.post( `/module/eingangsrechnungen/api/eingangsrechnungen.php?id=update&rechnungId=${eingangId}`, params.toString(), @@ -185,7 +190,10 @@ export class AgrarmonitorWebService { const parts = str.trim().split('.'); if (parts.length !== 3) return null; const [dd, mm, yy] = parts; - const year = parseInt(yy, 10) < 50 ? 2000 + parseInt(yy, 10) : 1900 + parseInt(yy, 10); + const yearRaw = parseInt(yy, 10); + const year = yy.length === 2 + ? (yearRaw < 50 ? 2000 + yearRaw : 1900 + yearRaw) + : yearRaw; const d = new Date(year, parseInt(mm, 10) - 1, parseInt(dd, 10)); return isNaN(d.getTime()) ? null : d; }