false, 'error' => 'Missing parameters']); exit; } $tables = DocumentTypeHelper::getTableNames($docType); if (!$tables) { echo json_encode(['success' => false, 'error' => 'Invalid document type']); exit; } $db->begin(); echo "

Repariere Section-Hierarchie und Sortierung

"; // 1. Alle Sections haben parent_section=NULL (Sections können nicht in Sections sein!) echo "

1. Korrigiere Section parent_section Werte

"; $sql = "UPDATE ".MAIN_DB_PREFIX."facture_lines_manager"; $sql .= " SET parent_section = NULL"; $sql .= " WHERE ".$tables['fk_parent']." = ".(int)$doc_id; $sql .= " AND document_type = '".$db->escape($docType)."'"; $sql .= " AND line_type = 'section'"; $sql .= " AND parent_section IS NOT NULL"; $result = $db->query($sql); echo "✅ Sections korrigiert (parent_section=NULL gesetzt)
"; // 2. Baue komplette neue line_order auf echo "

2. Neu-Sortierung aller Zeilen

"; $new_order = 1; $updates = array(); // Hole die line_order der ersten Section $sql = "SELECT MIN(line_order) as first_section_order FROM ".MAIN_DB_PREFIX."facture_lines_manager"; $sql .= " WHERE ".$tables['fk_parent']." = ".(int)$doc_id; $sql .= " AND document_type = '".$db->escape($docType)."'"; $sql .= " AND line_type = 'section'"; $resql = $db->query($sql); $obj = $db->fetch_object($resql); $first_section_order = $obj ? $obj->first_section_order : 9999; // Freie Produkte VOR den Sections $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."facture_lines_manager"; $sql .= " WHERE ".$tables['fk_parent']." = ".(int)$doc_id; $sql .= " AND document_type = '".$db->escape($docType)."'"; $sql .= " AND line_type = 'product'"; $sql .= " AND (parent_section IS NULL OR parent_section = 0)"; $sql .= " AND line_order < ".(int)$first_section_order; $sql .= " ORDER BY line_order"; $resql = $db->query($sql); while ($obj = $db->fetch_object($resql)) { $updates[$obj->rowid] = $new_order; echo "Freies Produkt (VOR Sections) #".$obj->rowid." → line_order=".$new_order."
"; $new_order++; } // Alle Sections $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."facture_lines_manager"; $sql .= " WHERE ".$tables['fk_parent']." = ".(int)$doc_id; $sql .= " AND document_type = '".$db->escape($docType)."'"; $sql .= " AND line_type = 'section'"; $sql .= " ORDER BY line_order"; $resql = $db->query($sql); $sections = array(); while ($obj = $db->fetch_object($resql)) { $sections[] = $obj->rowid; } foreach ($sections as $sec_id) { // Section selbst $updates[$sec_id] = $new_order; echo "Section #".$sec_id." → line_order=".$new_order."
"; $new_order++; // Produkte dieser Section $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."facture_lines_manager"; $sql .= " WHERE ".$tables['fk_parent']." = ".(int)$doc_id; $sql .= " AND document_type = '".$db->escape($docType)."'"; $sql .= " AND line_type = 'product'"; $sql .= " AND parent_section = ".(int)$sec_id; $sql .= " ORDER BY line_order"; $resql = $db->query($sql); while ($obj = $db->fetch_object($resql)) { $updates[$obj->rowid] = $new_order; echo "  → Produkt #".$obj->rowid." → line_order=".$new_order."
"; $new_order++; } // Textzeilen dieser Section $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."facture_lines_manager"; $sql .= " WHERE ".$tables['fk_parent']." = ".(int)$doc_id; $sql .= " AND document_type = '".$db->escape($docType)."'"; $sql .= " AND line_type = 'text'"; $sql .= " AND parent_section = ".(int)$sec_id; $sql .= " ORDER BY line_order"; $resql = $db->query($sql); while ($obj = $db->fetch_object($resql)) { $updates[$obj->rowid] = $new_order; echo "  → Text #".$obj->rowid." → line_order=".$new_order."
"; $new_order++; } // Subtotal dieser Section $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."facture_lines_manager"; $sql .= " WHERE ".$tables['fk_parent']." = ".(int)$doc_id; $sql .= " AND document_type = '".$db->escape($docType)."'"; $sql .= " AND line_type = 'subtotal'"; $sql .= " AND parent_section = ".(int)$sec_id; $resql = $db->query($sql); while ($obj = $db->fetch_object($resql)) { $updates[$obj->rowid] = $new_order; echo "  → Subtotal #".$obj->rowid." → line_order=".$new_order."
"; $new_order++; } } // Freie Produkte NACH den Sections (alle, die noch nicht processed wurden) $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."facture_lines_manager"; $sql .= " WHERE ".$tables['fk_parent']." = ".(int)$doc_id; $sql .= " AND document_type = '".$db->escape($docType)."'"; $sql .= " AND line_type = 'product'"; $sql .= " AND (parent_section IS NULL OR parent_section = 0)"; $sql .= " ORDER BY line_order"; $resql = $db->query($sql); while ($obj = $db->fetch_object($resql)) { if (!isset($updates[$obj->rowid])) { $updates[$obj->rowid] = $new_order; echo "Freies Produkt (NACH Sections) #".$obj->rowid." → line_order=".$new_order."
"; $new_order++; } } // 3. Updates ausführen echo "

3. Schreibe neue line_order Werte

"; foreach ($updates as $rowid => $order) { $sql = "UPDATE ".MAIN_DB_PREFIX."facture_lines_manager"; $sql .= " SET line_order = ".(int)$order; $sql .= " WHERE rowid = ".(int)$rowid; $db->query($sql); } echo "✅ ".count($updates)." Zeilen neu sortiert
"; // 4. Sync rang in Detail-Tabelle echo "

4. Synchronisiere rang in Detail-Tabelle

"; $sql = "SELECT rowid, line_type, ".$tables['fk_line']." as detail_id FROM ".MAIN_DB_PREFIX."facture_lines_manager"; $sql .= " WHERE ".$tables['fk_parent']." = ".(int)$doc_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); echo $obj->line_type." manager#".$obj->rowid." detail#".$detail_id." → rang=".$rang."
"; $rang++; } } echo "✅ ".$rang." Zeilen synchronisiert
"; $db->commit(); echo "

✅ Reparatur abgeschlossen!

"; echo "

Zurück zum Kundenauftrag

";