— Detail eines Berichts * POST /api/reports.php?id=&action=finalize — Finalisierung anstoßen * * Listing aller Berichte läuft über orders.php (pro Auftrag). */ require_once __DIR__.'/_inc.php'; api_authenticate(); global $db, $user, $conf, $langs; $id = (int) ($_GET['id'] ?? 0); $action = $_GET['action'] ?? ''; /* ----- LISTE aller Berichte für den User ----- */ if (!$id && $action === '') { // Multi-User-Filter: Berichte an Aufträgen, die der User angelegt/validiert/modifiziert hat // PLUS eigene Berichte (fk_user_creat) $extra = ''; if (empty($user->admin)) { $extra = " AND (b.fk_user_creat = ".((int) $user->id) ." OR EXISTS (SELECT 1 FROM ".$db->prefix()."commande c WHERE c.rowid = b.fk_element AND b.element_type='order' AND (c.fk_user_author = ".((int) $user->id)." OR c.fk_user_valid = ".((int) $user->id)." OR c.fk_user_modif = ".((int) $user->id)."))" ." OR EXISTS (SELECT 1 FROM ".$db->prefix()."facture f WHERE f.rowid = b.fk_element AND b.element_type='invoice' AND (f.fk_user_author = ".((int) $user->id)." OR f.fk_user_valid = ".((int) $user->id)." OR f.fk_user_modif = ".((int) $user->id)."))" .")"; } $sql = "SELECT b.rowid, b.ref, b.titel, b.element_type, b.fk_element, b.status, b.datec, b.auftragsnummer," ." (SELECT COUNT(*) FROM ".$db->prefix()."bericht_page WHERE fk_bericht = b.rowid) AS page_count" ." FROM ".$db->prefix()."bericht b" ." WHERE b.entity IN (".getEntity('bericht').") ".$extra ." ORDER BY b.datec DESC LIMIT 200"; $r = $db->query($sql); if (!$r) api_fail('DB-Fehler: '.$db->lasterror(), 500); $items = array(); while ($o = $db->fetch_object($r)) { // Parent-Ref für Anzeige ermitteln $parent_ref = ''; if ($o->element_type === 'order') { $pr = $db->query("SELECT ref FROM ".$db->prefix()."commande WHERE rowid = ".((int) $o->fk_element)); if ($pr && ($p = $db->fetch_object($pr))) $parent_ref = $p->ref; } elseif ($o->element_type === 'invoice') { $pr = $db->query("SELECT ref FROM ".$db->prefix()."facture WHERE rowid = ".((int) $o->fk_element)); if ($pr && ($p = $db->fetch_object($pr))) $parent_ref = $p->ref; } $items[] = array( 'id' => (int) $o->rowid, 'ref' => $o->ref, 'titel' => $o->titel, 'element_type' => $o->element_type, 'fk_element' => (int) $o->fk_element, 'parent_ref' => $parent_ref, 'status' => (int) $o->status, 'datec' => $db->jdate($o->datec), 'auftragsnummer'=> $o->auftragsnummer, 'page_count' => (int) $o->page_count, ); } api_ok(array('reports' => $items, 'count' => count($items))); } /* ----- POST: neuen Bericht anlegen ----- */ if (!$id && $_SERVER['REQUEST_METHOD'] === 'POST' && $action === 'create') { if (!$user->hasRight('bericht', 'write')) api_fail('Permission denied', 403); $in = api_input(); $el_type = (string) ($in['element_type'] ?? 'order'); $el_id = (int) ($in['element_id'] ?? 0); $titel = trim((string) ($in['titel'] ?? '')); $format = (string) ($in['page_format'] ?? 'A4'); $orient = (string) ($in['page_orientation'] ?? 'P'); $template_id = (int) ($in['template_id'] ?? 0); $template_odt = (string) ($in['template_odt'] ?? ''); if (!$el_id) api_fail('element_id erforderlich'); if (!in_array($el_type, array('order', 'invoice', 'propal'), true)) api_fail('element_type ungültig'); // Auftragsnummer ermitteln $parent = bericht_fetch_parent($db, $el_type, $el_id); if (!$parent) api_fail('Parent nicht gefunden', 404); $auftragsnummer = ''; if ($el_type === 'invoice') { $auftragsnummer = $parent->array_options['options_auftragsnummer'] ?? $parent->ref_client ?? $parent->ref; } else { $auftragsnummer = $parent->ref; } if ($template_id > 0) { $new_id = Bericht::createFromTemplate($db, $user, $template_id, $el_type, $el_id, $auftragsnummer); if (!$new_id) api_fail('Vorlage konnte nicht angewendet werden', 500); // Nachbearbeiten falls abweichende Meta $b = new Bericht($db); $b->fetch($new_id); if ($titel) $b->titel = $titel; if (in_array($format, array('A4','A3','A5','Letter'), true)) $b->page_format = $format; if (in_array($orient, array('P','L'), true)) $b->page_orientation = $orient; if ($template_odt) $b->template_odt = $template_odt; $b->update($user); api_ok(array('bericht_id' => $new_id)); } $b = new Bericht($db); $b->element_type = $el_type; $b->fk_element = $el_id; $b->titel = $titel ?: ('Bericht '.$auftragsnummer); $b->auftragsnummer = $auftragsnummer; $b->template_odt = $template_odt ?: getDolGlobalString('BERICHT_DEFAULT_TEMPLATE', ''); $b->page_format = in_array($format, array('A4','A3','A5','Letter'), true) ? $format : 'A4'; $b->page_orientation = in_array($orient, array('P','L'), true) ? $orient : 'P'; if ($b->create($user) <= 0) api_fail('Anlegen fehlgeschlagen', 500); api_ok(array('bericht_id' => $b->id)); } if (!$id) api_fail('id erforderlich'); $bericht = new Bericht($db); if ($bericht->fetch($id) <= 0) api_fail('Bericht nicht gefunden', 404); if ($action === 'finalize') { if (!$user->hasRight('bericht', 'write')) api_fail('Schreibrechte fehlen', 403); // Wir laden generate_pdf.php inline — es erwartet aber POST mit berichtid und ausreichend // gesetzter Token-Kontext. Einfacher: Wir replizieren die Kernlogik hier direkt. require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; require_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmfiles.class.php'; $parent = bericht_fetch_parent($db, $bericht->element_type, $bericht->fk_element); if (!$parent) api_fail('Parent-Objekt nicht gefunden', 404); $pages = BerichtPage::fetchAllForBericht($db, $bericht->id); if (empty($pages)) api_fail('Bericht enthält keine Seiten'); // TCPDF + FPDI laden $tcpdf_loaded = false; foreach (array( DOL_DOCUMENT_ROOT.'/includes/tecnickcom/tcpdf/tcpdf.php', DOL_DOCUMENT_ROOT.'/includes/tcpdf/tcpdf.php', ) as $p) { if (file_exists($p)) { require_once $p; $tcpdf_loaded = true; break; } } if (!$tcpdf_loaded) api_fail('TCPDF nicht gefunden', 500); $fpdi_loaded = false; foreach (array( DOL_DOCUMENT_ROOT.'/includes/setasign/vendor/setasign/fpdi/src/Tcpdf/Fpdi.php', DOL_DOCUMENT_ROOT.'/includes/fpdi/src/Tcpdf/Fpdi.php', ) as $p) { if (file_exists($p)) { require_once $p; $fpdi_loaded = true; break; } } $ori = in_array($bericht->page_orientation, array('P','L'), true) ? $bericht->page_orientation : 'P'; $fmt = in_array($bericht->page_format, array('A4','A3','A5','Letter'), true) ? $bericht->page_format : 'A4'; require_once __DIR__.'/../class/berichtpdf.class.php'; if ($fpdi_loaded && class_exists('BerichtPdfFpdi')) { $pdf = new BerichtPdfFpdi($ori, 'mm', $fmt, true, 'UTF-8', false); } else { $pdf = new BerichtPdf($ori, 'mm', $fmt, true, 'UTF-8', false); } global $mysoc; $pdf->SetCreator('Dolibarr Bericht-Modul (PWA)'); $pdf->SetAuthor($user->getFullName($langs)); $pdf->SetTitle($bericht->titel ?: $bericht->ref); $logo_path = !empty($mysoc->logo) ? $conf->mycompany->dir_output.'/logos/'.$mysoc->logo : ''; $pdf->berichtInit($bericht->titel ?: $bericht->ref, $mysoc->name ?? '', $logo_path); $pdf->SetMargins(10, 30, 10); $pdf->SetAutoPageBreak(true, 16); $pdf->setPrintHeader(true); $pdf->setPrintFooter(true); $pdf->setHeaderMargin(5); $pdf->setFooterMargin(10); foreach ($pages as $page) { bericht_render_page_to_pdf($pdf, $page, $ori, $fmt, $fpdi_loaded); } $dir_key = bericht_element_to_dir_key($bericht->element_type); $target_dir = $conf->{$dir_key}->multidir_output[$parent->entity].'/'.dol_sanitizeFileName($parent->ref); if (!is_dir($target_dir)) dol_mkdir($target_dir); $filename = 'Bericht_'.dol_sanitizeFileName($bericht->auftragsnummer ?: $bericht->ref).'_'.dol_print_date(dol_now(), '%Y%m%d_%H%M%S').'.pdf'; $target_path = $target_dir.'/'.$filename; $pdf->Output($target_path, 'F'); if (!file_exists($target_path)) api_fail('PDF-Output fehlgeschlagen', 500); $ecmfile = new EcmFiles($db); $ecmfile->filepath = $dir_key.'/'.dol_sanitizeFileName($parent->ref); $ecmfile->filename = $filename; $ecmfile->fullpath_orig = $target_path; $ecmfile->src_object_type = $dir_key; $ecmfile->src_object_id = $parent->id; $ecmfile->label = md5_file($target_path); @$ecmfile->create($user); $bericht->status = Bericht::STATUS_FINAL; $bericht->final_pdf_path = str_replace(DOL_DATA_ROOT.'/', '', $target_path); $bericht->update($user); api_ok(array( 'status' => 'final', 'filename' => $filename, 'path' => $bericht->final_pdf_path, )); } // Detail $pages = BerichtPage::fetchAllForBericht($db, $bericht->id); $pages_out = array(); foreach ($pages as $p) { $pages_out[] = array( 'id' => (int) $p->id, 'page_order' => (int) $p->page_order, 'source_type'=> $p->source_type, 'source_path'=> $p->source_path, 'rotation' => (int) $p->rotation, 'note' => $p->note, 'layout' => $p->layout, ); } api_ok(array( 'report' => array( 'id' => (int) $bericht->id, 'ref' => $bericht->ref, 'titel' => $bericht->titel, 'auftragsnummer' => $bericht->auftragsnummer, 'element_type' => $bericht->element_type, 'fk_element' => (int) $bericht->fk_element, 'page_format' => $bericht->page_format, 'page_orientation'=> $bericht->page_orientation, 'status' => (int) $bericht->status, 'datec' => (int) $bericht->datec, ), 'pages' => $pages_out, ));