1.9.0: Auftragsbeschreibung aus der Baustellen-App ändern

orders.php?action=set_beschreibung schreibt das Zusatzfeld auftragsbeschreibung
(updateExtraField, ORDER_MODIFY), mit Konfliktschutz: weicht der Stand von
vorher ab, 409 mit aktuellem Text statt Überschreiben.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Eduard Wisch 2026-10-21 19:57:16 +02:00
parent c4c4aba891
commit 7f44ca7cfe
4 changed files with 50 additions and 1 deletions

View file

@ -1,5 +1,21 @@
# Changelog
## 1.9.0 — 2026-10-21
### Auftragsbeschreibung aus der Baustellen-App ändern
„Notizen ist gut, aber als extra Datei brauche ich das selten — Sachen, die ich mir merken will für den Auftrag,
lieber in der Auftragsbeschreibung festhalten" (Eddy, 21.10.2026).
- **`api/orders.php?id=<id>&action=set_beschreibung`** (POST, JSON `{ text, vorher }`) schreibt das Zusatzfeld
`auftragsbeschreibung` am Auftrag — wie „Zusatzfelder ändern" auf der Auftragskarte (`updateExtraField`, Trigger
`ORDER_MODIFY`). Recht: Aufträge ändern (`commande creer`). Bis 20 000 Zeichen, Zeilenenden vereinheitlicht.
- **Kein stilles Überschreiben:** `vorher` ist der Stand, den die App angezeigt hat. Weicht der Server-Stand ab (im Büro
geändert), kommt **409** mit dem aktuellen Text — die App fragt, statt die Büro-Änderung zu verlieren.
- ⚠ Die Auftragsbeschreibung steht auch auf dem **Stundenzettel-PDF für den Kunden** (Modul Stundenzettel) — Eddy hat
sich bewusst dafür entschieden; die App weist im Dialog darauf hin.
- Geprüft (Testinstanz über die App): speichern mehrzeilig, Konflikt 409 bei Büro-Änderung, „Büro-Stand + meine
Ergänzung" behält beides.
## 1.8.0 — 2026-10-19
### Videos aus der Baustellen-App

View file

