171 lines
7.2 KiB
PHP
Executable file
171 lines
7.2 KiB
PHP
Executable file
<?php
|
|
define('NOTOKENRENEWAL', 1);
|
|
require '../../../main.inc.php';
|
|
require_once __DIR__.'/../lib/subtotaltitle.lib.php';
|
|
require_once __DIR__.'/../class/DocumentTypeHelper.class.php';
|
|
|
|
$line_id = GETPOST('line_id', 'int');
|
|
$section_id = GETPOST('section_id', 'int');
|
|
$document_id = GETPOST('document_id', 'int');
|
|
$docType = GETPOST('document_type', 'alpha');
|
|
|
|
subtotaltitle_debug_log('🔗 add_to_section: line='.$line_id.', section='.$section_id.', doc='.$document_id.', docType='.$docType);
|
|
|
|
if (!$line_id || !$section_id || !$document_id || !$docType) {
|
|
echo json_encode(['success' => false, 'error' => 'Missing parameters']);
|
|
exit;
|
|
}
|
|
|
|
$tables = DocumentTypeHelper::getTableNames($docType);
|
|
if (!$tables) {
|
|
echo json_encode(['success' => false, 'error' => 'Invalid document type']);
|
|
exit;
|
|
}
|
|
|
|
$db->begin();
|
|
|
|
// 1. Hole die Manager-Zeile des Produkts
|
|
$sql = "SELECT rowid, line_order FROM ".MAIN_DB_PREFIX."facture_lines_manager";
|
|
$sql .= " WHERE ".$tables['fk_line']." = ".(int)$line_id;
|
|
$sql .= " AND ".$tables['fk_parent']." = ".(int)$document_id;
|
|
$sql .= " AND document_type = '".$db->escape($docType)."'";
|
|
$sql .= " AND line_type = 'product'";
|
|
$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;
|
|
}
|
|
|
|
$product = $db->fetch_object($resql);
|
|
$manager_id = $product->rowid;
|
|
$current_line_order = $product->line_order;
|
|
|
|
// 2. Hole die line_order der Section
|
|
$sql_section = "SELECT line_order FROM ".MAIN_DB_PREFIX."facture_lines_manager";
|
|
$sql_section .= " WHERE rowid = ".(int)$section_id;
|
|
$sql_section .= " AND line_type = 'section'";
|
|
$sql_section .= " AND document_type = '".$db->escape($docType)."'";
|
|
$resql_section = $db->query($sql_section);
|
|
|
|
if (!$resql_section || $db->num_rows($resql_section) == 0) {
|
|
$db->rollback();
|
|
echo json_encode(['success' => false, 'error' => 'Section not found']);
|
|
exit;
|
|
}
|
|
|
|
$section = $db->fetch_object($resql_section);
|
|
$section_line_order = $section->line_order;
|
|
|
|
// 3. Finde die neue line_order für das Produkt
|
|
// Das Produkt soll IMMER als LETZTES Produkt der Section eingefügt werden
|
|
// (nach allen bestehenden Produkten dieser Section, aber vor der nächsten Section oder dem Subtotal)
|
|
|
|
// Suche das letzte Produkt/Text dieser Section
|
|
$sql_last = "SELECT MAX(line_order) as max_order FROM ".MAIN_DB_PREFIX."facture_lines_manager";
|
|
$sql_last .= " WHERE ".$tables['fk_parent']." = ".(int)$document_id;
|
|
$sql_last .= " AND document_type = '".$db->escape($docType)."'";
|
|
$sql_last .= " AND parent_section = ".(int)$section_id;
|
|
$sql_last .= " AND line_type IN ('product', 'text')";
|
|
$sql_last .= " AND rowid != ".(int)$manager_id; // Nicht das aktuelle Produkt selbst
|
|
$resql_last = $db->query($sql_last);
|
|
$obj_last = $db->fetch_object($resql_last);
|
|
|
|
if ($obj_last && $obj_last->max_order) {
|
|
// Es gibt bereits Produkte in dieser Section → füge NACH dem letzten ein
|
|
$new_line_order = (int)$obj_last->max_order + 1;
|
|
} else {
|
|
// Keine anderen Produkte in der Section → füge direkt nach der Section ein
|
|
$new_line_order = $section_line_order + 1;
|
|
}
|
|
|
|
subtotaltitle_debug_log(' current_line_order='.$current_line_order.', section_line_order='.$section_line_order.', new_line_order='.$new_line_order);
|
|
|
|
// 4. Verschiebe Zeilen
|
|
// WICHTIG: Zuerst das Produkt "entfernen" (temporär auf -1 setzen), dann verschieben, dann einfügen
|
|
$sql_temp = "UPDATE ".MAIN_DB_PREFIX."facture_lines_manager";
|
|
$sql_temp .= " SET line_order = -1";
|
|
$sql_temp .= " WHERE rowid = ".(int)$manager_id;
|
|
$db->query($sql_temp);
|
|
|
|
if ($current_line_order < $new_line_order) {
|
|
// Produkt wird nach hinten verschoben
|
|
// Schließe die Lücke: alle Zeilen zwischen current+1 und new_line_order um -1 verschieben
|
|
$sql_shift = "UPDATE ".MAIN_DB_PREFIX."facture_lines_manager";
|
|
$sql_shift .= " SET line_order = line_order - 1";
|
|
$sql_shift .= " WHERE ".$tables['fk_parent']." = ".(int)$document_id;
|
|
$sql_shift .= " AND document_type = '".$db->escape($docType)."'";
|
|
$sql_shift .= " AND line_order > ".(int)$current_line_order;
|
|
$sql_shift .= " AND line_order <= ".(int)$new_line_order;
|
|
$db->query($sql_shift);
|
|
// Korrigiere new_line_order (weil wir verschoben haben)
|
|
$new_line_order = $new_line_order - 1;
|
|
subtotaltitle_debug_log(' Nach hinten: Lücke geschlossen, new_line_order korrigiert auf '.$new_line_order);
|
|
} elseif ($current_line_order > $new_line_order) {
|
|
// Produkt wird nach vorne verschoben
|
|
// Mache Platz: alle Zeilen ab new_line_order bis current-1 um +1 verschieben
|
|
$sql_shift = "UPDATE ".MAIN_DB_PREFIX."facture_lines_manager";
|
|
$sql_shift .= " SET line_order = line_order + 1";
|
|
$sql_shift .= " WHERE ".$tables['fk_parent']." = ".(int)$document_id;
|
|
$sql_shift .= " AND document_type = '".$db->escape($docType)."'";
|
|
$sql_shift .= " AND line_order >= ".(int)$new_line_order;
|
|
$sql_shift .= " AND line_order < ".(int)$current_line_order;
|
|
$db->query($sql_shift);
|
|
subtotaltitle_debug_log(' Nach vorne: Platz gemacht ab position '.$new_line_order);
|
|
}
|
|
|
|
// 5. Update das Produkt: setze parent_section und neue line_order
|
|
$sql_update = "UPDATE ".MAIN_DB_PREFIX."facture_lines_manager";
|
|
$sql_update .= " SET parent_section = ".(int)$section_id;
|
|
$sql_update .= ", line_order = ".(int)$new_line_order;
|
|
$sql_update .= " WHERE rowid = ".(int)$manager_id;
|
|
$db->query($sql_update);
|
|
|
|
subtotaltitle_debug_log('✅ Produkt #'.$line_id.' zu Section #'.$section_id.' hinzugefügt mit line_order='.$new_line_order);
|
|
|
|
// 6. Normalisiere alle line_order (keine Lücken, keine Duplikate)
|
|
$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, rowid"; // Bei Gleichstand nach rowid sortieren
|
|
$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++;
|
|
}
|
|
subtotaltitle_debug_log(' line_order normalisiert: '.($new_order-1).' Zeilen');
|
|
|
|
// 7. 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]);
|