// RMLWorkorderAdmin.js Vue.component('r-m-l-workorder-admin', { template: `
{{ workordersToAssign.length }} Workorder(s) zuweisen:
`, data() { return { window, workordersToAssign: [], editingWorkorderId: null, editingDeadlineId: null, companies: [], massAssignCompanyId: null, massAssignLoading: false, crudConfig: { ...window.TT_CONFIG.CRUD_CONFIG, selectable: false, expandable: true, customRowClass: (row) => { const deadlineDate = moment.unix(row.deadlineDate); if (['completed', 'new'].includes(row.status) || !deadlineDate.isValid()) { return 'tt-rml-workorder-irrelevant'; } if (['correction_requested', 'intervention_required'].includes(row.status)) { return 'tt-rml-workorder-high'; } const daysLeft = deadlineDate.diff(moment(), 'days'); if (daysLeft <= 7) return 'tt-rml-workorder-urgent'; if (daysLeft <= 21) return 'tt-rml-workorder-medium'; return 'tt-rml-workorder-ontrack'; }, additionalActions: [] } } }, async mounted() { const response = await axios.get(`${window.TT_CONFIG.BASE_PATH}/RMLWorkorderAdmin/getCompanies`); this.companies = response.data; }, methods: { addToAssignList(row) { if (!this.workordersToAssign.includes(row.id)) { this.workordersToAssign.push(row.id); } }, removeFromAssignList(row) { this.workordersToAssign = this.workordersToAssign.filter(id => id !== row.id); }, getStatusColumn(status) { const column = this.crudConfig.columns.find(c => c.key === 'status'); return column.table.filterOptions.find(opt => opt.value === status) || {}; }, formatDate(timestamp) { if (!timestamp) return '–'; return window.moment.unix(timestamp).format('DD.MM.YYYY'); }, async assignCompany(workorder, companyId) { if (!companyId) { this.editingWorkorderId = null; return; } const payload = { workorderId: workorder.id, companyId: companyId }; try { const response = await axios.post(`${window.TT_CONFIG.BASE_PATH}/RMLWorkorderAdmin/assignWorkorder`, payload); if (response.data.success) { window.notify('success', response.data.message); this.$refs.table.$refs.table.refreshTable(); } else { window.notify('error', response.data.message || 'Ein Fehler ist aufgetreten.'); } } catch (e) { window.notify('error', 'Ein Netzwerkfehler ist aufgetreten.'); } finally { this.editingWorkorderId = null; } }, async massAssignCompanies(companyId) { if (!companyId) return; if (!confirm(`${this.workordersToAssign.length} Workorder(s) der ausgewählten Firma zuweisen?`)) { this.massAssignCompanyId = null; // Reset select on cancel return; } this.massAssignLoading = true; const payload = { companyId: companyId, workorderIds: this.workordersToAssign }; try { const response = await axios.post(`${window.TT_CONFIG.BASE_PATH}/RMLWorkorderAdmin/massAssignWorkorders`, payload); if (response.data.success) { window.notify('success', response.data.message); this.workordersToAssign = []; this.$refs.table.$refs.table.refreshTable(); } else { window.notify('error', response.data.message || 'Ein Fehler ist aufgetreten.'); } } catch (e) { window.notify('error', 'Ein Netzwerkfehler ist aufgetreten.'); } finally { this.massAssignLoading = false; this.massAssignCompanyId = null; } }, async updateDeadline(workorder, newDate) { if (!newDate) { this.editingDeadlineId = null; return; } try { const response = await axios.post(`${window.TT_CONFIG.BASE_PATH}/RMLWorkorderAdmin/updateDeadline`, { workorderId: workorder.id, deadlineDate: newDate }); if (response.data.success) { window.notify('success', response.data.message); this.$refs.table.$refs.table.refreshTable(); } else { window.notify('error', response.data.message || 'Ein Fehler ist aufgetreten.'); } } catch (e) { window.notify('error', 'Ein Netzwerkfehler ist aufgetreten.'); } finally { this.editingDeadlineId = null; } }, async acceptDocumentation(workorderId) { if (!confirm('Soll die Dokumentation für diesen Arbeitsauftrag wirklich akzeptiert und der Auftrag abgeschlossen werden?')) return; try { const response = await axios.post(`${window.TT_CONFIG.BASE_PATH}/RMLWorkorderAdmin/acceptDocumentation`, { workorderId }); if (response.data.success) { window.notify('success', response.data.message); this.$refs.table.$refs.table.refreshTable(); } else { window.notify('error', response.data.message || 'Ein Fehler ist aufgetreten.'); } } catch (e) { window.notify('error', 'Ein Netzwerkfehler ist aufgetreten.'); } } } }); Vue.component('traffic-light', { props: ['deadline', 'status'], computed: { lightInfo() { if (['completed', 'new'].includes(this.status)) return {color: '#cccccc', title: 'Status irrelevant für Dringlichkeit'}; const now = moment(); const deadlineDate = moment.unix(this.deadline); if (!deadlineDate.isValid()) return {color: '#cccccc', title: 'Keine Deadline gesetzt'}; if (deadlineDate.isBefore(now)) return {color: '#dc3545', title: 'Deadline überschritten'}; const daysLeft = deadlineDate.diff(now, 'days'); if (daysLeft <= 7) return {color: '#dc3545', title: 'Dringend: Weniger als 1 Woche'}; if (daysLeft <= 21) return {color: '#ffc107', title: 'Mittel: Weniger als 3 Wochen'}; return {color: '#28a745', title: 'Im Plan: Mehr als 3 Wochen'}; } }, template: `` }); Vue.component('rml-documentation-viewer-admin', { props: ['workorderId'], template: `
Korrektur anfordern

