bericht/bericht_thirdparty.php
Eduard Wisch 0fbfb1bf27
All checks were successful
Deploy bericht / deploy (push) Successful in 1s
feat: Phase 1.3 + 1.7 + Schema 1.4/1.5 — Format/Orient + Kunden-Tab
Phase 1.3 Seitenformat A4/A3/A5/Letter + Hoch/Quer:
- Neue Spalten page_format, page_orientation in llx_bericht
- Bericht-Meta zeigt Format + Orientation Selects
- Auto-Save via neuem ajax/save_meta.php
- generate_pdf + preview_pdf nutzen die gewählten Werte
- Bilder werden dynamisch via getPageWidth/getPageHeight skaliert
  (statt hardcoded 210x297 für A4)

Phase 1.4 + 1.5 Schema-Vorbereitung:
- Neue Tabelle llx_bericht_page_image für Multi-Image-Seiten
- Spalten layout, image_scale, image_align in llx_bericht_page
- DB-Migrationen im init() für bestehende Installationen
  (ALTER TABLE mit Error-Suppress)
- Grid-Rendering im Editor/PDF folgt im nächsten Commit
  (siehe CLAUDE.md TODO)

Phase 1.7 Tab "Berichte" auf Kundenkarte:
- Neue Konstante BERICHT_TAB_ON_THIRDPARTY (default 1)
- Tab-Definition in modBericht für 'thirdparty' Element
- Neue Datei bericht_thirdparty.php
- UNION-SQL über bericht JOIN commande/facture/propal mit fk_soc
- Read-only flache Tabelle sortiert nach Datum
- Pro Bericht: Quelle (Symbol + Ref-Link), Status, Öffnen/Zur Quelle

Version-Bump 1.0.0 → 1.1.0, ChangeLog ergänzt.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
[deploy]
2026-04-08 22:20:09 +02:00

128 lines
5.7 KiB
PHP

<?php
/* Read-only Übersicht aller Berichte eines Kunden.
* Listet ALLE Berichte zu den Aufträgen + Rechnungen + Angeboten dieses Kunden,
* sortiert nach Datum (neueste zuerst).
*
* NICHT zum Anlegen von Berichten. Hier wird kein Bericht direkt am Kunden gespeichert.
*
* GET: socid (thirdparty id)
*/
$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.'/societe/class/societe.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
require_once __DIR__.'/class/bericht.class.php';
if (!$user->hasRight('bericht', 'read')) accessforbidden();
if (!$user->hasRight('societe', 'lire')) accessforbidden();
$langs->loadLangs(array("bericht@bericht", "main", "companies"));
$socid = GETPOSTINT('socid');
if (!$socid) accessforbidden('socid fehlt');
$soc = new Societe($db);
if ($soc->fetch($socid) <= 0) accessforbidden('Kunde nicht gefunden');
// Berichte des Kunden ermitteln (ein UNION über alle drei Element-Typen)
$sql = "SELECT b.rowid, b.ref AS bref, b.titel, b.datec, b.status, b.element_type,"
." 'order' AS quelle, c.ref AS parent_ref, c.rowid AS parent_id"
." FROM ".$db->prefix()."bericht b"
." INNER JOIN ".$db->prefix()."commande c ON c.rowid = b.fk_element"
." WHERE b.element_type = 'order' AND c.fk_soc = ".((int) $socid)
." UNION "
."SELECT b.rowid, b.ref AS bref, b.titel, b.datec, b.status, b.element_type,"
." 'invoice' AS quelle, f.ref AS parent_ref, f.rowid AS parent_id"
." FROM ".$db->prefix()."bericht b"
." INNER JOIN ".$db->prefix()."facture f ON f.rowid = b.fk_element"
." WHERE b.element_type = 'invoice' AND f.fk_soc = ".((int) $socid)
." UNION "
."SELECT b.rowid, b.ref AS bref, b.titel, b.datec, b.status, b.element_type,"
." 'propal' AS quelle, p.ref AS parent_ref, p.rowid AS parent_id"
." FROM ".$db->prefix()."bericht b"
." INNER JOIN ".$db->prefix()."propal p ON p.rowid = b.fk_element"
." WHERE b.element_type = 'propal' AND p.fk_soc = ".((int) $socid)
." ORDER BY datec DESC";
$rows = array();
$resq = $db->query($sql);
if ($resq) {
while ($obj = $db->fetch_object($resq)) {
$rows[] = $obj;
}
}
llxHeader('', $langs->trans("Berichte").' — '.$soc->name, '', '', 0, 0, array(), array(), '', 'mod-bericht page-bericht-thirdparty');
$head = societe_prepare_head($soc);
print dol_get_fiche_head($head, 'bericht', $langs->trans("ThirdParty"), -1, 'company');
dol_banner_tab($soc, 'socid', '', ($user->socid ? 0 : 1), 'rowid', 'nom');
print dol_get_fiche_end();
print '<br>';
print '<div class="bericht-thirdparty-list">';
print '<h3>'.$langs->trans("Berichte").' ('.count($rows).')</h3>';
print '<p class="opacitymedium small">Read-only Übersicht aller Berichte aus Aufträgen, Rechnungen und Angeboten dieses Kunden. Bericht-Anlage erfolgt direkt am jeweiligen Auftrag oder der Rechnung.</p>';
if (empty($rows)) {
print '<div class="opacitymedium" style="padding:20px;">Noch keine Berichte für diesen Kunden vorhanden.</div>';
} else {
print '<table class="noborder centpercent">';
print '<tr class="liste_titre">';
print '<th>'.$langs->trans("Ref").'</th>';
print '<th>'.$langs->trans("BerichtTitle").'</th>';
print '<th>Quelle</th>';
print '<th>'.$langs->trans("BerichtCreatedAt").'</th>';
print '<th>'.$langs->trans("BerichtStatus").'</th>';
print '<th class="right">'.$langs->trans("Action").'</th>';
print '</tr>';
foreach ($rows as $r) {
$bericht_url = dol_buildpath('/bericht/bericht_card.php', 1).'?berichtid='.$r->rowid;
// Parent-URL berechnen
if ($r->quelle === 'order') {
$parent_url = DOL_URL_ROOT.'/commande/card.php?id='.$r->parent_id;
$quelle_label = '🛒 Auftrag';
} elseif ($r->quelle === 'invoice') {
$parent_url = DOL_URL_ROOT.'/compta/facture/card.php?id='.$r->parent_id;
$quelle_label = '📄 Rechnung';
} else {
$parent_url = DOL_URL_ROOT.'/comm/propal/card.php?id='.$r->parent_id;
$quelle_label = '📋 Angebot';
}
$status_html = ((int) $r->status === 1)
? '<span class="badge badge-status4">Final</span>'
: '<span class="badge badge-status0">Entwurf</span>';
print '<tr class="oddeven">';
print '<td><a href="'.$bericht_url.'">'.dol_escape_htmltag($r->bref).'</a></td>';
print '<td>'.dol_escape_htmltag($r->titel).'</td>';
print '<td>'.$quelle_label.' <a href="'.$parent_url.'">'.dol_escape_htmltag($r->parent_ref).'</a></td>';
print '<td>'.dol_print_date($db->jdate($r->datec), 'dayhour').'</td>';
print '<td>'.$status_html.'</td>';
print '<td class="right">';
print '<a href="'.$bericht_url.'" class="button-small">Öffnen</a> ';
print '<a href="'.$parent_url.'" class="button-small">Zur Quelle</a>';
print '</td>';
print '</tr>';
}
print '</table>';
}
print '</div>';
llxFooter();
$db->close();