bericht/class/actions_bericht.class.php
Eduard Wisch ca2b796b36
All checks were successful
Deploy bericht / deploy (push) Successful in 6s
Feature: Lieferschein-Unterschrift via ODT-Hook + PWA-Signatur-Workflow
- Neuer API-Endpoint api/shipments.php: Liste Lieferungen zu Auftrag, PDF-Stream, confirm (Unterschrift stempeln)
- ODT-Hook actions_bericht.class.php: ersetzt {signature} Platzhalter via odfphp->setImage, setzt {signer_name}/{signed_at}/{gps}
- Backup-Roundtrip: generateDocument-Backup → signed.pdf erzeugen → Original wiederherstellen
- JWT-Fallback in _jwt.php: ?jwt= Query-Param für <img>/<object> ohne Authorization-Header
- Admin: BERICHT_SIGNATURE_IMAGE_RATIO Feld, Toggle BERICHT_TAB_ON_SHIPMENT, Signature-Box-Editor
- DB: llx_bericht_signature_box für pro-Template mm-Box-Geometrie
- element_type='shipment' in modBericht + lib/bericht.lib.php
- element_element Richtung: commande=source, shipping=target (fk_target=expedition_id)
- DOL_DATA_ROOT-Auflösung für EXPEDITION_ADDON_PDF_ODT_PATH
- Sprachen: de_DE + en_US mit neuen Schlüsseln für Signatur-Workflow

[deploy]

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 06:48:42 +02:00

77 lines
3.4 KiB
PHP

<?php
/* Copyright (C) 2026 Eduard Wisch <data@data-it-solution.de>
* GPL v3+
*
* Hook-Klasse fuer das Bericht-Modul.
* Aktuell genutzt fuer: setImage('signature') beim ODT-Render von Lieferscheinen.
*/
class ActionsBericht
{
/** @var string */
public $error = '';
/** @var string[] */
public $errors = array();
/** @var array<string,mixed> */
public $results = array();
/**
* Hook fuer Dolibarrs ODT-Generation. Wird VOR dem saveToDisk aufgerufen.
* Wenn das Objekt eine Expedition mit gesetzter $object->bericht_signature_png ist,
* setzen wir das Bild im ODT-Platzhalter "signature" ein und befuellen Audit-Vars.
*
* Wichtig (KB #434): Bei MAIN_ODT_AS_PDF=libreoffice MUSS dieser Hook (nicht afterODTCreation)
* verwendet werden — sonst ist das ODT bereits zu PDF konvertiert.
*
* @param array<string,mixed> $parameters
* @param object $object
* @param string $action
* @return int 0 = OK
*/
public function beforeODTSave($parameters, &$object, &$action)
{
dol_syslog('ActionsBericht::beforeODTSave aufgerufen', LOG_DEBUG);
if (empty($parameters['odfHandler'])) { dol_syslog('ActionsBericht: kein odfHandler', LOG_DEBUG); return 0; }
$odfHandler = $parameters['odfHandler'];
$obj = isset($parameters['object']) ? $parameters['object'] : $object;
if (!is_object($obj)) { dol_syslog('ActionsBericht: kein Objekt', LOG_DEBUG); return 0; }
$cls = get_class($obj);
$has = property_exists($obj, 'bericht_signature_png') ? 'yes' : 'no';
$png = $obj->bericht_signature_png ?? '';
dol_syslog('ActionsBericht: obj='.$cls.' bericht_signature_png prop='.$has.' val='.$png.' exists='.($png && file_exists($png) ? 'yes' : 'no'), LOG_DEBUG);
// Nur greifen wenn shipments.php zuvor den Signatur-Pfad gesetzt hat
if (empty($obj->bericht_signature_png) || !file_exists($obj->bericht_signature_png)) {
dol_syslog('ActionsBericht: skip - kein signature_png', LOG_DEBUG);
return 0;
}
// setImage: ersetzt {signature}-Text im ODT durch das PNG-draw-frame
try {
$ratio = (float) getDolGlobalString('BERICHT_SIGNATURE_IMAGE_RATIO', '0.35');
$odfHandler->setImage('signature', $obj->bericht_signature_png, $ratio);
dol_syslog('ActionsBericht: setImage(signature) ok, ratio='.$ratio.' png='.$obj->bericht_signature_png, LOG_INFO);
} catch (Throwable $e) {
dol_syslog('ActionsBericht::beforeODTSave setImage(signature) failed: '.$e->getMessage(), LOG_WARNING);
}
// Zusatz-Variablen fuer Audit (optional im ODT als {signer_name} etc.)
$meta = isset($obj->bericht_signature_meta) && is_array($obj->bericht_signature_meta)
? $obj->bericht_signature_meta : array();
$gps_str = '';
if (!empty($meta['gps_lat']) && !empty($meta['gps_lon'])) {
$gps_str = sprintf('%.6f, %.6f', $meta['gps_lat'], $meta['gps_lon']);
}
$vars = array(
'signer_name' => (string) ($meta['signer_name'] ?? ''),
'signed_at' => (string) ($meta['signed_at'] ?? ''),
'gps' => $gps_str,
);
foreach ($vars as $k => $v) {
try { $odfHandler->setVars($k, $v, true, 'UTF-8'); }
catch (Throwable $e) { /* Key muss nicht im ODT existieren */ }
}
return 0;
}
}