* Liefert Detail eines einzelnen Auftrags. * GET /api/orders.php?id=&action=photos * Liefert die Anhang-Bilder/PDFs eines Auftrags. * POST /api/orders.php?id=&action=upload_photo * multipart: file= — fügt ein Foto zum Bericht des Auftrags hinzu * (legt automatisch einen Bericht an wenn keiner existiert) */ require_once __DIR__.'/_inc.php'; api_authenticate(); global $db, $user, $conf; require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php'; require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; $id = (int) ($_GET['id'] ?? 0); $action = $_GET['action'] ?? ''; /* ----- LISTE ----- */ if (!$id) { // Filter: nur Aufträge des aktuellen Users (oder Admin sieht alle) $where = "c.entity IN (".getEntity('commande').")"; if (empty($user->admin)) { $where .= " AND (c.fk_user_author = ".((int) $user->id) ." OR c.fk_user_valid = ".((int) $user->id) ." OR c.fk_user_modif = ".((int) $user->id).")"; } // Optional: nur offene if (!empty($_GET['open'])) { $where .= " AND c.fk_statut IN (1, 2)"; // validiert + in Bearbeitung } // Suchterm if (!empty($_GET['q'])) { $q = $db->escape($_GET['q']); $where .= " AND (c.ref LIKE '%$q%' OR s.nom LIKE '%$q%')"; } $sql = "SELECT c.rowid, c.ref, c.date_commande, c.fk_statut, c.total_ttc," ." s.rowid AS soc_id, s.nom AS soc_name, s.zip, s.town, s.address," ." (SELECT COUNT(*) FROM ".$db->prefix()."bericht b WHERE b.element_type='order' AND b.fk_element=c.rowid) AS bericht_count" ." FROM ".$db->prefix()."commande c" ." LEFT JOIN ".$db->prefix()."societe s ON s.rowid = c.fk_soc" ." WHERE ".$where ." ORDER BY c.date_commande DESC, c.rowid DESC" ." LIMIT 200"; $r = $db->query($sql); if (!$r) api_fail('DB-Fehler: '.$db->lasterror(), 500); $orders = array(); while ($o = $db->fetch_object($r)) { $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, 'customer' => array( 'id' => (int) $o->soc_id, 'name' => $o->soc_name, 'zip' => $o->zip, 'town' => $o->town, 'address' => $o->address, ), 'bericht_count' => (int) $o->bericht_count, ); } api_ok(array('orders' => $orders, 'count' => count($orders))); } /* ----- DETAIL eines Auftrags ----- */ $cmd = new Commande($db); if ($cmd->fetch($id) <= 0) api_fail('Auftrag nicht gefunden', 404); $cmd->fetch_thirdparty(); if (method_exists($cmd, 'fetch_optionals')) $cmd->fetch_optionals(); if ($action === 'photos') { // Anhänge des Auftrags $upload_dir = $conf->commande->multidir_output[$cmd->entity].'/'.dol_sanitizeFileName($cmd->ref); $files = is_dir($upload_dir) ? dol_dir_list($upload_dir, 'files', 1, '', '(\.meta|_preview.*\.png|thumbs)$') : array(); $out = array(); foreach ($files as $f) { $out[] = array( 'filename' => $f['name'], 'size' => (int) $f['size'], 'mime' => dol_mimetype($f['name']), 'date' => (int) $f['date'], 'relpath' => str_replace(DOL_DATA_ROOT.'/', '', $f['fullname']), ); } api_ok(array('photos' => $out, 'count' => count($out))); } if ($action === 'upload_photo' && $_SERVER['REQUEST_METHOD'] === 'POST') { if (!$user->hasRight('bericht', 'write')) api_fail('Schreibrechte fehlen', 403); if (empty($_FILES['file']['tmp_name'])) api_fail('file fehlt'); // Bericht zum Auftrag suchen: neuester ENTWURF wird erweitert. // Wenn nur finalisierte Berichte existieren, wird ein neuer Entwurf angelegt. // Mit ?bericht_id=X kann die PWA einen spezifischen Bericht addressieren. $wanted_id = (int) ($_GET['bericht_id'] ?? 0); $bericht = null; if ($wanted_id > 0) { $b = new Bericht($db); if ($b->fetch($wanted_id) > 0 && $b->fk_element == $cmd->id && $b->element_type === 'order') { $bericht = $b; } } if (!$bericht) { $list = Bericht::fetchAllForElement($db, 'order', $cmd->id); foreach ($list as $b) { if ((int) $b->status === Bericht::STATUS_DRAFT) { $bericht = $b; break; } } } if (!$bericht) { $bericht = new Bericht($db); $bericht->element_type = 'order'; $bericht->fk_element = $cmd->id; $bericht->titel = 'Bericht '.$cmd->ref; $bericht->auftragsnummer = $cmd->ref; $bericht->template_odt = getDolGlobalString('BERICHT_DEFAULT_TEMPLATE', ''); if ($bericht->create($user) <= 0) api_fail('Bericht-Anlage fehlgeschlagen', 500); } // Datei speichern $orig = dol_sanitizeFileName($_FILES['file']['name']); $ext = strtolower(pathinfo($orig, PATHINFO_EXTENSION)); if (!in_array($ext, array('jpg', 'jpeg', 'png'))) api_fail('Dateityp nicht unterstützt'); $workdir = DOL_DATA_ROOT.'/bericht/work/'.$bericht->id; if (!is_dir($workdir)) dol_mkdir($workdir); $target = $workdir.'/api_'.dol_print_date(dol_now(), '%Y%m%d_%H%M%S').'_'.uniqid().'.'.$ext; if (!move_uploaded_file($_FILES['file']['tmp_name'], $target)) api_fail('Upload fehlgeschlagen', 500); $relpath = str_replace(DOL_DATA_ROOT.'/', '', $target); // Als Page anlegen $resm = $db->query("SELECT COALESCE(MAX(page_order),0) AS m FROM ".$db->prefix()."bericht_page WHERE fk_bericht = ".((int) $bericht->id)); $next = ($resm && ($o = $db->fetch_object($resm))) ? ((int) $o->m) + 1 : 1; $page = new BerichtPage($db); $page->fk_bericht = $bericht->id; $page->page_order = $next; $page->source_type = 'upload'; $page->source_path = $relpath; if ($page->create() <= 0) api_fail('Page-Insert fehlgeschlagen', 500); api_ok(array( 'bericht_id' => (int) $bericht->id, 'page_id' => (int) $page->id, 'filename' => basename($target), )); } // Default: Auftrags-Detail $berichte = Bericht::fetchAllForElement($db, 'order', $cmd->id); $berichte_out = array(); foreach ($berichte as $b) { $berichte_out[] = array( 'id' => (int) $b->id, 'ref' => $b->ref, 'titel' => $b->titel, 'status' => (int) $b->status, 'datec' => (int) $b->datec, ); } api_ok(array( 'order' => array( 'id' => (int) $cmd->id, 'ref' => $cmd->ref, 'date' => $cmd->date_commande, 'status'=> (int) $cmd->statut, 'total' => (float) $cmd->total_ttc, 'note_private' => $cmd->note_private, 'auftragsbeschreibung' => $cmd->array_options['options_auftragsbeschreibung'] ?? '', ), 'customer' => array( 'id' => (int) ($cmd->thirdparty->id ?? 0), 'name' => $cmd->thirdparty->name ?? '', 'address' => $cmd->thirdparty->address ?? '', 'zip' => $cmd->thirdparty->zip ?? '', 'town' => $cmd->thirdparty->town ?? '', 'phone' => $cmd->thirdparty->phone ?? '', 'email' => $cmd->thirdparty->email ?? '', ), 'berichte' => $berichte_out, ));