Wählen Sie die zu korrigierenden Dokumente aus der Galerie aus und geben Sie einen Grund an.

Dokumentation akzeptieren

Wenn die Dokumentation korrekt ist, können Sie sie hier akzeptieren.

Journal
  • {{ formatDate(log.create) }} ({{ log.createByName }}):
    {{ log.text }}
Keine Journaleinträge.
`, data() { return { loading: true, correctionLoading: false, docs: [], journals: [], selectedDocs: [], correctionText: '', newJournalMessage: '', addingJournalEntry: false, } }, methods: { async fetchData() { this.loading = true; try { const response = await axios.get(`${window.TT_CONFIG.BASE_PATH}/RMLWorkorderAdmin/getDocumentation`, { params: { workorderId: this.workorderId }}); this.docs = response.data.docs; this.journals = response.data.journals; } catch(e) { window.notify('error', 'Dokumentation konnte nicht geladen werden.'); } finally { this.loading = false; } }, async requestCorrection() { if (!this.correctionText) return window.notify('error', 'Bitte geben Sie einen Grund für die Korrektur an.'); if (this.selectedDocs.length === 0) return window.notify('error', 'Bitte wählen Sie mindestens ein Dokument für die Korrektur aus.'); this.correctionLoading = true; try { const payload = { workorderId: this.workorderId, text: this.correctionText, fileIds: this.selectedDocs }; const response = await axios.post(`${window.TT_CONFIG.BASE_PATH}/RMLWorkorderAdmin/requestCorrection`, payload); if (response.data.success) { window.notify('success', response.data.message); this.correctionText = ''; this.selectedDocs = []; await this.fetchData(); this.$emit('workorder-updated'); } else { window.notify('error', response.data.message); } } catch (e) { window.notify('error', 'Ein Netzwerkfehler ist aufgetreten.'); } this.correctionLoading = false; }, async addJournalEntry() { if (!this.newJournalMessage.trim()) { return window.notify('error', 'Bitte geben Sie eine Nachricht ein.'); } this.addingJournalEntry = true; try { const response = await axios.post(`${window.TT_CONFIG.BASE_PATH}/RMLWorkorderAdmin/addJournal`, { workorderId: this.workorderId, text: this.newJournalMessage }); if (response.data.success) { window.notify('success', response.data.message || 'Journal-Eintrag hinzugefügt.'); this.newJournalMessage = ''; this.journals = response.data.journals; } else { window.notify('error', response.data.message || 'Eintrag konnte nicht gespeichert werden.'); } } catch (e) { window.notify('error', 'Ein Netzwerkfehler ist aufgetreten.'); } finally { this.addingJournalEntry = false; } }, formatDate(timestamp) { return window.moment.unix(timestamp).format('DD.MM.YYYY HH:mm'); }, }, mounted() { this.fetchData(); } });