diff --git a/Layout/default/WarehouseOffer/PDF_MAIN.php b/Layout/default/WarehouseOffer/PDF_MAIN.php index 7bb8a81f4..aa6e85d49 100644 --- a/Layout/default/WarehouseOffer/PDF_MAIN.php +++ b/Layout/default/WarehouseOffer/PDF_MAIN.php @@ -33,6 +33,7 @@ $texts = [ 'usageLabel' => 'Zweck:', 'customerReferenceLabel' => 'Kundenreferenz:', 'validUntilLabel' => 'Gültig bis:', + 'vatLabel' => 'USt-IdNr.:', 'pageLabel' => 'Seite', // For page numbering in content if needed 'table' => [ 'pos' => 'Pos', @@ -241,6 +242,10 @@ $formattedValidUntil = $validUntilDate ? date("d.m.Y", $validUntilDate) : date(" purpose ?? 'Keine Angabe' ?> + customerVAT)) : ?> + + customerVAT) ?> + diff --git a/application/WarehouseOffer/WarehouseOfferController.php b/application/WarehouseOffer/WarehouseOfferController.php index 271b88460..2c1562682 100644 --- a/application/WarehouseOffer/WarehouseOfferController.php +++ b/application/WarehouseOffer/WarehouseOfferController.php @@ -11,7 +11,7 @@ class WarehouseOfferController extends TTCrud { ['key' => 'customerNumber', 'text' => 'Kundennummer', 'required' => true, 'modal' => false], ['key' => 'customerName', 'text' => 'Kundenname', 'required' => true, 'modal' => false], ['key' => 'customerCity', 'text' => 'Stadt', 'required' => true, 'modal' => false], - ['key' => 'customerVAT', 'text' => 'UID', 'required' => true, 'modal' => false], + ['key' => 'customerVAT', 'text' => 'UID', 'required' => false, 'modal' => false], ['key' => 'editor', 'text' => 'Sachbearbeiter', 'required' => true, 'modal' => ['type' => 'select'], 'table' => ['filter' => 'select']], ['key' => 'totalAmount', 'text' => 'Gesamtbetrag', 'required' => true, 'modal' => false], ['key' => 'status', 'text' => 'Status', 'required' => true], diff --git a/public/plugins/vue/tt-components/tt-position-manager.js b/public/plugins/vue/tt-components/tt-position-manager.js index 59abd15a4..42ffff1c5 100644 --- a/public/plugins/vue/tt-components/tt-position-manager.js +++ b/public/plugins/vue/tt-components/tt-position-manager.js @@ -56,6 +56,8 @@ Vue.component('tt-positions-manager', formData: {}, groupName: '', selectedIndex: null, + editingGroupName: null, + tempGroupName: '', } }, template: ` @@ -155,8 +157,21 @@ Vue.component('tt-positions-manager', @@ -237,6 +252,71 @@ Vue.component('tt-positions-manager', this.positions.push({_group: this.groupName}); this.groupName = ''; }, + startGroupEdit(groupName) { + this.editingGroupName = groupName; + this.tempGroupName = groupName; + }, + saveGroupName(oldGroupName) { + if (this.tempGroupName.trim() === '') { + window.notify('error', 'Gruppenname darf nicht leer sein'); + return; + } + + if (this.tempGroupName !== oldGroupName) { + // Update all positions with the old group name to the new group name + this.positions.forEach(position => { + if (position._group === oldGroupName) { + this.$set(position, '_group', this.tempGroupName); + } + }); + this.$emit('input', this.positions); + } + + this.editingGroupName = null; + this.tempGroupName = ''; + }, + cancelGroupEdit() { + this.editingGroupName = null; + this.tempGroupName = ''; + }, + deleteGroup(groupName) { + if (confirm(`Möchten Sie die Gruppe "${groupName}" wirklich löschen? Alle Einträge werden in "Keine Gruppe" verschoben.`)) { + // Move all items from this group to "Keine Gruppe" and remove empty group entries + this.positions = this.positions.filter(position => { + if (position._group === groupName) { + // If it's just a group header (only has _group property), remove it + if (Object.keys(position).length === 1) { + return false; + } + // Otherwise, move to "Keine Gruppe" + this.$set(position, '_group', 'Keine Gruppe'); + } + return true; + }); + this.$emit('input', this.positions); + } + }, + getActualIndex(position, groupName, groupIndex) { + // Find the actual index in the positions array + if (!this.groupMode) return groupIndex; + + let actualIndex = 0; + let currentGroupIndex = 0; + + for (let i = 0; i < this.positions.length; i++) { + const pos = this.positions[i]; + const posGroup = pos._group ?? 'Keine Gruppe'; + + if (posGroup === groupName && Object.keys(pos).length > 1) { + if (currentGroupIndex === groupIndex) { + return i; + } + currentGroupIndex++; + } + } + + return groupIndex; // Fallback + }, async editEntry(index) { this.selectedIndex = index; for (const [key, field] of Object.entries(this.config.fields)) { @@ -316,4 +396,4 @@ Vue.component('tt-positions-manager', deep: true } } - }); + })