subtotaltitle/ajax/assign_last_product.php

124 lines
5.1 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';
$facture_id = GETPOST('facture_id', 'int');
$section_id = GETPOST('section_id', 'int');
$docType = GETPOST('document_type', 'alpha');
subtotaltitle_debug_log('🔍 assign_last_product: facture=' . $facture_id . ', section=' . $section_id . ', docType=' . $docType);
if (!$facture_id || !$section_id || !$docType) {
echo json_encode(['success' => 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();
// Hole das neueste Produkt dieses Dokuments (höchster rang)
$sql = "SELECT rowid, rang FROM ".MAIN_DB_PREFIX.$tables['lines_table'];
$sql .= " WHERE ".$tables['fk_parent']." = ".(int)$facture_id;
$sql .= " ORDER BY rang DESC LIMIT 1";
$resql = $db->query($sql);
if (!$resql || $db->num_rows($resql) == 0) {
$db->rollback();
echo json_encode(['success' => false, 'error' => 'Kein Produkt gefunden']);
exit;
}
$product = $db->fetch_object($resql);
$product_id = $product->rowid;
subtotaltitle_debug_log(' → Neustes Produkt: #' . $product_id . ' (rang=' . $product->rang . ')');
// Prüfe ob schon in Manager-Tabelle (anhand der Detail-FK-Spalte)
$sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."facture_lines_manager";
$sql .= " WHERE ".$tables['fk_line']." = ".(int)$product_id;
$resql = $db->query($sql);
// Hole die line_order der Section (Produkt soll direkt danach kommen)
$sql_section = "SELECT line_order FROM ".MAIN_DB_PREFIX."facture_lines_manager WHERE rowid = ".(int)$section_id;
$resql_section = $db->query($sql_section);
$section_order = 1;
if ($obj_section = $db->fetch_object($resql_section)) {
$section_order = $obj_section->line_order;
}
// Berechne neue line_order: Höchste line_order der Produkte in dieser Section + 1
// Oder Section line_order + 1 wenn keine Produkte vorhanden
$sql_max_in_section = "SELECT MAX(line_order) as max_order FROM ".MAIN_DB_PREFIX."facture_lines_manager";
$sql_max_in_section .= " WHERE parent_section = ".(int)$section_id;
$sql_max_in_section .= " AND line_type = 'product'";
$resql_max_section = $db->query($sql_max_in_section);
$obj_max_section = $db->fetch_object($resql_max_section);
if ($obj_max_section && $obj_max_section->max_order) {
$new_line_order = $obj_max_section->max_order + 1;
} else {
$new_line_order = $section_order + 1;
}
subtotaltitle_debug_log(' → Section line_order='.$section_order.', neue Produkt line_order='.$new_line_order);
// Verschiebe alle nachfolgenden Zeilen um 1 nach hinten
$sql_shift = "UPDATE ".MAIN_DB_PREFIX."facture_lines_manager";
$sql_shift .= " SET line_order = line_order + 1";
$sql_shift .= " WHERE ".$tables['fk_parent']." = ".(int)$facture_id;
$sql_shift .= " AND document_type = '".$db->escape($docType)."'";
$sql_shift .= " AND line_order >= ".$new_line_order;
$db->query($sql_shift);
if ($db->num_rows($resql) == 0) {
// Produkt fehlt - hinzufügen
// Setze alle FK-Felder explizit (NULL für nicht genutzte)
$fk_facture = ($docType === 'invoice') ? (int)$facture_id : 'NULL';
$fk_propal = ($docType === 'propal') ? (int)$facture_id : 'NULL';
$fk_commande = ($docType === 'order') ? (int)$facture_id : 'NULL';
$sql_ins = "INSERT INTO ".MAIN_DB_PREFIX."facture_lines_manager";
$sql_ins .= " (fk_facture, fk_propal, fk_commande, document_type, line_type, ".$tables['fk_line'].", parent_section, line_order, date_creation)";
$sql_ins .= " VALUES (".$fk_facture.", ".$fk_propal.", ".$fk_commande.", '".$db->escape($docType)."', 'product', ".(int)$product_id.", ".(int)$section_id.", ".$new_line_order.", NOW())";
$db->query($sql_ins);
subtotaltitle_debug_log(' → Produkt zu Manager-Tabelle hinzugefügt (line_order=' . $new_line_order . ')');
} else {
// Produkt existiert - UPDATE parent_section UND line_order
subtotaltitle_debug_log('🔵🔵🔵 assign_last_product: Produkt #'.$product_id.' → parent_section='.$section_id.', line_order='.$new_line_order);
$sql_upd = "UPDATE ".MAIN_DB_PREFIX."facture_lines_manager";
$sql_upd .= " SET parent_section = ".(int)$section_id;
$sql_upd .= ", line_order = ".$new_line_order;
$sql_upd .= " WHERE ".$tables['fk_line']." = ".(int)$product_id;
$db->query($sql_upd);
subtotaltitle_debug_log(' → parent_section und line_order updated');
}
// Neu sortieren
require_once DOL_DOCUMENT_ROOT.'/custom/subtotaltitle/class/actions_subtotaltitle.class.php';
$hook = new ActionsSubtotalTitle($db);
$reflection = new ReflectionClass($hook);
$method = $reflection->getMethod('reorderLines');
$method->setAccessible(true);
$method->invoke($hook, $facture_id);
$method = $reflection->getMethod('syncRangFromManager');
$method->setAccessible(true);
$method->invoke($hook, $facture_id);
$db->commit();
subtotaltitle_debug_log('✅ Assignment erfolgreich');
echo json_encode(['success' => true, 'product_id' => $product_id]);