false, 'error' => 'Missing parameters']); exit; } // Hole die richtigen Tabellennamen fuer diesen Dokumenttyp $tables = DocumentTypeHelper::getTableNames($docType); if (!$tables) { echo json_encode(['success' => false, 'error' => 'Invalid document type']); exit; } // 1. Hole Section-Info $sql = "SELECT ".$tables['fk_parent']." as doc_id FROM ".MAIN_DB_PREFIX."facture_lines_manager"; $sql .= " WHERE rowid = ".(int)$section_id; $sql .= " AND line_type = 'section'"; $resql = $db->query($sql); if (!$resql || $db->num_rows($resql) == 0) { echo json_encode(['success' => false, 'error' => 'Section not found']); exit; } $section = $db->fetch_object($resql); $document_id = $section->doc_id; // 2. Pruefe Dokumentstatus $object = DocumentTypeHelper::loadDocument($docType, $document_id, $db); if (!$object) { echo json_encode(['success' => false, 'error' => 'Dokument nicht gefunden']); exit; } $isDraft = DocumentTypeHelper::isDraft($object, $docType); if ($force && !$isDraft) { echo json_encode(['success' => false, 'error' => 'Dokument ist nicht im Entwurf']); exit; } // 3. Hole Produkt-IDs DIREKT aus DB $product_ids = []; $sql_products = "SELECT ".$tables['fk_line']." as detail_id FROM ".MAIN_DB_PREFIX."facture_lines_manager"; $sql_products .= " WHERE parent_section = ".(int)$section_id; $sql_products .= " AND line_type = 'product'"; $res_products = $db->query($sql_products); while ($prod = $db->fetch_object($res_products)) { if ($prod->detail_id) { $product_ids[] = (int)$prod->detail_id; } } $product_count = count($product_ids); subtotaltitle_debug_log('Gefundene Produkte in Section: ' . implode(', ', $product_ids)); $db->begin(); // 4. Force-Delete: Produkte aus Dokument loeschen if ($force && $product_count > 0) { subtotaltitle_debug_log('Loesche ' . $product_count . ' Zeilen aus Dokument...'); foreach ($product_ids as $line_id) { $sql_del_line = "DELETE FROM ".MAIN_DB_PREFIX.$tables['lines_table']." WHERE rowid = ".(int)$line_id; $res_del = $db->query($sql_del_line); if ($res_del) { subtotaltitle_debug_log('Detail geloescht: ' . $line_id); } else { subtotaltitle_debug_log('SQL Fehler: ' . $line_id . ' - ' . $db->lasterror()); } } // Aus Manager-Tabelle loeschen $sql_del = "DELETE FROM ".MAIN_DB_PREFIX."facture_lines_manager"; $sql_del .= " WHERE parent_section = ".(int)$section_id; $sql_del .= " AND line_type = 'product'"; $db->query($sql_del); subtotaltitle_debug_log('Force-Delete abgeschlossen: ' . $product_count . ' Produkte'); } else if (!$force) { // Ohne force: Produkte nur freigeben $sql = "UPDATE ".MAIN_DB_PREFIX."facture_lines_manager"; $sql .= " SET parent_section = NULL"; $sql .= " WHERE parent_section = ".(int)$section_id; $sql .= " AND line_type = 'product'"; $db->query($sql); subtotaltitle_debug_log($product_count . ' Produkte freigegeben'); } // ========== SUBTOTAL LOESCHEN ========== $sql_subtotal = "SELECT rowid, ".$tables['fk_line']." as detail_id FROM ".MAIN_DB_PREFIX."facture_lines_manager"; $sql_subtotal .= " WHERE parent_section = ".(int)$section_id; $sql_subtotal .= " AND line_type = 'subtotal'"; $res_subtotal = $db->query($sql_subtotal); if ($obj_sub = $db->fetch_object($res_subtotal)) { // Falls Subtotal in Detail-Tabelle ist, dort auch loeschen if ($obj_sub->detail_id > 0) { $sql_del_fd = "DELETE FROM ".MAIN_DB_PREFIX.$tables['lines_table']." WHERE rowid = ".(int)$obj_sub->detail_id; $db->query($sql_del_fd); subtotaltitle_debug_log('Subtotal aus Detail geloescht: ' . $obj_sub->detail_id); } // Aus Manager-Tabelle loeschen $sql_del_sub = "DELETE FROM ".MAIN_DB_PREFIX."facture_lines_manager WHERE rowid = ".(int)$obj_sub->rowid; $db->query($sql_del_sub); subtotaltitle_debug_log('Subtotal aus Manager geloescht: ' . $obj_sub->rowid); } // ========== VERWAISTE SUBTOTALS AUFRAEUMEN ========== $sql_orphans = "SELECT s.rowid, s.".$tables['fk_line']." as detail_id, s.parent_section FROM ".MAIN_DB_PREFIX."facture_lines_manager s WHERE s.".$tables['fk_parent']." = ".(int)$document_id." AND s.document_type = '".$db->escape($docType)."' AND s.line_type = 'subtotal' AND s.parent_section IS NOT NULL AND NOT EXISTS ( SELECT 1 FROM ".MAIN_DB_PREFIX."facture_lines_manager sec WHERE sec.rowid = s.parent_section AND sec.line_type = 'section' )"; $res_orphans = $db->query($sql_orphans); $orphan_count = 0; while ($orphan = $db->fetch_object($res_orphans)) { if ($orphan->detail_id > 0) { $sql_del_orphan_fd = "DELETE FROM ".MAIN_DB_PREFIX.$tables['lines_table']." WHERE rowid = ".(int)$orphan->detail_id; $db->query($sql_del_orphan_fd); subtotaltitle_debug_log('Verwaistes Subtotal aus Detail geloescht: ' . $orphan->detail_id); } $sql_del_orphan = "DELETE FROM ".MAIN_DB_PREFIX."facture_lines_manager WHERE rowid = ".(int)$orphan->rowid; $db->query($sql_del_orphan); $orphan_count++; } if ($orphan_count > 0) { subtotaltitle_debug_log('Aufgeraeumt: ' . $orphan_count . ' verwaiste Subtotals entfernt'); } // 5. Section selbst loeschen $sql = "DELETE FROM ".MAIN_DB_PREFIX."facture_lines_manager"; $sql .= " WHERE rowid = ".(int)$section_id; $db->query($sql); // Dokumenttotale neu berechnen $object->update_price(1); // 6. Neuordnen $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."facture_lines_manager"; $sql .= " WHERE ".$tables['fk_parent']." = ".(int)$document_id; $sql .= " AND document_type = '".$db->escape($docType)."'"; $sql .= " ORDER BY line_order"; $resql = $db->query($sql); $new_order = 1; while ($obj = $db->fetch_object($resql)) { $sql_upd = "UPDATE ".MAIN_DB_PREFIX."facture_lines_manager"; $sql_upd .= " SET line_order = ".$new_order; $sql_upd .= " WHERE rowid = ".(int)$obj->rowid; $db->query($sql_upd); $new_order++; } // 7. Sync rang $sql = "SELECT ".$tables['fk_line']." as detail_id FROM ".MAIN_DB_PREFIX."facture_lines_manager"; $sql .= " WHERE ".$tables['fk_parent']." = ".(int)$document_id; $sql .= " AND document_type = '".$db->escape($docType)."'"; $sql .= " AND ".$tables['fk_line']." IS NOT NULL"; $sql .= " ORDER BY line_order"; $resql = $db->query($sql); $rang = 1; while ($obj = $db->fetch_object($resql)) { if ($obj->detail_id) { $sql_upd = "UPDATE ".MAIN_DB_PREFIX.$tables['lines_table']; $sql_upd .= " SET rang = ".$rang; $sql_upd .= " WHERE rowid = ".(int)$obj->detail_id; $db->query($sql_upd); $rang++; } } $db->commit(); echo json_encode(['success' => true, 'deleted' => $force ? $product_count : 0]);