Merge branch 'WarehouseOffer/improve2' into 'master'
updated warehouseoffer See merge request fronk/thetool!1468
This commit is contained in:
@@ -33,6 +33,7 @@ $texts = [
|
|||||||
'usageLabel' => 'Zweck:',
|
'usageLabel' => 'Zweck:',
|
||||||
'customerReferenceLabel' => 'Kundenreferenz:',
|
'customerReferenceLabel' => 'Kundenreferenz:',
|
||||||
'validUntilLabel' => 'Gültig bis:',
|
'validUntilLabel' => 'Gültig bis:',
|
||||||
|
'vatLabel' => 'USt-IdNr.:',
|
||||||
'pageLabel' => 'Seite', // For page numbering in content if needed
|
'pageLabel' => 'Seite', // For page numbering in content if needed
|
||||||
'table' => [
|
'table' => [
|
||||||
'pos' => 'Pos',
|
'pos' => 'Pos',
|
||||||
@@ -241,6 +242,10 @@ $formattedValidUntil = $validUntilDate ? date("d.m.Y", $validUntilDate) : date("
|
|||||||
<tr>
|
<tr>
|
||||||
<td class="label" style="text-align: left"><?= $text['usageLabel'] ?></td>
|
<td class="label" style="text-align: left"><?= $text['usageLabel'] ?></td>
|
||||||
<td><?= $offer->purpose ?? 'Keine Angabe' ?></td>
|
<td><?= $offer->purpose ?? 'Keine Angabe' ?></td>
|
||||||
|
<?php if (!empty($offer->customerVAT)) : ?>
|
||||||
|
<td class="label"><?= $text['vatLabel'] ?></td>
|
||||||
|
<td><?= htmlspecialchars($offer->customerVAT) ?></td>
|
||||||
|
<?php endif; ?>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ class WarehouseOfferController extends TTCrud {
|
|||||||
['key' => 'customerNumber', 'text' => 'Kundennummer', 'required' => true, 'modal' => false],
|
['key' => 'customerNumber', 'text' => 'Kundennummer', 'required' => true, 'modal' => false],
|
||||||
['key' => 'customerName', 'text' => 'Kundenname', 'required' => true, 'modal' => false],
|
['key' => 'customerName', 'text' => 'Kundenname', 'required' => true, 'modal' => false],
|
||||||
['key' => 'customerCity', 'text' => 'Stadt', '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' => 'editor', 'text' => 'Sachbearbeiter', 'required' => true, 'modal' => ['type' => 'select'], 'table' => ['filter' => 'select']],
|
||||||
['key' => 'totalAmount', 'text' => 'Gesamtbetrag', 'required' => true, 'modal' => false],
|
['key' => 'totalAmount', 'text' => 'Gesamtbetrag', 'required' => true, 'modal' => false],
|
||||||
['key' => 'status', 'text' => 'Status', 'required' => true],
|
['key' => 'status', 'text' => 'Status', 'required' => true],
|
||||||
|
|||||||
@@ -56,6 +56,8 @@ Vue.component('tt-positions-manager',
|
|||||||
formData: {},
|
formData: {},
|
||||||
groupName: '',
|
groupName: '',
|
||||||
selectedIndex: null,
|
selectedIndex: null,
|
||||||
|
editingGroupName: null,
|
||||||
|
tempGroupName: '',
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
template: `
|
template: `
|
||||||
@@ -155,8 +157,21 @@ Vue.component('tt-positions-manager',
|
|||||||
|
|
||||||
<template v-for="(group, groupName) in positionsToRender">
|
<template v-for="(group, groupName) in positionsToRender">
|
||||||
<tr v-if="groupMode">
|
<tr v-if="groupMode">
|
||||||
<td colspan="100%">
|
<td :colspan="Object.keys(config.fields).length + 1">
|
||||||
<h4 style="text-align: center;">{{ groupName }}</h4>
|
<div class="d-flex justify-content-center align-items-center">
|
||||||
|
<template v-if="editingGroupName === groupName">
|
||||||
|
<tt-input v-model="tempGroupName" sm style="max-width: 200px; margin-right: 10px;"/>
|
||||||
|
<tt-button @click="saveGroupName(groupName)" sm additional-class="btn-success" icon="fa fa-check" style="margin-right: 5px;"/>
|
||||||
|
<tt-button @click="cancelGroupEdit" sm additional-class="btn-secondary" icon="fa fa-times"/>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<h4 style="margin: 0; margin-right: 10px;">{{ groupName }}</h4>
|
||||||
|
<template v-if="groupName !== 'Keine Gruppe'">
|
||||||
|
<tt-button @click="startGroupEdit(groupName)" sm additional-class="btn-primary" icon="fa fa-edit" style="margin-right: 5px;"/>
|
||||||
|
<tt-button @click="deleteGroup(groupName)" sm additional-class="btn-danger" icon="fa fa-trash"/>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr v-for="(position, index) in group" :key="groupMode ? groupName + index : index">
|
<tr v-for="(position, index) in group" :key="groupMode ? groupName + index : index">
|
||||||
@@ -175,8 +190,8 @@ Vue.component('tt-positions-manager',
|
|||||||
<select v-if="groupMode" v-model="position._group" @change="$set(position, '_group', $event.target.value)">
|
<select v-if="groupMode" v-model="position._group" @change="$set(position, '_group', $event.target.value)">
|
||||||
<option v-for="group in allGroups" :value="group">{{ group }}</option>
|
<option v-for="group in allGroups" :value="group">{{ group }}</option>
|
||||||
</select>
|
</select>
|
||||||
<tt-button @click="editEntry(index)" sm additional-class="btn-primary" icon="fa fa-edit"/>
|
<tt-button @click="editEntry(getActualIndex(position, groupName, index))" sm additional-class="btn-primary" icon="fa fa-edit"/>
|
||||||
<tt-button @click="deleteEntry(index)" sm additional-class="btn-danger" icon="fa fa-trash"/>
|
<tt-button @click="deleteEntry(getActualIndex(position, groupName, index))" sm additional-class="btn-danger" icon="fa fa-trash"/>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</template>
|
</template>
|
||||||
@@ -237,6 +252,71 @@ Vue.component('tt-positions-manager',
|
|||||||
this.positions.push({_group: this.groupName});
|
this.positions.push({_group: this.groupName});
|
||||||
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) {
|
async editEntry(index) {
|
||||||
this.selectedIndex = index;
|
this.selectedIndex = index;
|
||||||
for (const [key, field] of Object.entries(this.config.fields)) {
|
for (const [key, field] of Object.entries(this.config.fields)) {
|
||||||
@@ -316,4 +396,4 @@ Vue.component('tt-positions-manager',
|
|||||||
deep: true
|
deep: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user