All checks were successful
Deploy Eplan / deploy (push) Successful in 14s
Statt aller ElektroPlan-Projekte wird über die Backend-Verknüpfung
(Auftrag→Projekt, /api/dolibarr/auftraege/{id}/projekt) nur das zu diesem
Auftrag gehörende Aufmaß geladen — inkl. Räume-Anzahl, Gesamtfläche und
Quelle (Baustelle/Editor). Behebt den TODO-Platzhalter, der projektfremde
Aufmaße anzeigte.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
175 lines
8 KiB
PHP
175 lines
8 KiB
PHP
<?php
|
|
/* Copyright (C) 2026 Eduard Wisch <data@data-it-solution.de>
|
|
* GPL v3+
|
|
*
|
|
* Tab "Aufmaß" auf der Auftragskarte
|
|
*/
|
|
|
|
$res = 0;
|
|
if (!$res && !empty($_SERVER["CONTEXT_DOCUMENT_ROOT"])) $res = @include $_SERVER["CONTEXT_DOCUMENT_ROOT"]."/main.inc.php";
|
|
$tmp = empty($_SERVER['SCRIPT_FILENAME']) ? '' : $_SERVER['SCRIPT_FILENAME']; $tmp2 = realpath(__FILE__); $i = strlen($tmp) - 1; $j = strlen($tmp2) - 1;
|
|
while ($i > 0 && $j > 0 && isset($tmp[$i]) && isset($tmp2[$j]) && $tmp[$i] == $tmp2[$j]) { $i--; $j--; }
|
|
if (!$res && $i > 0 && file_exists(substr($tmp, 0, ($i + 1))."/main.inc.php")) $res = @include substr($tmp, 0, ($i + 1))."/main.inc.php";
|
|
if (!$res && $i > 0 && file_exists(dirname(substr($tmp, 0, ($i + 1)))."/main.inc.php")) $res = @include dirname(substr($tmp, 0, ($i + 1)))."/main.inc.php";
|
|
if (!$res && file_exists("../main.inc.php")) $res = @include "../main.inc.php";
|
|
if (!$res && file_exists("../../main.inc.php")) $res = @include "../../main.inc.php";
|
|
if (!$res) die("Include of main fails");
|
|
|
|
require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
|
|
require_once DOL_DOCUMENT_ROOT.'/core/lib/order.lib.php';
|
|
|
|
$langs->loadLangs(array('orders', 'eplan@eplan'));
|
|
|
|
$id = GETPOSTINT('id');
|
|
$ref = GETPOST('ref', 'alpha');
|
|
|
|
$object = new Commande($db);
|
|
if ($id > 0 || !empty($ref)) {
|
|
$object->fetch($id, $ref);
|
|
}
|
|
|
|
if (!$object->id) {
|
|
llxHeader('', 'Aufmaß');
|
|
print '<div class="error">Auftrag nicht gefunden</div>';
|
|
llxFooter();
|
|
exit;
|
|
}
|
|
|
|
$pwa_url = getDolGlobalString('EPLAN_PWA_URL');
|
|
|
|
// Sicherheit
|
|
if (!$user->hasRight('eplan', 'read')) accessforbidden();
|
|
|
|
llxHeader('', 'Aufmaß — '.$object->ref, '', '', 0, 0, '', '', '', 'mod-eplan');
|
|
|
|
// Auftrag-Header + Tabs
|
|
$head = commande_prepare_head($object);
|
|
print dol_get_fiche_head($head, 'aufmass', $langs->trans("Order"), -1, 'order');
|
|
|
|
// Auftrag-Info-Leiste
|
|
dol_banner_tab($object, 'ref', '', 1, 'ref', 'ref');
|
|
|
|
print '<div class="fichecenter">';
|
|
print '<div class="underbanner clearboth"></div>';
|
|
|
|
// PWA-Link mit Auftrags-Kontext
|
|
if (!empty($pwa_url)) {
|
|
$pwa_link = $pwa_url . '/?auftrag=' . urlencode($object->ref) . '&kunde=' . urlencode($object->thirdparty->name ?? '') . '&auftrag_id=' . $object->id;
|
|
|
|
print '<div style="background: linear-gradient(135deg, #1565C0 0%, #0D47A1 100%); border-radius: 10px; padding: 20px; margin: 16px 0; color: #fff; box-sizing: border-box;">';
|
|
print '<div style="display: flex; align-items: center; justify-content: space-between; flex-wrap: wrap; gap: 16px;">';
|
|
print '<div style="flex: 1; min-width: 220px;">';
|
|
print '<strong style="font-size: 16px;">Aufmaß für ' . dol_escape_htmltag($object->ref) . '</strong>';
|
|
if (!empty($object->thirdparty->name)) {
|
|
print '<br><span style="opacity: 0.8; font-size: 13px;">' . dol_escape_htmltag($object->thirdparty->name) . '</span>';
|
|
}
|
|
print '<br><span style="opacity: 0.7; font-size: 12px; margin-top: 8px; display: inline-block;">QR mit Handy scannen oder Button klicken — Auftrag wird automatisch verknüpft.</span>';
|
|
print '<div style="margin-top: 12px;">';
|
|
print '<a href="' . dol_escape_htmltag($pwa_link) . '" target="_blank" rel="noopener" ';
|
|
print 'style="display: inline-block; background: #fff; color: #1565C0; padding: 10px 24px; border-radius: 8px; font-size: 14px; font-weight: 700; text-decoration: none;">';
|
|
print '<i class="fas fa-drafting-compass" style="margin-right: 6px;"></i>Aufmaß starten</a>';
|
|
print '</div>';
|
|
print '</div>';
|
|
// QR-Code (clientseitig generiert, kein externer Tracking-Service)
|
|
print '<div id="eplan-qr" style="background: #fff; padding: 8px; border-radius: 8px; flex-shrink: 0;"></div>';
|
|
print '</div>';
|
|
print '</div>';
|
|
|
|
// qrcode-generator (selbsthosting wäre besser, aber CDN ist akzeptabel —
|
|
// bei fehlender Internet-Verbindung bleibt zumindest der Text-Link nutzbar)
|
|
print '<script src="https://cdn.jsdelivr.net/npm/qrcode-generator@1.4.4/qrcode.min.js"></script>';
|
|
print '<script>(function(){';
|
|
print ' if (typeof qrcode !== "function") return;';
|
|
print ' var q = qrcode(0, "M");';
|
|
print ' q.addData(' . json_encode($pwa_link, JSON_UNESCAPED_SLASHES) . ');';
|
|
print ' q.make();';
|
|
print ' var el = document.getElementById("eplan-qr");';
|
|
print ' if (el) el.innerHTML = q.createSvgTag({cellSize: 4, margin: 0});';
|
|
print '})();</script>';
|
|
} else {
|
|
print '<div class="warning" style="margin: 16px 0;">';
|
|
print '<i class="fas fa-exclamation-triangle"></i> ElektroPlan PWA-URL nicht konfiguriert. ';
|
|
print '<a href="' . dol_buildpath('/eplan/admin/setup.php', 1) . '">Einstellungen öffnen</a>';
|
|
print '</div>';
|
|
}
|
|
|
|
// Aufmaß-Daten aus dem ElektroPlan-Backend laden — nur das mit DIESEM Auftrag
|
|
// verknüpfte Projekt (über die Verknüpfungstabelle im Backend).
|
|
$api_url = rtrim(getDolGlobalString('EPLAN_PWA_URL'), '/');
|
|
$projekt = null;
|
|
$raeume = array();
|
|
if (!empty($api_url)) {
|
|
// Kleiner GET-Helfer: liefert dekodiertes JSON-Array oder null
|
|
$eplan_get = function ($pfad) use ($api_url) {
|
|
$ch = curl_init($api_url.$pfad);
|
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
|
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
|
|
$resp = curl_exec($ch);
|
|
$code = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
|
curl_close($ch);
|
|
if ($resp === false || $code < 200 || $code >= 300) return null;
|
|
$daten = json_decode($resp, true);
|
|
return is_array($daten) ? $daten : null;
|
|
};
|
|
|
|
// Auftrag → projekt_id auflösen
|
|
$verkn = $eplan_get('/api/dolibarr/auftraege/'.((int) $object->id).'/projekt');
|
|
$projekt_id = $verkn['projekt_id'] ?? null;
|
|
if (!empty($projekt_id)) {
|
|
$projekt = $eplan_get('/api/projekte/'.rawurlencode($projekt_id));
|
|
$raeume = $eplan_get('/api/projekte/'.rawurlencode($projekt_id).'/raeume');
|
|
if (!is_array($raeume)) $raeume = array();
|
|
}
|
|
}
|
|
|
|
print '<table class="noborder centpercent" style="margin-top: 16px;">';
|
|
print '<tr class="liste_titre">';
|
|
print '<td>Grundriss</td><td class="center">Räume</td><td class="right">Fläche</td><td>Quelle</td><td>Erstellt</td><td></td>';
|
|
print '</tr>';
|
|
|
|
if (!empty($projekt)) {
|
|
// Gesamtfläche + Quellen aus den Räumen aggregieren
|
|
$flaeche = 0.0;
|
|
$quellen = array();
|
|
foreach ($raeume as $r) {
|
|
$flaeche += (float) ($r['flaeche_m2'] ?? 0);
|
|
$q = $r['quelle'] ?? '';
|
|
if ($q !== '' && !in_array($q, $quellen, true)) $quellen[] = $q;
|
|
}
|
|
$quelleLabel = empty($quellen) ? '-' : implode(', ', array_map(function ($q) {
|
|
return $q === 'aufmass' ? 'Baustelle' : ($q === 'editor' ? 'Editor' : $q);
|
|
}, $quellen));
|
|
|
|
// Öffnen-Link mit Auftrags-Kontext → PWA lädt das verknüpfte Projekt automatisch
|
|
$open_link = $pwa_url . '/?auftrag=' . urlencode($object->ref)
|
|
. '&kunde=' . urlencode($object->thirdparty->name ?? '')
|
|
. '&auftrag_id=' . ((int) $object->id);
|
|
|
|
print '<tr class="oddeven">';
|
|
print '<td>'.dol_escape_htmltag($projekt['name'] ?? '-').'</td>';
|
|
print '<td class="center">'.count($raeume).'</td>';
|
|
print '<td class="right">'.($flaeche > 0 ? price($flaeche, 0, '', 0, 2).' m²' : '-').'</td>';
|
|
print '<td>'.dol_escape_htmltag($quelleLabel).'</td>';
|
|
print '<td>'.dol_print_date(strtotime($projekt['geaendert'] ?? $projekt['erstellt'] ?? ''), 'dayhour').'</td>';
|
|
print '<td class="right">';
|
|
if (!empty($pwa_url)) {
|
|
print '<a href="'.dol_escape_htmltag($open_link).'" target="_blank" rel="noopener" class="butAction butActionSmall">Öffnen</a>';
|
|
}
|
|
print '</td>';
|
|
print '</tr>';
|
|
} else {
|
|
print '<tr class="oddeven"><td colspan="6" class="opacitymedium" style="text-align: center; padding: 20px;">';
|
|
if (empty($api_url)) {
|
|
print 'ElektroPlan-Backend nicht erreichbar (PWA-URL nicht konfiguriert).';
|
|
} else {
|
|
print 'Noch kein Aufmaß mit diesem Auftrag verknüpft. Starte ein neues Aufmaß über den Button oben.';
|
|
}
|
|
print '</td></tr>';
|
|
}
|
|
|
|
print '</table>';
|
|
|
|
print '</div>'; // fichecenter
|
|
print dol_get_fiche_end();
|
|
llxFooter();
|
|
$db->close();
|