false, 'error' => 'Missing parameters']); exit; } // Hole die richtigen Tabellennamen für diesen Dokumenttyp $tables = DocumentTypeHelper::getTableNames($docType); if (!$tables) { echo json_encode(['success' => false, 'error' => 'Invalid document type']); exit; } $db->begin(); // 1. Hole parent_section und document_id BEVOR wir entfernen $sql = "SELECT parent_section, ".$tables['fk_parent']." as doc_id FROM ".MAIN_DB_PREFIX."facture_lines_manager"; $sql .= " WHERE ".$tables['fk_line']." = ".(int)$product_id; $sql .= " AND document_type = '".$db->escape($docType)."'"; $resql = $db->query($sql); if (!$resql || $db->num_rows($resql) == 0) { $db->rollback(); echo json_encode(['success' => false, 'error' => 'Product not found in manager table']); exit; } $obj = $db->fetch_object($resql); $old_section_id = $obj->parent_section; $document_id = $obj->doc_id; // 2. Entferne aus Section $sql = "UPDATE ".MAIN_DB_PREFIX."facture_lines_manager"; $sql .= " SET parent_section = NULL"; $sql .= " WHERE ".$tables['fk_line']." = ".(int)$product_id; $sql .= " AND document_type = '".$db->escape($docType)."'"; $db->query($sql); subtotaltitle_debug_log('✅ Produkt #' . $product_id . ' aus Section #'.$old_section_id.' entfernt'); // 3. Wenn Product aus einer Section entfernt wurde, Subtotal neu berechnen if ($old_section_id > 0) { // Prüfe ob Section Subtotal anzeigen soll $sql = "SELECT show_subtotal, title FROM ".MAIN_DB_PREFIX."facture_lines_manager"; $sql .= " WHERE rowid = ".(int)$old_section_id; $sql .= " AND line_type = 'section'"; $resql = $db->query($sql); if ($resql && $obj = $db->fetch_object($resql)) { if ($obj->show_subtotal) { // Berechne neue Summe $sql_sum = "SELECT SUM(d.total_ht) as total"; $sql_sum .= " FROM ".MAIN_DB_PREFIX."facture_lines_manager m"; $sql_sum .= " INNER JOIN ".MAIN_DB_PREFIX.$tables['lines_table']." d ON d.rowid = m.".$tables['fk_line']; $sql_sum .= " WHERE m.parent_section = ".(int)$old_section_id; $sql_sum .= " AND m.document_type = '".$db->escape($docType)."'"; $sql_sum .= " AND m.line_type = 'product'"; $res_sum = $db->query($sql_sum); $obj_sum = $db->fetch_object($res_sum); $new_total = $obj_sum->total ? (float)$obj_sum->total : 0; // Update Subtotal in Detail-Tabelle $sql_upd = "UPDATE ".MAIN_DB_PREFIX.$tables['lines_table']." d"; $sql_upd .= " INNER JOIN ".MAIN_DB_PREFIX."facture_lines_manager m ON m.".$tables['fk_line']." = d.rowid"; $sql_upd .= " SET d.subprice = ".(float)$new_total.", d.total_ht = ".(float)$new_total.", d.total_ttc = ".(float)$new_total; $sql_upd .= " WHERE m.parent_section = ".(int)$old_section_id; $sql_upd .= " AND m.document_type = '".$db->escape($docType)."'"; $sql_upd .= " AND m.line_type = 'subtotal'"; $db->query($sql_upd); subtotaltitle_debug_log(' Subtotal für Section #'.$old_section_id.' aktualisiert: '.$new_total); } } } // 4. Sync rang in Detail-Tabelle subtotaltitle_debug_log(' Starte rang-Synchronisation für docType='.$docType.' doc_id='.$document_id); $sql = "SELECT rowid, line_type, ".$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)) { $detail_id = $obj->detail_id; if ($detail_id) { $sql_upd = "UPDATE ".MAIN_DB_PREFIX.$tables['lines_table']; $sql_upd .= " SET rang = ".$rang; $sql_upd .= " WHERE rowid = ".(int)$detail_id; $db->query($sql_upd); subtotaltitle_debug_log(' Sync rang: '.$obj->line_type.' manager#'.$obj->rowid.' detail#'.$detail_id.' → rang='.$rang); $rang++; } } subtotaltitle_debug_log(' rang-Synchronisation abgeschlossen, '.$rang.' Zeilen synchronisiert'); $db->commit(); echo json_encode(['success' => true]);