fix: harden AgrarmonitorWebService error handling and date parsing

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-23 14:41:01 +02:00
parent 433b3be7fa
commit 79874bf54f
@@ -32,7 +32,11 @@ export class AgrarmonitorWebService {
async eingangsrechnungenLivesearch(suchstring: string): Promise<EingangsrechnungEntry[]> { async eingangsrechnungenLivesearch(suchstring: string): Promise<EingangsrechnungEntry[]> {
const client = await this.agrarmonitorService.getClient(); 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 = const searchUrl =
`/module/dateien/livesearch.php?suchstring=${encodeURIComponent(suchstring)}` + `/module/dateien/livesearch.php?suchstring=${encodeURIComponent(suchstring)}` +
`&stammdatum_typ=-1&mobil=-1&sensibel=-1&firma=0&itemsperpage=100000&seite=1`; `&stammdatum_typ=-1&mobil=-1&sensibel=-1&firma=0&itemsperpage=100000&seite=1`;
@@ -94,16 +98,12 @@ export class AgrarmonitorWebService {
if (receivedEl) { if (receivedEl) {
const eingangsText = receivedEl.text.trim(); const eingangsText = receivedEl.text.trim();
if (eingangsText !== 'Nicht empfangen' && eingangsText.length > 13) { const eingangsMatch = eingangsText.match(/Empfangen am (\d{2}\.\d{2}\.\d{2,4})/);
eingangsDatum = this.parseGermanDate(eingangsText.substring(13)); if (eingangsMatch) eingangsDatum = this.parseGermanDate(eingangsMatch[1]);
}
const parentText = receivedEl.parentNode?.text ?? ''; const parentText = receivedEl.parentNode?.text ?? '';
const dashIdx = parentText.lastIndexOf('-'); const buchenMatch = parentText.match(/Gebucht am (\d{2}\.\d{2}\.\d{2,4})/);
const buchenText = dashIdx >= 0 ? parentText.substring(dashIdx + 1).trim() : ''; if (buchenMatch) buchungsDatum = this.parseGermanDate(buchenMatch[1]);
if (buchenText !== 'Nicht gebucht' && buchenText.length > 11) {
buchungsDatum = this.parseGermanDate(buchenText.substring(11));
}
} }
results.push({ eingangId, belegNummer, interneBelegNummer, kundenId, betriebId, buchungsDatum, eingangsDatum }); results.push({ eingangId, belegNummer, interneBelegNummer, kundenId, betriebId, buchungsDatum, eingangsDatum });
@@ -112,7 +112,7 @@ export class AgrarmonitorWebService {
return results; return results;
} }
async setEingangsdatum(eingangId: number, _belegNummer: string, datum: Date): Promise<boolean> { async setEingangsdatum(eingangId: number, datum: Date): Promise<boolean> {
const client = await this.agrarmonitorService.getClient(); const client = await this.agrarmonitorService.getClient();
const params = new URLSearchParams(); const params = new URLSearchParams();
params.append('datum', this.formatGermanDate(datum)); params.append('datum', this.formatGermanDate(datum));
@@ -138,31 +138,36 @@ export class AgrarmonitorWebService {
async setLieferscheinNummer(eingangId: number, lieferscheinNummer: string): Promise<boolean> { async setLieferscheinNummer(eingangId: number, lieferscheinNummer: string): Promise<boolean> {
const client = await this.agrarmonitorService.getClient(); const client = await this.agrarmonitorService.getClient();
const { data: editHtml } = await client.http.get<string>(
`/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 { try {
const { data: editHtml } = await client.http.get<string>(
`/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( const res = await client.http.post(
`/module/eingangsrechnungen/api/eingangsrechnungen.php?id=update&rechnungId=${eingangId}`, `/module/eingangsrechnungen/api/eingangsrechnungen.php?id=update&rechnungId=${eingangId}`,
params.toString(), params.toString(),
@@ -185,7 +190,10 @@ export class AgrarmonitorWebService {
const parts = str.trim().split('.'); const parts = str.trim().split('.');
if (parts.length !== 3) return null; if (parts.length !== 3) return null;
const [dd, mm, yy] = parts; 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)); const d = new Date(year, parseInt(mm, 10) - 1, parseInt(dd, 10));
return isNaN(d.getTime()) ? null : d; return isNaN(d.getTime()) ? null : d;
} }