Version 1.1: Zwischensummen bei Section-Löschung mitlöschen

- doActions-Hook erweitert: Beim Löschen einer Section (confirm_deleteline)
  werden zugehörige Zwischensummen aus facturedet und facture_lines_manager
  automatisch mitgelöscht
- Verwaiste Subtotals (parent_section zeigt auf nicht-existierende Section)
  werden nach jeder Zeilenlöschung aufgeräumt

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Eduard Wisch 2026-03-02 18:39:55 +01:00
parent 59041906b4
commit 85f5fe6507
2 changed files with 52 additions and 1 deletions

View file

@ -1,5 +1,10 @@
# CHANGELOG MODULE SUBTOTALTITLE FOR [DOLIBARR ERP CRM](https://www.dolibarr.org)
## 1.1
- **Zwischensumme bei Section-Löschung mitlöschen**: Wenn eine Produktgruppe über Dolibarrs Standard-Löschbutton (confirm_deleteline) gelöscht wird, werden zugehörige Zwischensummen automatisch aus facturedet und facture_lines_manager mitgelöscht
- **Verwaiste Subtotals aufräumen**: Nach jeder Zeilenlöschung werden verwaiste Zwischensummen (parent_section zeigt auf nicht-existierende Section) automatisch bereinigt
## 1.0
Initial version

View file

@ -323,11 +323,57 @@ class ActionsSubtotalTitle extends CommonHookActions
$tables = DocumentTypeHelper::getTableNames($docType);
if ($tables) {
// Lösche aus Manager-Tabelle
// Prüfe ob die gelöschte Zeile eine Section war
$sqlCheckSection = "SELECT rowid FROM ".MAIN_DB_PREFIX."facture_lines_manager";
$sqlCheckSection .= " WHERE ".$tables['fk_line']." = ".(int)$lineid;
$sqlCheckSection .= " AND line_type = 'section'";
$resqlCheck = $db->query($sqlCheckSection);
$deletedSectionId = 0;
if ($resqlCheck && $db->num_rows($resqlCheck) > 0) {
$objCheck = $db->fetch_object($resqlCheck);
$deletedSectionId = (int)$objCheck->rowid;
}
// Wenn Section gelöscht: Zugehörige Zwischensumme mitlöschen
if ($deletedSectionId > 0) {
$sqlSubtotal = "SELECT rowid, ".$tables['fk_line']." as detail_id FROM ".MAIN_DB_PREFIX."facture_lines_manager";
$sqlSubtotal .= " WHERE parent_section = ".$deletedSectionId;
$sqlSubtotal .= " AND line_type = 'subtotal'";
$resqlSub = $db->query($sqlSubtotal);
while ($objSub = $db->fetch_object($resqlSub)) {
// Aus facturedet/Detail-Tabelle löschen
if ($objSub->detail_id > 0) {
$db->query("DELETE FROM ".MAIN_DB_PREFIX.$tables['lines_table']." WHERE rowid = ".(int)$objSub->detail_id);
}
// Aus Manager-Tabelle löschen
$db->query("DELETE FROM ".MAIN_DB_PREFIX."facture_lines_manager WHERE rowid = ".(int)$objSub->rowid);
}
}
// Lösche die Zeile selbst aus Manager-Tabelle
$sql = "DELETE FROM ".MAIN_DB_PREFIX."facture_lines_manager";
$sql .= " WHERE ".$tables['fk_line']." = ".(int)$lineid;
$db->query($sql);
// Verwaiste Subtotals aufräumen (parent_section zeigt auf nicht-existierende Section)
$sqlOrphans = "SELECT s.rowid, s.".$tables['fk_line']." as detail_id";
$sqlOrphans .= " FROM ".MAIN_DB_PREFIX."facture_lines_manager s";
$sqlOrphans .= " WHERE s.".$tables['fk_parent']." = ".(int)$object->id;
$sqlOrphans .= " AND s.document_type = '".$db->escape($docType)."'";
$sqlOrphans .= " AND s.line_type = 'subtotal'";
$sqlOrphans .= " AND s.parent_section IS NOT NULL";
$sqlOrphans .= " AND NOT EXISTS (";
$sqlOrphans .= " SELECT 1 FROM ".MAIN_DB_PREFIX."facture_lines_manager sec";
$sqlOrphans .= " WHERE sec.rowid = s.parent_section AND sec.line_type = 'section'";
$sqlOrphans .= " )";
$resqlOrph = $db->query($sqlOrphans);
while ($objOrph = $db->fetch_object($resqlOrph)) {
if ($objOrph->detail_id > 0) {
$db->query("DELETE FROM ".MAIN_DB_PREFIX.$tables['lines_table']." WHERE rowid = ".(int)$objOrph->detail_id);
}
$db->query("DELETE FROM ".MAIN_DB_PREFIX."facture_lines_manager WHERE rowid = ".(int)$objOrph->rowid);
}
// Nummeriere line_order neu durch
$sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."facture_lines_manager";
$sql .= " WHERE ".$tables['fk_parent']." = ".(int)$object->id;