Eingangsrechnungen: neue Endpunkte editForm.php und update.php

Agrarmonitor hat eingangsrechnungen.php entfernt (404). Das
Bearbeiten-Formular kommt jetzt von editForm.php?invoiceID=<id>,
gespeichert wird per JSON-POST an update.php mit
{ rechnungID, formData }. setRechnungsdaten laedt dafuer das
aktuelle Formular, uebernimmt alle Felder und ueberschreibt nur die
geaenderten Werte. Eine Fehlermeldung (msg) aus update.php wird als
Exception weitergegeben.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
bjoernpoettkerandClaude Opus 5.5 committed 2026-09-27 14:17:34 +02:00
1 parent 4cd0da4a8a
commit 0a01fbe8ca
6 files changed
+307 -50

No files matched your search

+65 -19
View File
@@ -211,14 +211,9 @@ class AgrarmonitorConnector {
return this.hasTableRows(response.data, 'table#dateien_eingang tbody tr');
}
async getRechnungsdaten(rechnungId) {
const response = await this.http.get('/module/eingangsrechnungen/api/eingangsrechnungen.php', {
params: {
id: 'edit',
rechnungId,
},
});
await this.saveSession();
const document = this.parseHtmlDocument(response.data);
return this.rechnungsdatenAusFormular(await this.loadEingangsrechnungEditForm(rechnungId));
}
rechnungsdatenAusFormular(document) {
return {
lieferschein: this.inputValue(document, 'lieferscheinnummer'),
rechnung: this.inputValue(document, 'rechnungsnummer'),
@@ -228,14 +223,33 @@ class AgrarmonitorConnector {
};
}
async setRechnungsdaten(rechnungId, daten) {
const response = await this.http.post(`/module/eingangsrechnungen/api/eingangsrechnungen.php?id=update&rechnungId=${encodeURIComponent(rechnungId)}`, new URLSearchParams({
// update.php erwartet das komplette Formular. Deshalb das aktuelle Formular laden
// und nur die geaenderten Felder ueberschreiben, damit nichts geleert wird.
const document = await this.loadEingangsrechnungEditForm(rechnungId);
const formData = {
...this.serializeForm(document, 'form#rechnung-detail'),
lieferscheinnummer: daten.lieferschein,
rechnungsnummer: daten.rechnung,
rechnungsdatum: this.formatGermanShortDate(daten.datum),
rgempf: String(daten.kundenId),
adresstext: daten.adresstext,
}), this.formPostConfig(`/eingangsrechnungen/detail/${rechnungId}`));
addressName: daten.adresstext,
};
const response = await this.http.post('/module/eingangsrechnungen/api/update.php', { rechnungID: rechnungId, formData }, {
headers: {
'Content-Type': 'application/json',
Accept: 'application/json, */*',
'X-Requested-With': 'XMLHttpRequest',
Referer: `${this.baseUrl}/eingangsrechnungen/detail/${rechnungId}`,
Origin: this.baseUrl,
},
validateStatus: status => status >= 200 && status < 400,
});
await this.saveSession();
// Erfolg: leeres Array. Fehler: Objekt mit msg.
const msg = response.data?.msg;
if (typeof msg === 'string' && msg.trim()) {
throw new Error(`Rechnung ${rechnungId} konnte nicht gespeichert werden: ${msg.trim()}`);
}
return response.status >= 200 && response.status < 300;
}
async setLieferscheinNummer(rechnungId, nummer) {
@@ -622,14 +636,7 @@ class AgrarmonitorConnector {
};
}
async getEingangsrechnungEditMeta(rechnungId) {
const response = await this.http.get('/module/eingangsrechnungen/api/eingangsrechnungen.php', {
params: {
id: 'edit',
rechnungId,
},
});
await this.saveSession();
const document = this.parseHtmlDocument(response.data);
const document = await this.loadEingangsrechnungEditForm(rechnungId);
return {
interneBelegNummer: this.inputValue(document, 'lieferscheinnummer'),
kundenId: this.selectedNumberValue(document, 'rgempf'),
@@ -637,6 +644,45 @@ class AgrarmonitorConnector {
dokumentTyp: this.selectedNumberValue(document, 'typ'),
};
}
async loadEingangsrechnungEditForm(rechnungId) {
const response = await this.http.get('/module/eingangsrechnungen/api/editForm.php', {
params: {
invoiceID: rechnungId,
},
});
await this.saveSession();
return this.parseHtmlDocument(response.data);
}
/** Flaches Objekt aus allen Formularfeldern, wie es das Agrarmonitor-Frontend an update.php schickt. */
serializeForm(document, formSelector) {
const form = document.querySelector(formSelector);
if (!form) {
throw new Error(`Formular ${formSelector} nicht gefunden`);
}
const values = {};
for (const field of Array.from(form.querySelectorAll('input, select, textarea'))) {
if (!field.name || field.disabled) {
continue;
}
if (field instanceof document.defaultView.HTMLInputElement) {
if (['button', 'submit', 'reset', 'image', 'file'].includes(field.type)) {
continue;
}
if (field.type === 'checkbox') {
values[field.name] = field.checked ? '1' : '0';
continue;
}
if (field.type === 'radio') {
if (field.checked) {
values[field.name] = field.value;
}
continue;
}
}
values[field.name] = field.value;
}
return values;
}
async getEingangsrechnungDetailMeta(rechnungId) {
const response = await this.http.get(`/eingangsrechnungen/detail/${rechnungId}`);
await this.saveSession();