All checks were successful
Deploy bericht / deploy (push) Successful in 2s
Unterschrift (api/pages.php?action=signature): - Metadaten einbrennen: Überschrift, Bericht-Ref, Parent-Ref, Kunde, Datum/Zeit (Server), Unterzeichner-Name, Bestätigungstext, GPS - SHA256 Hash-Verkettung über alle vorherigen Seiten + Bericht-Ref → nachträgliches Austauschen von Seiten fällt auf - Composite-Canvas: Header mit Metadaten, Unterschrift mittig, Footer mit Hash + Server + Zeitstempel - Metadaten-JSON neben der PNG (für spätere Verifikation) - signer_name ist Pflicht, gps_lat/gps_lon optional - Page-Note zeigt Unterzeichner + Zeit statt nur 'Unterschrift Kunde' Kundenkarten-API (api/customers.php): - GET ohne id = Liste mit Suche (q-Param), zeigt Stammdaten + Bericht-Count - GET mit id = Detail: Stammdaten, letzten 50 Aufträge, 50 Rechnungen, 100 Berichte über UNION aus commande/facture JOIN - Nur echte Kunden (client IN (1,2,3)), keine reinen Lieferanten Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> [deploy]
147 lines
5.4 KiB
PHP
147 lines
5.4 KiB
PHP
<?php
|
|
/* GET /api/customers.php — Liste der Kunden mit letzten Berichten
|
|
* GET /api/customers.php?id=<soc_id> — Kunden-Detail: Stammdaten + Aufträge + Berichte
|
|
* GET /api/customers.php?q=<search> — Filter per Name
|
|
*/
|
|
require_once __DIR__.'/_inc.php';
|
|
|
|
api_authenticate();
|
|
global $db, $user, $conf, $langs;
|
|
|
|
require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
|
|
|
|
$id = (int) ($_GET['id'] ?? 0);
|
|
$q = (string) ($_GET['q'] ?? '');
|
|
|
|
/* ----- LISTE ----- */
|
|
if (!$id) {
|
|
$where = "s.entity IN (".getEntity('societe').")";
|
|
if ($q !== '') {
|
|
$q_esc = $db->escape($q);
|
|
$where .= " AND (s.nom LIKE '%$q_esc%' OR s.code_client LIKE '%$q_esc%' OR s.town LIKE '%$q_esc%')";
|
|
}
|
|
// Standardmäßig nur Kunden (client=1 oder 3) — keine reinen Lieferanten
|
|
$where .= " AND (s.client = 1 OR s.client = 2 OR s.client = 3)";
|
|
|
|
$sql = "SELECT s.rowid, s.nom, s.code_client, s.zip, s.town, s.phone, s.email,"
|
|
." (SELECT COUNT(*) FROM ".$db->prefix()."bericht b"
|
|
." INNER JOIN ".$db->prefix()."commande c ON c.rowid = b.fk_element AND b.element_type='order' AND c.fk_soc = s.rowid) AS b_order,"
|
|
." (SELECT COUNT(*) FROM ".$db->prefix()."bericht b"
|
|
." INNER JOIN ".$db->prefix()."facture f ON f.rowid = b.fk_element AND b.element_type='invoice' AND f.fk_soc = s.rowid) AS b_invoice,"
|
|
." (SELECT MAX(c2.date_commande) FROM ".$db->prefix()."commande c2 WHERE c2.fk_soc = s.rowid) AS last_order_date"
|
|
." FROM ".$db->prefix()."societe s"
|
|
." WHERE ".$where
|
|
." ORDER BY last_order_date DESC, s.nom ASC"
|
|
." LIMIT 200";
|
|
$r = $db->query($sql);
|
|
if (!$r) api_fail('DB-Fehler: '.$db->lasterror(), 500);
|
|
$out = array();
|
|
while ($o = $db->fetch_object($r)) {
|
|
$bericht_count = (int) $o->b_order + (int) $o->b_invoice;
|
|
$out[] = array(
|
|
'id' => (int) $o->rowid,
|
|
'name' => $o->nom,
|
|
'code' => $o->code_client,
|
|
'zip' => $o->zip,
|
|
'town' => $o->town,
|
|
'phone' => $o->phone,
|
|
'email' => $o->email,
|
|
'bericht_count' => $bericht_count,
|
|
'last_order_date' => $o->last_order_date ? $db->jdate($o->last_order_date) : null,
|
|
);
|
|
}
|
|
api_ok(array('customers' => $out, 'count' => count($out)));
|
|
}
|
|
|
|
/* ----- DETAIL eines Kunden ----- */
|
|
$soc = new Societe($db);
|
|
if ($soc->fetch($id) <= 0) api_fail('Kunde nicht gefunden', 404);
|
|
|
|
// Aufträge des Kunden
|
|
$orders = array();
|
|
$ro = $db->query("SELECT c.rowid, c.ref, c.date_commande, c.fk_statut, c.total_ttc"
|
|
." FROM ".$db->prefix()."commande c"
|
|
." WHERE c.fk_soc = ".((int) $id)
|
|
." AND c.entity IN (".getEntity('commande').")"
|
|
." ORDER BY c.date_commande DESC, c.rowid DESC LIMIT 50");
|
|
if ($ro) {
|
|
while ($o = $db->fetch_object($ro)) {
|
|
// Bericht-Count pro Auftrag
|
|
$rb = $db->query("SELECT COUNT(*) AS n FROM ".$db->prefix()."bericht WHERE element_type='order' AND fk_element = ".((int) $o->rowid));
|
|
$bc = ($rb && ($rbo = $db->fetch_object($rb))) ? (int) $rbo->n : 0;
|
|
$orders[] = array(
|
|
'id' => (int) $o->rowid,
|
|
'ref' => $o->ref,
|
|
'date' => $db->jdate($o->date_commande),
|
|
'status' => (int) $o->fk_statut,
|
|
'total' => (float) $o->total_ttc,
|
|
'bericht_count' => $bc,
|
|
);
|
|
}
|
|
}
|
|
|
|
// Rechnungen des Kunden
|
|
$invoices = array();
|
|
$ri = $db->query("SELECT f.rowid, f.ref, f.datef, f.fk_statut, f.total_ttc"
|
|
." FROM ".$db->prefix()."facture f"
|
|
." WHERE f.fk_soc = ".((int) $id)
|
|
." AND f.entity IN (".getEntity('facture').")"
|
|
." ORDER BY f.datef DESC, f.rowid DESC LIMIT 50");
|
|
if ($ri) {
|
|
while ($f = $db->fetch_object($ri)) {
|
|
$invoices[] = array(
|
|
'id' => (int) $f->rowid,
|
|
'ref' => $f->ref,
|
|
'date' => $db->jdate($f->datef),
|
|
'status' => (int) $f->fk_statut,
|
|
'total' => (float) $f->total_ttc,
|
|
);
|
|
}
|
|
}
|
|
|
|
// Alle Berichte des Kunden (über Joins)
|
|
$reports = array();
|
|
$rr = $db->query(
|
|
"SELECT b.rowid, b.ref, b.titel, b.status, b.datec, b.element_type, c.ref AS parent_ref"
|
|
." 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) $id)
|
|
." UNION "
|
|
."SELECT b.rowid, b.ref, b.titel, b.status, b.datec, b.element_type, f.ref AS parent_ref"
|
|
." 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) $id)
|
|
." ORDER BY datec DESC LIMIT 100"
|
|
);
|
|
if ($rr) {
|
|
while ($b = $db->fetch_object($rr)) {
|
|
$reports[] = array(
|
|
'id' => (int) $b->rowid,
|
|
'ref' => $b->ref,
|
|
'titel' => $b->titel,
|
|
'status' => (int) $b->status,
|
|
'datec' => $db->jdate($b->datec),
|
|
'element_type' => $b->element_type,
|
|
'parent_ref' => $b->parent_ref,
|
|
);
|
|
}
|
|
}
|
|
|
|
api_ok(array(
|
|
'customer' => array(
|
|
'id' => (int) $soc->id,
|
|
'name' => $soc->name,
|
|
'code' => $soc->code_client,
|
|
'address' => $soc->address,
|
|
'zip' => $soc->zip,
|
|
'town' => $soc->town,
|
|
'country' => $soc->country,
|
|
'phone' => $soc->phone,
|
|
'email' => $soc->email,
|
|
'siret' => $soc->idprof1 ?? '',
|
|
'vat' => $soc->tva_intra ?? '',
|
|
),
|
|
'orders' => $orders,
|
|
'invoices' => $invoices,
|
|
'reports' => $reports,
|
|
));
|