@ -16,6 +16,7 @@ Bilder und PDFs lassen sich im Browser annotieren (Pfeile, Kreise, Rechtecke, Te
- **Bild einer Seite austauschen** ohne sie zu löschen — Reihenfolge, Notiz und Anmerkungen bleiben erhalten. Bei Raster-Layouts lässt sich jeder Platz einzeln tauschen, direkt auf der Seite anklickbar.
- **Ziehen und Ablegen**: Kachel auf die Seitenliste legt neue Seiten an, Kachel auf die Arbeitsfläche ersetzt das Bild der offenen Seite, Kachel auf einen Raster-Platz setzt genau diesen. Dateien vom Rechner auf die Anhänge-Spalte werden hochgeladen.
- **Mobiler Upload per QR-Code** — Handy scannt, lädt Fotos direkt in den offenen Bericht (zeitlich begrenzte Token)
- **Auftragsbeschreibung aus der Baustellen-App (1.9.0)** — `orders.php?action=set_beschreibung` schreibt das Zusatzfeld `auftragsbeschreibung` (Merkzettel zum Auftrag), mit Konfliktschutz (409 bei Büro-Änderung). Steht auch auf dem Stundenzettel-PDF.
- **Videos aus der Baustellen-App (1.8.0)** — `orders.php?action=upload_photo` nimmt mp4/m4v/mov/webm (Inhalt geprüft, Name `video_…`, Aufnahmezeit aus `taken_at` bzw. dem MP4-Kopf), `photo.php` liefert Teilbereiche (Range) zum Abspielen und Spulen, `config.php` meldet `upload_max`, zu groß → 413. Im Editor 🎬-Kachel, nicht in Berichte übernehmbar.
- **AVIF- und WebP-Bilder (1.7.4/1.7.5)** — beim Hochladen (Editor, PWA, Handy-Upload) am Inhalt erkannt und in JPG bzw. PNG (mit Transparenz) umgewandelt (`lib/bericht_avif.lib.php`, `bericht_upload_bild_umwandeln()`, KB #1698, #447). Bewegte WebP werden mit Meldung abgelehnt.
- **Ablage am Beleg als Beilage (1.7.2)** — Fotos, Notizen, Sprachnotizen, Scans und Bericht-PDFs, die im Belegordner landen, stehen im ECM-Index als `uploaded` (`lib/bericht_index.lib.php`): nur im Reiter „Verknüpfte Dokumente", nie vorne im Kasten der Belegkarte (KB #1641)
@ -106,6 +107,10 @@ GET /custom/bericht/api/orders.php?id=<id>
GET /custom/bericht/api/orders.php?id=<id>&action=photos
Je Datei: filename, size, mime, date (mtime), taken_at (EXIF-Aufnahmezeit, sonst
Dateidatum), relpath. Sortiert nach taken_at, neuste zuerst.
POST /custom/bericht/api/orders.php?id=<id>&action=set_beschreibung (1.9.0)
Body: { text, vorher? } — Auftragsbeschreibung (Zusatzfeld auftragsbeschreibung) ändern,
Recht „Aufträge ändern". Weicht der Server-Stand von `vorher` ab → 409 mit aktuellem Text.
Achtung: die Beschreibung steht auch auf dem Stundenzettel-PDF für den Kunden.
POST /custom/bericht/api/orders.php?action=create
Body: { socid, ref_client, title?, note_private?, date?, date_livraison?, validate? }
ref_client ("Ihr Zeichen") ist PFLICHT. validate=true gibt den Auftrag direkt frei —

View file

@ -21,6 +21,12 @@
* Die Leistungen kommen später aus dem Stundenzettel.
* Legt einen Draft-Auftrag an und übernimmt Kunden-Defaults (Zahlungsbedingungen,
* Zahlart, Bankkonto, Incoterms, Lieferadresse, Default-Ansprechpartner).
* POST /api/orders.php?id=<id>&action=set_beschreibung (1.9.0)
* JSON-Body: { text, vorher? } — Auftragsbeschreibung (Extrafield auftragsbeschreibung) ändern.
* Eddy: „Sachen, die ich mir merken will, lieber in der Auftragsbeschreibung festhalten."
* `vorher` = Stand, den die App angezeigt hat: weicht der Server-Stand ab (im Büro geändert),
* antwortet die API mit 409 und dem aktuellen Text statt ihn zu überschreiben.
* ⚠ Die Beschreibung steht auch auf dem Stundenzettel-PDF für den Kunden (Eddy wollte es so).
*/
require_once __DIR__.'/_inc.php';
@ -302,6 +308,28 @@ if ($action === 'upload_photo' && $_SERVER['REQUEST_METHOD'] === 'POST') {
));
}
/* ----- AUFTRAGSBESCHREIBUNG ÄNDERN (1.9.0) ----- */
if ($action === 'set_beschreibung' && $_SERVER['REQUEST_METHOD'] === 'POST') {
if (!$user->hasRight('commande', 'creer')) api_fail('Keine Berechtigung, Aufträge zu ändern', 403);
$in = api_input();
// Zeilenenden vereinheitlichen, Leerzeichen am Ende weg — sonst gilt jeder Handy-Text als „geändert"
$norm = function ($t) { return rtrim(str_replace(array("\r\n", "\r"), "\n", (string) $t)); };
$text = $norm($in['text'] ?? '');
if (mb_strlen($text, 'UTF-8') > 20000) api_fail('Die Beschreibung ist zu lang');
$aktuell = $norm($cmd->array_options['options_auftragsbeschreibung'] ?? '');
if (array_key_exists('vorher', $in) && $norm($in['vorher']) !== $aktuell) {
api_send(array('error' => 'Die Beschreibung wurde inzwischen geändert — bitte den neuen Stand ansehen.',
'auftragsbeschreibung' => $aktuell), 409);
}
if ($text === $aktuell) api_ok(array('auftragsbeschreibung' => $aktuell, 'unveraendert' => true));
$cmd->array_options['options_auftragsbeschreibung'] = ($text === '') ? null : $text;
// Wie „Zusatzfelder ändern" auf der Auftragskarte: Trigger ORDER_MODIFY (Ereignis, Benachrichtigungen)
if ($cmd->updateExtraField('auftragsbeschreibung', 'ORDER_MODIFY', $user) < 0) {
api_fail('Speichern fehlgeschlagen: '.($cmd->error ?: $db->lasterror()), 500);
}
api_ok(array('auftragsbeschreibung' => $text));
}
// Default: Auftrags-Detail
$berichte = Bericht::fetchAllForElement($db, 'order', $cmd->id);
$berichte_out = array();

View file

@ -27,7 +27,7 @@ class modBericht extends DolibarrModules
$this->editor_name = 'Alles Watt läuft';
$this->editor_url = '';
$this->version = '1.8.0';
$this->version = '1.9.0';
$this->const_name = 'MAIN_MODULE_'.strtoupper($this->name);
$this->picto = 'fa-file-pdf';