// DEBUG FLAG - true für Debug-Ausgaben, false für Produktiv
var SUBTOTAL_DEBUG = false;
// Fallback für AJAX-URL wenn nicht von PHP gesetzt (z.B. bei direktem JS-Include)
if (typeof subtotaltitleAjaxUrl === 'undefined') {
// Versuche URL aus aktuellem Script-Pfad abzuleiten
var scripts = document.getElementsByTagName('script');
for (var i = 0; i < scripts.length; i++) {
var src = scripts[i].src || '';
if (src.indexOf('subtotaltitle') !== -1 && src.indexOf('/js/') !== -1) {
// Pfad: .../subtotaltitle/js/subtotaltitle.js -> .../subtotaltitle/ajax/
var subtotaltitleAjaxUrl = src.replace(/\/js\/.*$/, '/ajax/');
break;
}
}
// Letzter Fallback
if (typeof subtotaltitleAjaxUrl === 'undefined') {
var subtotaltitleAjaxUrl = '/custom/subtotaltitle/ajax/';
}
}
function debugLog(message) {
if (SUBTOTAL_DEBUG) {
console.log(message);
}
}
/**
* Zeigt einen Dolibarr-styled Bestätigungsdialog
* @param {string} title - Dialogtitel
* @param {string} content - Dialoginhalt (HTML erlaubt)
* @param {function} onConfirm - Callback bei Bestätigung
* @param {string} confirmLabel - Text für Bestätigen-Button (optional)
* @param {string} cancelLabel - Text für Abbrechen-Button (optional)
*/
function showConfirmDialog(title, content, onConfirm, confirmLabel, cancelLabel) {
confirmLabel = confirmLabel || 'Ja';
cancelLabel = cancelLabel || 'Abbrechen';
var dialogId = 'subtotal-confirm-dialog-' + Date.now();
// Entferne vorherige Dialoge
$('.subtotal-confirm-dialog').remove();
var $dialog = $('
';
// Inhalt (colspan=10)
html += '| ';
html += textline.title;
html += ' | ';
// Edit (Spalte 11)
html += '';
html += '';
html += '';
html += ' | ';
// Delete (Spalte 12)
html += '';
html += '';
html += '';
html += ' | ';
// Move (Spalte 13)
html += ' | ';
// Unlink (Spalte 14)
html += ' | ';
html += '
';
// Finde die richtige Position
var inserted = false;
$('#tablelines tbody tr').each(function() {
var $row = $(this);
var rowOrder = parseInt($row.attr('data-line-order'));
if (rowOrder && textline.line_order < rowOrder) {
$row.before(html);
inserted = true;
debugLog(' → Eingefügt vor Zeile mit order ' + rowOrder);
return false;
}
});
if (!inserted) {
var $addRow = $('#tablelines tbody tr.liste_titre_create');
if ($addRow.length > 0) {
$addRow.before(html);
debugLog(' → Vor Hinzufügen-Zeile eingefügt');
} else {
$('#tablelines tbody').append(html);
debugLog(' → Ans Ende angehängt');
}
}
}
/**
* Erstellt eine neue Textzeile
*/
function createTextLine() {
var lang = (typeof subtotalTitleLang !== 'undefined') ? subtotalTitleLang : {};
var docInfo = getDocumentInfo();
if (!docInfo.id) {
showErrorAlert(lang.errorLoadingSections || 'Fehler: Keine Dokument-ID gefunden');
return;
}
showInputDialog(
lang.buttonCreateTextline || 'Textzeile erstellen',
lang.textlineContent || 'Text eingeben:',
'',
function(text) {
debugLog('Erstelle Textzeile für ' + docInfo.type + ' ID ' + docInfo.id);
$.post(subtotaltitleAjaxUrl + 'create_textline.php', {
facture_id: docInfo.id,
document_type: docInfo.type,
text: text
}, function(response) {
debugLog('Textzeile erstellt: ' + JSON.stringify(response));
if (response.success) {
window.location.href = window.location.pathname + window.location.search;
} else {
showErrorAlert((lang.errorSavingTextline || 'Fehler') + ': ' + (response.error || 'Unbekannter Fehler'));
}
}, 'json').fail(function(xhr, status, error) {
debugLog('AJAX Fehler: ' + status + ' ' + error);
showErrorAlert((lang.errorSavingTextline || 'Fehler beim Erstellen') + ': ' + error);
});
},
lang.buttonSave || 'Erstellen',
lang.buttonCancel || 'Abbrechen'
);
}
/**
* Textzeile bearbeiten
*/
function editTextLine(textlineId, currentText) {
var lang = (typeof subtotalTitleLang !== 'undefined') ? subtotalTitleLang : {};
showInputDialog(
lang.buttonEdit || 'Textzeile bearbeiten',
lang.textlineContent || 'Text:',
currentText || '',
function(newText) {
debugLog('✏️ Bearbeite Textzeile ' + textlineId);
$.post(subtotaltitleAjaxUrl + 'edit_textline.php', {
textline_id: textlineId,
text: newText
}, function(response) {
debugLog('Edit response: ' + JSON.stringify(response));
if (response.success) {
window.location.href = window.location.pathname + window.location.search;
} else {
showErrorAlert((lang.errorSavingTextline || 'Fehler') + ': ' + (response.error || 'Unbekannter Fehler'));
}
}, 'json').fail(function(xhr, status, error) {
debugLog('AJAX Fehler: ' + status + ' ' + error);
showErrorAlert((lang.errorSavingTextline || 'Fehler beim Bearbeiten') + ': ' + error);
});
},
lang.buttonSave || 'Speichern',
lang.buttonCancel || 'Abbrechen'
);
}
/**
* Textzeile löschen
*/
function deleteTextLine(textlineId) {
var lang = (typeof subtotalTitleLang !== 'undefined') ? subtotalTitleLang : {};
showConfirmDialog(
'Textzeile löschen',
lang.confirmDeleteTextline || 'Textzeile wirklich löschen?',
function() {
debugLog('Lösche Textzeile ' + textlineId);
$.post(subtotaltitleAjaxUrl + 'delete_textline.php', {
textline_id: textlineId,
document_type: getDocumentType()
}, function(response) {
debugLog('Delete response: ' + JSON.stringify(response));
if (response.success) {
window.location.href = window.location.pathname + window.location.search;
} else {
showErrorAlert((lang.errorDeletingTextline || 'Fehler') + ': ' + (response.error || 'Unbekannter Fehler'));
}
}, 'json').fail(function(xhr, status, error) {
debugLog('AJAX Fehler: ' + status + ' ' + error);
showErrorAlert((lang.errorDeletingTextline || 'Fehler beim Löschen') + ': ' + error);
});
},
'Ja, löschen',
'Abbrechen'
);
}
/**
* Entfernt ein Produkt aus seiner Section
*/
function removeFromSection(productId) {
var lang = (typeof subtotalTitleLang !== 'undefined') ? subtotalTitleLang : {};
showConfirmDialog(
'Aus Positionsgruppe entfernen',
lang.confirmRemoveFromSection || 'Produkt aus Positionsgruppe entfernen?',
function() {
var docType = getDocumentType();
debugLog('Entferne Produkt ' + productId + ' aus Section (docType: ' + docType + ')');
$.post(subtotaltitleAjaxUrl + 'remove_from_section.php', {
product_id: productId,
document_type: docType
}, function(response) {
debugLog('Remove response: ' + JSON.stringify(response));
if (response.success) {
safeReload();
} else {
showErrorAlert((lang.errorReordering || 'Fehler') + ': ' + (response.error || 'Unbekannter Fehler'));
}
}, 'json').fail(function(xhr, status, error) {
debugLog('AJAX Fehler: ' + status + ' ' + error);
showErrorAlert((lang.errorReordering || 'Fehler') + ': ' + error);
});
},
'Ja, entfernen',
'Abbrechen'
);
}
function toggleMassDelete() {
var $checkboxes = $('.mass-delete-checkbox');
if ($checkboxes.length === 0) {
// Checkboxen einblenden
$('tr.drag[data-line-order]').each(function() {
var $row = $(this);
var lineId = $row.attr('id')?.match(/row-(\d+)/)?.[1];
if (lineId) {
$row.find('td:first').prepend(
'