diff --git a/application/WorkorderAdmin/WorkorderAdminController.php b/application/WorkorderAdmin/WorkorderAdminController.php index 40259cb0b..22bea34b5 100644 --- a/application/WorkorderAdmin/WorkorderAdminController.php +++ b/application/WorkorderAdmin/WorkorderAdminController.php @@ -342,5 +342,60 @@ class WorkorderAdminController extends WorkorderBaseController self::returnJson(['success' => true, 'message' => 'Status erfolgreich auf "Zugewiesen" zurückgesetzt.']); } + + protected function scheduleAppointmentAction() + { + if (empty($this->postData['workorderId']) || empty($this->postData['appointmentDate'])) self::sendError("Erforderliche Felder fehlen."); + $workorder = WorkorderModel::get($this->postData['workorderId']); + if (!$workorder) self::sendError("Arbeitsauftrag nicht gefunden."); + if ((int)date('H', $this->postData['appointmentDate']) >= 23 || (int)date('H', $this->postData['appointmentDate']) < 1) self::sendError("Bitte geben Sie eine Uhrzeit an!"); + + $workorder->appointmentDate = $this->postData['appointmentDate']; + $workorder->status = 'scheduled'; + WorkorderModel::update((array)$workorder); + + WorkorderJournalModel::create([ + 'workorderId' => $workorder->id, 'text' => 'Termin festgelegt auf: ' . date('d.m.Y H:i', $this->postData['appointmentDate']), + 'create' => time(), 'createBy' => $this->user->id, + ]); + self::returnJson(['success' => true, 'message' => 'Termin erfolgreich gespeichert.']); + } + + protected function rescheduleAppointmentAction() + { + if (empty($this->postData['workorderId']) || empty($this->postData['appointmentDate']) || empty($this->postData['reason'])) self::sendError("Erforderliche Felder fehlen."); + $workorder = WorkorderModel::get($this->postData['workorderId']); + if (!$workorder) self::sendError("Arbeitsauftrag nicht gefunden."); + if ((int)date('H', $this->postData['appointmentDate']) >= 23 || (int)date('H', $this->postData['appointmentDate']) < 1) self::sendError("Bitte geben Sie eine Uhrzeit an!"); + + $oldDateFormatted = $workorder->appointmentDate ? date('d.m.Y H:i', $workorder->appointmentDate) : 'N/A'; + $newDateFormatted = date('d.m.Y H:i', $this->postData['appointmentDate']); + $workorder->appointmentDate = $this->postData['appointmentDate']; + WorkorderModel::update((array)$workorder); + + WorkorderJournalModel::create([ + 'workorderId' => $workorder->id, 'text' => "Termin verschoben von {$oldDateFormatted} auf {$newDateFormatted}. Grund: " . $this->postData['reason'], + 'create' => time(), 'createBy' => $this->user->id, + ]); + self::returnJson(['success' => true, 'message' => 'Termin erfolgreich verschoben.']); + } + + protected function clearAppointmentAction() + { + if (empty($this->postData['workorderId'])) self::sendError("Arbeitsauftrags-ID fehlt."); + $workorder = WorkorderModel::get($this->postData['workorderId']); + if (!$workorder) self::sendError("Arbeitsauftrag nicht gefunden."); + + $oldDateFormatted = $workorder->appointmentDate ? date('d.m.Y H:i', $workorder->appointmentDate) : 'N/A'; + $workorder->appointmentDate = null; + $workorder->status = 'assigned'; + WorkorderModel::update((array)$workorder); + + WorkorderJournalModel::create([ + 'workorderId' => $workorder->id, 'text' => "Termin gelöscht (war: {$oldDateFormatted}).", + 'create' => time(), 'createBy' => $this->user->id, + ]); + self::returnJson(['success' => true, 'message' => 'Termin erfolgreich gelöscht.']); + } //endregion } \ No newline at end of file diff --git a/public/js/pages/WorkorderAdmin/WorkorderAdmin.js b/public/js/pages/WorkorderAdmin/WorkorderAdmin.js index 6223ff0d1..ceb4eaa24 100644 --- a/public/js/pages/WorkorderAdmin/WorkorderAdmin.js +++ b/public/js/pages/WorkorderAdmin/WorkorderAdmin.js @@ -90,7 +90,23 @@ Vue.component('workorder-admin', { - {{ formatDate(row.appointmentDate, true) }} + + + + + + {{ formatDate(row.appointmentDate, true) }} + + + + – + @@ -120,13 +136,20 @@ Vue.component('workorder-admin', { + + Auftrag: #{{ rescheduleModalData.workorder.id }} + + + + `, data() { return { window, workordersToAssign: [], editingWorkorderId: null, editingDeadlineId: null, editingAdditionalInfoId: null, civilEngineeringData: null, tempAdditionalInfo: '', expandedNotes: [], companiesByTenant: {}, companiesLoading: false, massAssignCompanyId: null, - cancelWorkorderModalData: null, problemSolvedModalData: null, massAssignModalData: null, + cancelWorkorderModalData: null, problemSolvedModalData: null, massAssignModalData: null, rescheduleModalData: null, crudConfig: { ...window.TT_CONFIG.CRUD_CONFIG, selectable: false, expandable: true, customRowClass: (row) => { @@ -321,6 +344,98 @@ Vue.component('workorder-admin', { this.$refs.table.$refs.table.refreshTable(); this.cancelWorkorderModalData = null; } else window.notify('error', data.message || 'Stornierung fehlgeschlagen.'); + }, + getCalendarType(networkOwnerName) { + if (!networkOwnerName) return '1'; + const name = networkOwnerName.toLowerCase(); + if (name.includes('xinon')) return '2'; + if (name.includes('sbidi')) return '7'; + if (name.includes('estmk')) return '3'; + return '1'; + }, + getCampaignName(preordercampaignId) { + const col = this.crudConfig.columns.find(c => c.key === 'preordercampaign_id'); + const opt = col?.table?.filterOptions?.find(o => o.value == preordercampaignId); + return opt?.text || ''; + }, + openCalendarWithPrefill(workorder, dateUnix, win) { + const m = window.moment.unix(dateUnix); + const zeitraum = m.hour() < 12 ? 'VM' : 'NM'; + const campaignName = this.getCampaignName(workorder.preordercampaign_id); + const locationParts = [workorder.street, workorder.hausnummer]; + if (workorder.stiege) locationParts.push('/' + workorder.stiege); + const location = locationParts.join(' ') + ', ' + workorder.plz + ' ' + workorder.city; + const descLines = []; + if (workorder.oaid || campaignName || workorder.city) { + descLines.push([workorder.oaid, campaignName, workorder.city].filter(Boolean).join(' - ')); + } + descLines.push('Zeitraum: ' + zeitraum); + if (workorder.phone) descLines.push('Tel.: ' + workorder.phone); + if (workorder.additionalInfo) descLines.push(workorder.additionalInfo); + const calendarData = { + type: this.getCalendarType(workorder.networkOwnerName), + subject: workorder.customerCompany || workorder.customerName || '', + location: location, + cstart: m.format('DD.MM.YYYY HH:mm'), + cend: m.clone().add(90, 'minutes').format('DD.MM.YYYY HH:mm'), + description: descLines.join(''), + customer_phone: workorder.phone || null, + customer_email: workorder.email || null, + calendar_user_name: 'Pusnik', + attendee_names: ['Ziga Harc'], + }; + localStorage.setItem('Calendar_create', JSON.stringify(calendarData)); + win.location.href = '/Calendar/View'; + }, + async setAppointment(workorder, date) { + if (!date) return; + if (moment.unix(date).hour() >= 23 || moment.unix(date).hour() < 1) { + this.$refs.table.$refs.table.refreshTable(); + return window.notify('error', 'Bitte Uhrzeit angeben!'); + } + const calWin = window.open('about:blank', '_blank'); + const {data} = await axios.post(`${window.TT_CONFIG.BASE_PATH}/WorkorderAdmin/scheduleAppointment`, { + workorderId: workorder.id, appointmentDate: date + }); + if (data.success) { + window.notify('success', data.message); + this.$refs.table.$refs.table.refreshTable(); + this.openCalendarWithPrefill(workorder, date, calWin); + } else { + if (calWin) calWin.close(); + window.notify('error', data.message || 'Ein Fehler ist aufgetreten.'); + } + }, + openRescheduleModal(row) { + this.rescheduleModalData = { workorder: row, newDate: row.appointmentDate, reason: '' }; + }, + async rescheduleAppointment() { + const { workorder, newDate, reason } = this.rescheduleModalData; + if (!newDate || !reason) return window.notify('error', 'Bitte geben Sie ein neues Datum und einen Grund an.'); + if (moment.unix(newDate).hour() >= 23 || moment.unix(newDate).hour() < 1) return window.notify('error', 'Bitte Uhrzeit angeben!'); + const calWin = window.open('about:blank', '_blank'); + const {data} = await axios.post(`${window.TT_CONFIG.BASE_PATH}/WorkorderAdmin/rescheduleAppointment`, { + workorderId: workorder.id, appointmentDate: newDate, reason: reason + }); + if (data.success) { + window.notify('success', data.message); + this.$refs.table.$refs.table.refreshTable(); + this.openCalendarWithPrefill(workorder, newDate, calWin); + this.rescheduleModalData = null; + } else { + if (calWin) calWin.close(); + window.notify('error', data.message || 'Ein Fehler ist aufgetreten.'); + } + }, + async clearAppointment(workorder) { + if (!confirm('Möchten Sie den Termin wirklich löschen?')) return; + const {data} = await axios.post(`${window.TT_CONFIG.BASE_PATH}/WorkorderAdmin/clearAppointment`, { + workorderId: workorder.id + }); + if (data.success) { + window.notify('success', data.message); + this.$refs.table.$refs.table.refreshTable(); + } else window.notify('error', data.message || 'Ein Fehler ist aufgetreten.'); } }, watch: {
Auftrag: #{{ rescheduleModalData.workorder.id }}