Fotoqualitaet einstellbar, Vorgabe 1:1 statt fest 2000 px (v1.7.0) [deploy]
All checks were successful
Deploy bericht / deploy (push) Successful in 14s
All checks were successful
Deploy bericht / deploy (push) Successful in 14s
Eddy: „deswegen erkenne ich so wenig — mach im Admin eine Einstellung fuers
Verkleinern und stelle sie auf 100% 1:1. Ich will die volle Handy-Qualitaet der
Kamera, nichts anderes."
- Admin → Bericht → „Fotoqualitaet der Baustellen-App":
BERICHT_PHOTO_MAXSIDE (0 = Originalgroesse, sonst 4000/3000/2000/1600 px)
und BERICHT_PHOTO_QUALITY (nur relevant, wenn verkleinert wird)
- Vorgabe ist 0 = Originalgroesse. Ohne Zutun laedt die App ab jetzt das
unveraenderte Kamerabild. Prod-Limits tragen das (upload_max_filesize 300M,
nachgesehen)
- neuer Endpoint api/config.php liefert die Werte an die PWA, Auth per awl_sso
- Lang-Keys de+en
Nebenbefund, an einem Bestandsfoto gemessen: den bisherigen Fotos fehlt das
EXIF vollstaendig (Quality 85, kein DateTimeOriginal). Das Canvas-Verkleinern
hat es entfernt — deshalb fiel bericht_file_taken_at() immer auf das Dateidatum
zurueck. Mit 1:1 bleibt das Kamera-EXIF erhalten.
Admin-Feld und Endpoint lokal im Browser geprueft: Auswahl steht auf
Originalgroesse, config.php liefert {ok:true, photo_maxside:0, photo_quality:100}.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
004d9ab244
commit
7f51c89d3f
5 changed files with 79 additions and 0 deletions
25
ChangeLog.md
25
ChangeLog.md
|
|
@ -1,5 +1,30 @@
|
||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 1.7.0 — 2026-08-28
|
||||||
|
|
||||||
|
### Fotoqualität ist einstellbar — Vorgabe ist jetzt 1:1
|
||||||
|
|
||||||
|
Die Baustelle-PWA hat **jedes** Foto fest auf 2000 px heruntergerechnet. Auf Typenschildern,
|
||||||
|
Zählerständen und Mängeln war danach beim Hineinzoomen nichts mehr zu erkennen. Das war
|
||||||
|
nirgends einstellbar, sondern eine Zahl im JavaScript.
|
||||||
|
|
||||||
|
- **Admin → Bericht → „📷 Fotoqualität der Baustellen-App"**: `BERICHT_PHOTO_MAXSIDE`
|
||||||
|
(0 = Originalgröße, sonst 4000/3000/2000/1600 px) und `BERICHT_PHOTO_QUALITY`
|
||||||
|
(JPEG-Qualität, greift nur beim Verkleinern).
|
||||||
|
- **Vorgabe ist 0 = Originalgröße.** Ohne Eingriff lädt die App ab jetzt das unveränderte
|
||||||
|
Kamerabild hoch. Die PHP-Limits auf Prod tragen das mühelos (`upload_max_filesize` 300M).
|
||||||
|
- Neuer Endpoint **`api/config.php`** liefert die Werte an die PWA (Auth wie überall per
|
||||||
|
`awl_sso`-Cookie). Die App merkt sich die Antwort lokal, damit auch offline klar ist,
|
||||||
|
was gilt.
|
||||||
|
|
||||||
|
### Nebenbefund: den bisherigen Fotos fehlt das EXIF komplett
|
||||||
|
|
||||||
|
Ein Foto aus dem Bestand nachgemessen: `Quality: 85`, **kein** `DateTimeOriginal`, kein
|
||||||
|
EXIF-Block. Das Herunterrechnen lief über ein Canvas, und dabei geht sämtliche
|
||||||
|
EXIF-Information verloren — Aufnahmezeitpunkt, Ausrichtung, GPS. `bericht_file_taken_at()`
|
||||||
|
musste deshalb bisher immer auf das Dateidatum ausweichen. Mit der neuen Vorgabe (1:1, kein
|
||||||
|
Canvas) bleibt das EXIF der Kamera erhalten.
|
||||||
|
|
||||||
## 1.6.0 — 2026-08-28
|
## 1.6.0 — 2026-08-28
|
||||||
|
|
||||||
### Dasselbe Foto kommt kein zweites Mal in den Auftragsordner
|
### Dasselbe Foto kommt kein zweites Mal in den Auftragsordner
|
||||||
|
|
|
||||||
|
|
@ -68,6 +68,10 @@ if ($action === 'save_const') {
|
||||||
'BERICHT_TAB_ON_SHIPMENT' => GETPOST('tab_shipment', 'int') ? '1' : '0',
|
'BERICHT_TAB_ON_SHIPMENT' => GETPOST('tab_shipment', 'int') ? '1' : '0',
|
||||||
'BERICHT_SIGNATURE_IMAGE_RATIO' => str_replace(',', '.', (string) GETPOST('sig_ratio', 'alphanohtml')) ?: '0.35',
|
'BERICHT_SIGNATURE_IMAGE_RATIO' => str_replace(',', '.', (string) GETPOST('sig_ratio', 'alphanohtml')) ?: '0.35',
|
||||||
'BERICHT_BURN_ANNOTATIONS' => GETPOST('burn', 'int') ? '1' : '0',
|
'BERICHT_BURN_ANNOTATIONS' => GETPOST('burn', 'int') ? '1' : '0',
|
||||||
|
// Fotoqualitaet der Baustelle-PWA. 0 = Originalgroesse (1:1, Vorgabe),
|
||||||
|
// sonst die laengste Kante in Pixeln.
|
||||||
|
'BERICHT_PHOTO_MAXSIDE' => (string) max(0, GETPOSTINT('photo_maxside')),
|
||||||
|
'BERICHT_PHOTO_QUALITY' => (string) min(100, max(50, GETPOSTINT('photo_quality') ?: 100)),
|
||||||
'BERICHT_LIBREOFFICE_BIN' => GETPOST('lobin', 'alphanohtml'),
|
'BERICHT_LIBREOFFICE_BIN' => GETPOST('lobin', 'alphanohtml'),
|
||||||
'BERICHT_WHISPER_URL' => GETPOST('whisper_url', 'alphanohtml'),
|
'BERICHT_WHISPER_URL' => GETPOST('whisper_url', 'alphanohtml'),
|
||||||
'BERICHT_WHISPER_MODE' => GETPOST('whisper_mode', 'alphanohtml'),
|
'BERICHT_WHISPER_MODE' => GETPOST('whisper_mode', 'alphanohtml'),
|
||||||
|
|
@ -229,6 +233,25 @@ print '<br><span class="opacitymedium small">'.$langs->trans("BerichtSetupSignat
|
||||||
print '</td></tr>';
|
print '</td></tr>';
|
||||||
print '<tr class="oddeven"><td>'.$langs->trans("BerichtSetupBurnAnnotations").'</td><td>'.$cb('burn', 'BERICHT_BURN_ANNOTATIONS', '1').'</td></tr>';
|
print '<tr class="oddeven"><td>'.$langs->trans("BerichtSetupBurnAnnotations").'</td><td>'.$cb('burn', 'BERICHT_BURN_ANNOTATIONS', '1').'</td></tr>';
|
||||||
|
|
||||||
|
// --- Fotoqualitaet der Baustelle-PWA ---
|
||||||
|
// Bis v1.6.0 hat die PWA jedes Foto fest auf 2000 px verkleinert. Auf Typenschildern
|
||||||
|
// und Zaehlerstaenden war danach nichts mehr zu lesen. Jetzt einstellbar, Vorgabe 1:1.
|
||||||
|
$photo_maxside = getDolGlobalInt('BERICHT_PHOTO_MAXSIDE', 0);
|
||||||
|
$photo_quality = getDolGlobalInt('BERICHT_PHOTO_QUALITY', 100);
|
||||||
|
print '<tr><td colspan="2"><h4 style="margin:16px 0 4px 0;">📷 '.$langs->trans("BerichtSetupPhotoHeader").'</h4></td></tr>';
|
||||||
|
print '<tr class="oddeven"><td>'.$langs->trans("BerichtSetupPhotoMaxSide").'</td><td>';
|
||||||
|
print '<select name="photo_maxside" class="flat">';
|
||||||
|
foreach (array(0 => $langs->trans("BerichtSetupPhotoFull"), 4000 => '4000 px', 3000 => '3000 px', 2000 => '2000 px', 1600 => '1600 px') as $v => $lbl) {
|
||||||
|
print '<option value="'.((int) $v).'"'.($photo_maxside == $v ? ' selected' : '').'>'.dol_escape_htmltag($lbl).'</option>';
|
||||||
|
}
|
||||||
|
print '</select>';
|
||||||
|
print '<br><span class="opacitymedium small">'.$langs->trans("BerichtSetupPhotoMaxSideDesc").'</span>';
|
||||||
|
print '</td></tr>';
|
||||||
|
print '<tr class="oddeven"><td>'.$langs->trans("BerichtSetupPhotoQuality").'</td><td>';
|
||||||
|
print '<input type="number" min="50" max="100" step="5" name="photo_quality" value="'.((int) $photo_quality).'" size="4"> %';
|
||||||
|
print '<br><span class="opacitymedium small">'.$langs->trans("BerichtSetupPhotoQualityDesc").'</span>';
|
||||||
|
print '</td></tr>';
|
||||||
|
|
||||||
print '<tr class="oddeven"><td>'.$langs->trans("BerichtSetupLibreOfficeBin").'</td><td>';
|
print '<tr class="oddeven"><td>'.$langs->trans("BerichtSetupLibreOfficeBin").'</td><td>';
|
||||||
print '<input type="text" name="lobin" value="'.dol_escape_htmltag(getDolGlobalString('BERICHT_LIBREOFFICE_BIN', '/usr/bin/libreoffice')).'" size="40">';
|
print '<input type="text" name="lobin" value="'.dol_escape_htmltag(getDolGlobalString('BERICHT_LIBREOFFICE_BIN', '/usr/bin/libreoffice')).'" size="40">';
|
||||||
print '</td></tr>';
|
print '</td></tr>';
|
||||||
|
|
|
||||||
19
api/config.php
Normal file
19
api/config.php
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
<?php
|
||||||
|
/* GET /api/config.php
|
||||||
|
* Liefert die Einstellungen, die die Baustelle-PWA zur Laufzeit braucht.
|
||||||
|
* Auth wie ueberall per awl_sso-Cookie (api_authenticate).
|
||||||
|
*
|
||||||
|
* Antwort:
|
||||||
|
* photo_maxside — laengste Kante in px, an die die PWA ein Foto vor dem Upload
|
||||||
|
* anpasst. 0 = Originalgroesse (1:1), das ist die Vorgabe.
|
||||||
|
* photo_quality — JPEG-Qualitaet in Prozent; greift nur, wenn tatsaechlich
|
||||||
|
* umgerechnet wird (also bei photo_maxside > 0).
|
||||||
|
*/
|
||||||
|
require_once __DIR__.'/_inc.php';
|
||||||
|
|
||||||
|
api_authenticate();
|
||||||
|
|
||||||
|
api_ok(array(
|
||||||
|
'photo_maxside' => getDolGlobalInt('BERICHT_PHOTO_MAXSIDE', 0),
|
||||||
|
'photo_quality' => getDolGlobalInt('BERICHT_PHOTO_QUALITY', 100),
|
||||||
|
));
|
||||||
|
|
@ -60,6 +60,12 @@ BerichtSetupTabShipment = Reiter auf Lieferungen anzeigen
|
||||||
BerichtSetupSignatureRatio = Größen-Faktor Lieferschein-Unterschrift
|
BerichtSetupSignatureRatio = Größen-Faktor Lieferschein-Unterschrift
|
||||||
BerichtSetupSignatureRatioDesc = Wie groß das {signature}-Bild im gerenderten ODT-PDF wird (0.35 ≈ 7×3.5 cm; höher = größer). Wird zur Laufzeit gegen die PNG-Pixel multipliziert.
|
BerichtSetupSignatureRatioDesc = Wie groß das {signature}-Bild im gerenderten ODT-PDF wird (0.35 ≈ 7×3.5 cm; höher = größer). Wird zur Laufzeit gegen die PNG-Pixel multipliziert.
|
||||||
BerichtSetupBurnAnnotations = Annotationen ins PDF einbrennen (statt als PDF-Annotations)
|
BerichtSetupBurnAnnotations = Annotationen ins PDF einbrennen (statt als PDF-Annotations)
|
||||||
|
BerichtSetupPhotoHeader = Fotoqualität der Baustellen-App
|
||||||
|
BerichtSetupPhotoMaxSide = Fotos verkleinern auf
|
||||||
|
BerichtSetupPhotoFull = Originalgröße (1:1, volle Kameraqualität)
|
||||||
|
BerichtSetupPhotoMaxSideDesc = Längste Kante, auf die ein Foto vor dem Hochladen gerechnet wird. Originalgröße lädt das Bild unverändert hoch — nötig, damit Typenschilder, Zählerstände und Mängel beim Hineinzoomen lesbar bleiben. Kleinere Werte sparen Mobilfunk-Daten.
|
||||||
|
BerichtSetupPhotoQuality = JPEG-Qualität
|
||||||
|
BerichtSetupPhotoQualityDesc = Wirkt nur, wenn oben verkleinert wird. Bei Originalgröße bleibt die Datei so, wie die Kamera sie geliefert hat.
|
||||||
BerichtSetupLibreOfficeBin = Pfad zu LibreOffice (für ODT→PDF)
|
BerichtSetupLibreOfficeBin = Pfad zu LibreOffice (für ODT→PDF)
|
||||||
BerichtPlaceholdersTitle = Verfügbare Platzhalter in der ODT-Vorlage
|
BerichtPlaceholdersTitle = Verfügbare Platzhalter in der ODT-Vorlage
|
||||||
BerichtErrorNoParent = Übergeordnetes Dokument nicht gefunden
|
BerichtErrorNoParent = Übergeordnetes Dokument nicht gefunden
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,12 @@ BerichtSetupTabShipment = Show tab on shipments
|
||||||
BerichtSetupSignatureRatio = Delivery signature image ratio
|
BerichtSetupSignatureRatio = Delivery signature image ratio
|
||||||
BerichtSetupSignatureRatioDesc = How large the {signature} image is in the rendered ODT PDF (0.35 ≈ 7×3.5 cm; higher = bigger). Multiplied against PNG pixels at runtime.
|
BerichtSetupSignatureRatioDesc = How large the {signature} image is in the rendered ODT PDF (0.35 ≈ 7×3.5 cm; higher = bigger). Multiplied against PNG pixels at runtime.
|
||||||
BerichtSetupBurnAnnotations = Burn annotations into PDF (instead of PDF annotations)
|
BerichtSetupBurnAnnotations = Burn annotations into PDF (instead of PDF annotations)
|
||||||
|
BerichtSetupPhotoHeader = Photo quality of the site app
|
||||||
|
BerichtSetupPhotoMaxSide = Resize photos to
|
||||||
|
BerichtSetupPhotoFull = Original size (1:1, full camera quality)
|
||||||
|
BerichtSetupPhotoMaxSideDesc = Longest edge a photo is scaled to before upload. Original size uploads the image untouched — required to keep rating plates, meter readings and defects readable when zooming in. Smaller values save mobile data.
|
||||||
|
BerichtSetupPhotoQuality = JPEG quality
|
||||||
|
BerichtSetupPhotoQualityDesc = Only applies when resizing above. At original size the file stays exactly as the camera produced it.
|
||||||
BerichtSetupLibreOfficeBin = LibreOffice binary path (for ODT→PDF)
|
BerichtSetupLibreOfficeBin = LibreOffice binary path (for ODT→PDF)
|
||||||
BerichtPlaceholdersTitle = Available placeholders in ODT template
|
BerichtPlaceholdersTitle = Available placeholders in ODT template
|
||||||
BerichtErrorNoParent = Parent document not found
|
BerichtErrorNoParent = Parent document not found
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue