false, 'error' => 'Missing parameters')); exit; } // Wenn kein docType übergeben, versuche ihn aus der Section zu ermitteln if (!$docType) { $sql = "SELECT document_type FROM ".MAIN_DB_PREFIX."facture_lines_manager WHERE rowid = ".(int)$section_id; $res = $db->query($sql); if ($res && $obj = $db->fetch_object($res)) { $docType = $obj->document_type; } } if (!$docType) { $docType = 'invoice'; // Fallback } $tables = DocumentTypeHelper::getTableNames($docType); if (!$tables) { echo json_encode(array('success' => false, 'error' => 'Invalid document type')); exit; } // 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'"; $sql .= " AND document_type = '".$db->escape($docType)."'"; $resql = $db->query($sql); if (!$resql || $db->num_rows($resql) == 0) { echo json_encode(array('success' => false, 'error' => 'Section not found')); exit; } $section = $db->fetch_object($resql); $doc_id = $section->doc_id; $db->begin(); // 1. Hole alle Sections (sortiert) $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; } // 2. Finde Index und tausche $current_index = array_search($section_id, $sections); if ($current_index === false) { $db->rollback(); echo json_encode(array('success' => false, 'error' => 'Section not in list')); exit; } if ($direction == 'up') { if ($current_index == 0) { $db->rollback(); echo json_encode(array('success' => false, 'error' => 'Already at top')); exit; } $swap_index = $current_index - 1; } else { if ($current_index == count($sections) - 1) { $db->rollback(); echo json_encode(array('success' => false, 'error' => 'Already at bottom')); exit; } $swap_index = $current_index + 1; } // Tausche $temp = $sections[$current_index]; $sections[$current_index] = $sections[$swap_index]; $sections[$swap_index] = $temp; // 3. Baue komplette neue Reihenfolge auf $new_order = 1; $updates = array(); // Freie Produkte zuerst $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"; $sql .= " ORDER BY line_order"; $resql = $db->query($sql); while ($obj = $db->fetch_object($resql)) { $updates[$obj->rowid] = $new_order; $new_order++; } // Freie Textzeilen $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 IS NULL"; $sql .= " ORDER BY line_order"; $resql = $db->query($sql); while ($obj = $db->fetch_object($resql)) { $updates[$obj->rowid] = $new_order; $new_order++; } // Sections in neuer Reihenfolge foreach ($sections as $sec_id) { // Section-Header $updates[$sec_id] = $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; $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; $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; $new_order++; } } // Freie Produkte am Ende (nach allen 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"; $sql .= " AND rowid NOT IN (SELECT rowid FROM ".MAIN_DB_PREFIX."facture_lines_manager WHERE ".$tables['fk_parent']." = ".(int)$doc_id." AND document_type = '".$db->escape($docType)."' AND line_type = 'product' AND parent_section IS NULL AND line_order < (SELECT MIN(line_order) FROM ".MAIN_DB_PREFIX."facture_lines_manager WHERE ".$tables['fk_parent']." = ".(int)$doc_id." AND document_type = '".$db->escape($docType)."' AND line_type = 'section'))"; $sql .= " ORDER BY line_order"; // Diese Abfrage ist zu komplex - die freien Produkte wurden bereits oben behandelt // 4. Führe alle Updates aus 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); } // 5. Sync rang in Detail-Tabelle $sql = "SELECT ".$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); $rang++; } } $db->commit(); echo json_encode(array('success' => true));