diff --git a/application/WarehouseShippingNote/WarehouseShippingNoteController.php b/application/WarehouseShippingNote/WarehouseShippingNoteController.php index 559379fc3..f8c680eb9 100644 --- a/application/WarehouseShippingNote/WarehouseShippingNoteController.php +++ b/application/WarehouseShippingNote/WarehouseShippingNoteController.php @@ -45,19 +45,21 @@ class WarehouseShippingNoteController extends TTCrud { fn($p) => $p['status'] === 'new' ?: 'Status muss "Neu" sein', fn($p) => $this->validateHours($p['hoursEntries']) ]); - $postData['positions'] = json_encode($postData['positions']); + $this->postData['positions'] = json_encode($this->postData['positions']); + if (isset($this->postData['metadata'])) $this->postData['metadata'] = json_encode($this->postData['metadata']); return true; } protected function beforeUpdate($postData): bool { if (!$this->user->can('WarehouseAdmin')) { - $this->validate($postData, [ - fn($p) => !in_array(WarehouseShippingNoteModel::get($p['id'])->status, - ['accepted', 'invoiced']) ?: 'Änderungen nicht mehr möglich', - fn($p) => $this->validateHours($p['hoursEntries']) - ]); + $this->validate($postData, [ + fn($p) => !in_array(WarehouseShippingNoteModel::get($p['id'])->status, + ['accepted', 'invoiced']) ?: 'Änderungen nicht mehr möglich', + fn($p) => $this->validateHours($p['hoursEntries']) + ]); } - $postData['positions'] = json_encode($postData['positions']); + $this->postData['positions'] = json_encode($this->postData['positions']); + if (isset($this->postData['metadata'])) $this->postData['metadata'] = json_encode($this->postData['metadata']); (new WarehouseHistoryController)->create($postData, $this->mod); return true; } @@ -743,7 +745,9 @@ class WarehouseShippingNoteController extends TTCrud { return [ 'date' => date('Y-m-d H:i:s', strtotime($eventStart)), 'location' => $event['location']['location'] ?? '', - 'category' => $event['category']['category'] ?? '' + 'category' => $event['category']['category'] ?? '', + 'ccategory' => $event['ccategory']['ccategory'] ?? '', + 'event_type' => $event['event_type']['event_type'] ?? '', ]; }, $limitedEvents); diff --git a/application/WarehouseShippingNote/WarehouseShippingNoteModel.php b/application/WarehouseShippingNote/WarehouseShippingNoteModel.php index bf4851248..8cc4e5721 100644 --- a/application/WarehouseShippingNote/WarehouseShippingNoteModel.php +++ b/application/WarehouseShippingNote/WarehouseShippingNoteModel.php @@ -4,6 +4,7 @@ class WarehouseShippingNoteModel extends TTCrudBaseModel { public int $id; public ?int $billingAddressId; public ?string $type; + public ?string $metadata; public string $deliveryAddressName; public string $deliveryAddressLine; public string $deliveryAddressPLZ; @@ -20,6 +21,4 @@ class WarehouseShippingNoteModel extends TTCrudBaseModel { public ?int $eShopOrderId; public ?int $create; public ?int $createBy; -} - - +} \ No newline at end of file diff --git a/db/migrations/20250901110000_warehouse_modify_24.php b/db/migrations/20250901110000_warehouse_modify_24.php new file mode 100644 index 000000000..40f0acbfa --- /dev/null +++ b/db/migrations/20250901110000_warehouse_modify_24.php @@ -0,0 +1,30 @@ +getEnvironment() == "thetool") { + $WarehouseShippingNote = $this->table("WarehouseShippingNote"); + + if (!$WarehouseShippingNote->hasColumn("metadata")) { + $WarehouseShippingNote + ->addColumn("metadata", "json", ["null" => true, "default" => null, "after" => "type"]) + ->update(); + } + } + } + + public function down(): void { + if ($this->getEnvironment() == "thetool") { + $WarehouseShippingNote = $this->table("WarehouseShippingNote"); + + if ($WarehouseShippingNote->hasColumn("metadata")) { + $WarehouseShippingNote + ->removeColumn("metadata") + ->update(); + } + } + } +} diff --git a/public/js/pages/WarehouseShippingNote/WarehouseShippingNote.js b/public/js/pages/WarehouseShippingNote/WarehouseShippingNote.js index 631b1e63d..1e2ee29a7 100644 --- a/public/js/pages/WarehouseShippingNote/WarehouseShippingNote.js +++ b/public/js/pages/WarehouseShippingNote/WarehouseShippingNote.js @@ -306,6 +306,11 @@ Vue.component('warehouse-shipping-note-see-through', { + +
+ + Erstellt aus Kalendereintrag: {{ calendarEventType }} +
@@ -341,6 +346,21 @@ Vue.component('warehouse-shipping-note-see-through', { computed: { currentRow() { return this.rows[0]; + }, + calendarEventType() { + if (!this.currentRow || !this.currentRow.metadata) { + return null; + } + try { + const metadata = JSON.parse(this.currentRow.metadata); + if (metadata && metadata.from_calendar === true && metadata.event_type_text) { + return metadata.event_type_text; + } + } catch (e) { + console.error("Could not parse shipping note metadata:", e); + return null; + } + return null; } }, methods: { @@ -550,10 +570,40 @@ Vue.component('warehouse-shipping-note', { const locationParts = event.location.split(','); const line = locationParts.slice(0, -1).join(',').trim(); const plzCityRaw = locationParts.slice(-1)[0].trim(); - - const plzMatch = plzCityRaw.match(/^(\d+)/); + const plzMatch = plzCityRaw.match(/^(\\d+)/); const plz = plzMatch ? plzMatch[1] : ''; - const city = plzCityRaw.replace(/^\d+\s*/, '').trim(); + const city = plzCityRaw.replace(/^\\d+\\s*/, '').trim(); + + // Create metadata object + const eventTypeMap = { + '2': 'Xinon Inbetriebnahmen', + '3': 'ESTMK Inbetriebnahmen', + '7': 'Sbidi Inbetriebnahmen', + '4': 'SNOPP', + '5': 'Störungen', + '6': 'Support Gespräch' + }; + const eventTypeText = eventTypeMap[event.event_type] || 'Unbekannter Termintyp'; + + const metadata = { + from_calendar: true, + event_type_id: event.event_type, + event_type_text: eventTypeText + }; + + // Check for default positions for SBIDI event type + let defaultPositions = []; + if (event.event_type === '7') { + defaultPositions = [ + {"article": 56, "amount": "1", "isEnergieMaterial": 1}, + {"article": 71, "amount": "1", "isEnergieMaterial": 1}, + {"article": 134, "amount": "1", "isEnergieMaterial": 1}, + {"article": 324, "isEnergieMaterial": 1, "amount": "1"}, + {"article": 325, "amount": "1", "isEnergieMaterial": 1}, + {"article": 539, "amount": "1", "isEnergieMaterial": 1}, + {"article": 660, "amount": "1", "isEnergieMaterial": 1} + ]; + } // Directly set the data in the modal's `shippingNote` object const modalData = this.$refs.modal.shippingNote; @@ -561,6 +611,11 @@ Vue.component('warehouse-shipping-note', { this.$set(modalData, 'deliveryAddressLine', line); this.$set(modalData, 'deliveryAddressPLZ', plz); this.$set(modalData, 'deliveryAddressCity', city); + this.$set(modalData, 'metadata', metadata); // Set metadata + + if (defaultPositions.length > 0) { + this.$set(modalData, 'positions', defaultPositions); // Set default positions + } } }, closeDropdown(event) { diff --git a/public/js/pages/WarehouseShippingNote/WarehouseShippingNoteModal.js b/public/js/pages/WarehouseShippingNote/WarehouseShippingNoteModal.js index 8f10ffacb..5433748eb 100644 --- a/public/js/pages/WarehouseShippingNote/WarehouseShippingNoteModal.js +++ b/public/js/pages/WarehouseShippingNote/WarehouseShippingNoteModal.js @@ -18,6 +18,7 @@ Vue.component('warehouse-shipping-note-modal', { deliveryAddressPLZ: '', deliveryAddressCity: '', status: 'new', + metadata: null, positions: [], textElements: [], hoursEntries: [], @@ -196,7 +197,12 @@ Vue.component('warehouse-shipping-note-modal', { if (this.id === 'create') return; const {data} = await axios.get(`${window.TT_CONFIG["BASE_PATH"]}/WarehouseShippingNote/getById`, {params: {id: this.id}}); - this.shippingNote = {...data, positions: JSON.parse(data.positions), hoursEntries: JSON.parse(data.hoursEntries)}; + this.shippingNote = { + ...data, + positions: JSON.parse(data.positions), + hoursEntries: JSON.parse(data.hoursEntries), + metadata: data.metadata ? JSON.parse(data.metadata) : null + }; }, watch: { geoAddr: async function() {