Vue.component('warehouse-project', { template: `
`, data() { return { additionalActions: [], projectModalId: null }; }, methods: { openProjectModal(id) { this.projectModalId = id; }, closeProjectModal() { this.projectModalId = null; this.$refs.table.$refs.table.refreshTable(); } } }); Vue.component('warehouse-project-details', { props: ['project'], template: `
Projektdaten
Status
{{ statusText(project.status) }}
Projekt-Nr.
{{ project.projectNumber }}
Zeitraum
{{ formatDate(project.startDate) }} - {{ formatDate(project.endDate) }}
Lagerort
{{ project.storageLocation || '-' }}
Budget
{{ formatPrice(project.financials) }}
Details

Beschreibung

{{ project.description || 'Keine Beschreibung vorhanden.' }}

Externes Team / Partner

{{ project.externalTeam || '-' }}
Fortschritt:
{{ taskProgress }}%
Zu Erledigen {{ tasksByStatus('todo').length }}

{{ task.description }}

{{ task.assignedUserName || 'Niemand' }}
Keine Aufgaben
In Arbeit {{ tasksByStatus('in_progress').length }}

{{ task.description }}

{{ task.assignedUserName || 'Niemand' }}
Erledigt {{ tasksByStatus('done').length }}
{{ task.title }}
Abgeschlossen
Projektteam
{{ team.length }} Mitglieder
  • {{ member.name.charAt(0) }}
    {{ member.name }}
    {{ member.role || 'Projektmitarbeiter' }}
  • Noch keine Teammitglieder zugewiesen.

Logistik & Bestellungen
{{ request.requestId }} | {{ request.purpose }}
Erledigt Storniert Offen
Enthaltene Bestellungen
Order Nr. Status Aktion
{{ order.orderNumber }} {{ order.status || 'Unbekannt' }} Öffnen
Keine direkten Bestellungen verknüpft oder Daten noch nicht verfügbar.

Keine verknüpften Bestellwünsche.

{{ new Date(log.create * 1000).toLocaleDateString('de-DE', {day: '2-digit', month: '2-digit'}) }}
{{ new Date(log.create * 1000).toLocaleTimeString('de-DE', {hour: '2-digit', minute: '2-digit'}) }}
{{ log.userName }}
{{ log.text }}

Noch keine Journal-Einträge.

Dokumente

Dateien hierher ziehen

(WIP: Upload Funktion)

`, data() { return { activeTab: 'overview', tasks: [], team: [], linkedOrders: [], journal: [], allUsers: [], availableOrders: [], selectedUserId: '', newJournalMessage: '', currentTask: { id: null, title: '', description: '', assignedUserId: '', status: 'todo' } }; }, computed: { taskProgress() { if (!this.tasks || !this.tasks.length) return 0; const done = this.tasks.filter(t => t.status === 'done').length; return Math.round((done / this.tasks.length) * 100); }, allUsersSelectItems() { return this.allUsers.map(u => ({ value: u.id, text: u.name })); } }, mounted() { this.loadData(); }, methods: { async loadData() { try { await Promise.all([ this.fetchTasks(), this.fetchTeam(), this.fetchLinkedOrders(), this.fetchJournal(), this.fetchUsers() ]); } catch (e) { console.error("Error loading project data", e); } }, async fetchTasks() { try { const res = await axios.get('/WarehouseProject/getTasks?id=' + this.project.id); this.tasks = Array.isArray(res.data) ? res.data : []; } catch(e) { this.tasks = []; } }, async fetchTeam() { try { const res = await axios.get('/WarehouseProject/getTeam?id=' + this.project.id); this.team = Array.isArray(res.data) ? res.data : []; } catch(e) { this.team = []; } }, async fetchLinkedOrders() { try { const res = await axios.get('/WarehouseProject/getLinkedOrders?id=' + this.project.id); this.linkedOrders = Array.isArray(res.data) ? res.data : []; } catch(e) { this.linkedOrders = []; } }, async fetchJournal() { try { const res = await axios.get('/WarehouseProject/getJournal?id=' + this.project.id); this.journal = Array.isArray(res.data) ? res.data : []; } catch(e) { this.journal = []; } }, async fetchUsers() { try { const res = await axios.get('/WarehouseProject/getUsers'); this.allUsers = Array.isArray(res.data) ? res.data : []; } catch(e) { this.allUsers = []; } }, async fetchAvailableOrders() { try { const res = await axios.get('/WarehouseProject/getAvailableOrderRequests'); this.availableOrders = Array.isArray(res.data) ? res.data : []; } catch(e) { this.availableOrders = []; } }, // Helpers tasksByStatus(status) { if (!this.tasks) return []; return this.tasks.filter(t => t.status === status); }, statusLabel(status) { const map = { todo: 'ToDo', in_progress: 'In Arbeit', done: 'Erledigt' }; return map[status] || status; }, statusText(status) { const map = { new: 'Neu', wip: 'In Bearbeitung', finished: 'Abgeschlossen', cancelled: 'Storniert' }; return map[status] || status; }, statusBadgeClass(status) { const map = { new: 'badge badge-primary', wip: 'badge badge-warning', finished: 'badge badge-success', cancelled: 'badge badge-danger' }; return map[status] || 'badge badge-secondary'; }, formatDate(ts) { if (!ts) return '-'; return new Date(ts * 1000).toLocaleDateString('de-DE'); }, formatDateTime(ts) { if (!ts) return '-'; return new Date(ts * 1000).toLocaleString('de-DE'); }, formatPrice(val) { return new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(val || 0); }, // Actions openTaskModal(task = null) { if (task) { this.currentTask = { ...task }; } else { this.currentTask = { id: null, title: '', description: '', assignedUserId: '', status: 'todo' }; } $(this.$refs.taskModal).modal('show'); }, async saveTask() { if (!this.currentTask.title) return alert("Titel erforderlich"); try { await axios.post('/WarehouseProject/saveTask', { ...this.currentTask, projectId: this.project.id }); $(this.$refs.taskModal).modal('hide'); this.fetchTasks(); this.fetchJournal(); } catch(e) { console.error(e); alert("Fehler beim Speichern: " + (e.response?.data?.error || 'Unbekannt')); } }, async updateTaskStatus(id, status) { await axios.post('/WarehouseProject/updateTaskStatus', { id, status }); this.fetchTasks(); this.fetchJournal(); }, async deleteTask(id) { if(!confirm("Wirklich löschen?")) return; await axios.get('/WarehouseProject/deleteTask?id=' + id); this.fetchTasks(); this.fetchJournal(); }, async addMember() { if (!this.selectedUserId) return; try { await axios.post('/WarehouseProject/addTeamMember', { projectId: this.project.id, userId: this.selectedUserId }); this.fetchTeam(); this.fetchJournal(); this.selectedUserId = ''; } catch (e) { alert("Fehler beim Hinzufügen (evtl. bereits im Team?)"); } }, async removeMember(id) { await axios.get('/WarehouseProject/removeTeamMember?id=' + id); this.fetchTeam(); this.fetchJournal(); }, async openLinkOrderModal() { await this.fetchAvailableOrders(); $(this.$refs.linkOrderModal).modal('show'); }, async linkOrder(orderId) { if (!orderId) return; try { await axios.post('/WarehouseProject/linkOrder', { projectId: this.project.id, orderId }); $(this.$refs.linkOrderModal).modal('hide'); this.fetchLinkedOrders(); this.fetchJournal(); } catch (e) { alert("Fehler beim Verknüpfen"); } }, async unlinkOrder(id) { await axios.get('/WarehouseProject/unlinkOrder?id=' + id); this.fetchLinkedOrders(); this.fetchJournal(); }, async postJournal() { if (!this.newJournalMessage.trim()) return; await axios.post('/WarehouseProject/createJournalEntry', { projectId: this.project.id, message: this.newJournalMessage }); this.newJournalMessage = ''; this.fetchJournal(); } } });