added new features
This commit is contained in:
@@ -19,6 +19,7 @@ class RMLWorkorderAdminController extends TTCrud
|
||||
['value' => 'scheduled', 'text' => 'Terminiert', 'icon' => 'fas fa-calendar-check text-warning'],
|
||||
['value' => 'correction_requested', 'text' => 'Korrektur angefordert', 'icon' => 'fas fa-exclamation-triangle text-danger'],
|
||||
['value' => 'intervention_required', 'text' => 'Eingriff benötigt', 'icon' => 'fas fa-times-circle text-danger'],
|
||||
['value' => 'problem_solved', 'text' => 'Problem behoben', 'icon' => 'fas fa-check-circle text-success'],
|
||||
['value' => 'documented', 'text' => 'Dokumentiert', 'icon' => 'fas fa-file-alt text-success'],
|
||||
['value' => 'completed', 'text' => 'Abgeschlossen', 'icon' => 'fas fa-check-double text-secondary'],
|
||||
]]],
|
||||
@@ -101,23 +102,6 @@ class RMLWorkorderAdminController extends TTCrud
|
||||
}
|
||||
}
|
||||
|
||||
protected function assignWorkorderAction() {
|
||||
$post = json_decode(file_get_contents('php://input'), true);
|
||||
if (empty($post['workorderId']) || empty($post['companyId'])) self::sendError("Required fields are missing.");
|
||||
|
||||
$workorder = RMLWorkorderModel::get($post['workorderId']);
|
||||
if (!$workorder) self::sendError("Workorder not found.");
|
||||
|
||||
$workorder->companyId = $post['companyId'];
|
||||
$workorder->status = 'assigned';
|
||||
$workorder->assignmentDate = time();
|
||||
$workorder->deadlineDate = $post['deadlineDate'] ?? strtotime('+6 weeks');
|
||||
|
||||
RMLWorkorderModel::update((array)$workorder);
|
||||
|
||||
self::returnJson(['success' => true, 'message' => 'Auftrag erfolgreich zugewiesen.']);
|
||||
}
|
||||
|
||||
protected function getDocumentationAction() {
|
||||
if(empty($this->request->workorderId)) self::sendError("Workorder ID missing.");
|
||||
|
||||
@@ -137,20 +121,66 @@ class RMLWorkorderAdminController extends TTCrud
|
||||
self::returnJson(['docs' => $docs, 'journals' => $journals]);
|
||||
}
|
||||
|
||||
private function assignSingleWorkorder($workorderId, $companyId, $deadline, $userId) {
|
||||
$workorder = RMLWorkorderModel::get($workorderId);
|
||||
if (!$workorder) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$company = RMLWorkorderCompanyModel::get($companyId);
|
||||
if (!$company) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$workorder->companyId = $companyId;
|
||||
$workorder->status = 'assigned';
|
||||
$workorder->assignmentDate = time();
|
||||
$workorder->deadlineDate = $deadline;
|
||||
RMLWorkorderModel::update((array)$workorder);
|
||||
|
||||
RMLWorkorderJournalModel::create([
|
||||
'workorderId' => $workorder->id,
|
||||
'text' => "Firma '{$company->name}' wurde zugewiesen.",
|
||||
'create' => time(),
|
||||
'createBy' => $userId,
|
||||
]);
|
||||
|
||||
$preorder = new Preorder($workorder->preorderId);
|
||||
if ($preorder) {
|
||||
$preorder->status_id = 10; // Assuming 10 is the status for "assigned"
|
||||
$preorder->edit_by = $this->user->id;
|
||||
$preorder->save();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function assignWorkorderAction() {
|
||||
$post = json_decode(file_get_contents('php://input'), true);
|
||||
if (empty($post['workorderId']) || empty($post['companyId'])) {
|
||||
self::sendError("Erforderliche Felder fehlen.");
|
||||
}
|
||||
|
||||
$deadline = !empty($post['deadlineDate']) ? $post['deadlineDate'] : strtotime('+6 weeks');
|
||||
$success = $this->assignSingleWorkorder($post['workorderId'], $post['companyId'], $deadline, $this->user->id);
|
||||
|
||||
if ($success) {
|
||||
self::returnJson(['success' => true, 'message' => 'Auftrag erfolgreich zugewiesen.']);
|
||||
} else {
|
||||
self::sendError("Auftrag konnte nicht zugewiesen werden. Möglicherweise wurde er bereits bearbeitet oder existiert nicht.");
|
||||
}
|
||||
}
|
||||
|
||||
protected function massAssignWorkordersAction() {
|
||||
$post = json_decode(file_get_contents('php://input'), true);
|
||||
if (empty($post['workorderIds']) || empty($post['companyId'])) self::sendError("Required fields are missing.");
|
||||
if (empty($post['workorderIds']) || empty($post['companyId'])) {
|
||||
self::sendError("Erforderliche Felder fehlen.");
|
||||
}
|
||||
|
||||
$deadline = strtotime($post['deadlineDate'] ?? '+6 weeks');
|
||||
$count = 0;
|
||||
foreach ($post['workorderIds'] as $workorderId) {
|
||||
$workorder = RMLWorkorderModel::get($workorderId);
|
||||
if ($workorder && $workorder->status === 'new') {
|
||||
$workorder->companyId = $post['companyId'];
|
||||
$workorder->status = 'assigned';
|
||||
$workorder->assignmentDate = time();
|
||||
$workorder->deadlineDate = $deadline;
|
||||
RMLWorkorderModel::update((array)$workorder);
|
||||
if ($this->assignSingleWorkorder($workorderId, $post['companyId'], $deadline, $this->user->id)) {
|
||||
$count++;
|
||||
}
|
||||
}
|
||||
@@ -260,4 +290,44 @@ class RMLWorkorderAdminController extends TTCrud
|
||||
|
||||
self::returnJson(['success' => true, 'message' => 'Dokumentation akzeptiert und Auftrag abgeschlossen.']);
|
||||
}
|
||||
|
||||
protected function setToProblemSolvedAction() {
|
||||
// const response = await axios.post(`${window.TT_CONFIG.BASE_PATH}/RMLWorkorderAdmin/setToProblemSolved`, {
|
||||
// workorderId: row.id,
|
||||
// text: text
|
||||
// });
|
||||
|
||||
$post = json_decode(file_get_contents('php://input'), true);
|
||||
|
||||
if (empty($post['workorderId']) || empty($post['text'])) {
|
||||
self::sendError("Workorder ID und Text sind erforderlich.");
|
||||
}
|
||||
|
||||
$workorder = RMLWorkorderModel::get($post['workorderId']);
|
||||
|
||||
if (!$workorder) {
|
||||
self::sendError("Workorder nicht gefunden.");
|
||||
}
|
||||
|
||||
if ($workorder->status !== 'intervention_required') {
|
||||
self::sendError("Der Auftrag muss den Status 'Eingriff benötigt' haben, um als Problem gelöst markiert zu werden.");
|
||||
}
|
||||
|
||||
$oldStatus = $workorder->status;
|
||||
$workorder->status = 'problem_solved';
|
||||
RMLWorkorderModel::update((array)$workorder);
|
||||
|
||||
$oldStatusText = $oldStatus === 'intervention_required' ? 'Eingriff benötigt' : $oldStatus;
|
||||
$problem_solved = 'Problem gelöst';
|
||||
|
||||
RMLWorkorderJournalModel::create([
|
||||
'workorderId' => $workorder->id,
|
||||
'text' => $post['text'],
|
||||
'statusChange' => "$oldStatusText -> $problem_solved",
|
||||
'create' => time(),
|
||||
'createBy' => $this->user->id,
|
||||
]);
|
||||
|
||||
self::returnJson(['success' => true, 'message' => 'Auftrag als Problem gelöst markiert.']);
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,7 @@ class RMLWorkorderCompanyController extends TTCrud
|
||||
['value' => 'scheduled', 'text' => 'Terminiert', 'icon' => 'fas fa-calendar-check text-warning'],
|
||||
['value' => 'correction_requested', 'text' => 'Korrektur angefordert', 'icon' => 'fas fa-exclamation-triangle text-danger'],
|
||||
['value' => 'intervention_required', 'text' => 'Eingriff benötigt', 'icon' => 'fas fa-times-circle text-danger'],
|
||||
['value' => 'problem_solved', 'text' => 'Problem behoben', 'icon' => 'fas fa-check-circle text-success'],
|
||||
['value' => 'documented', 'text' => 'Dokumentiert', 'icon' => 'fas fa-file-alt text-success'],
|
||||
['value' => 'completed', 'text' => 'Abgeschlossen', 'icon' => 'fas fa-check-double text-secondary'],
|
||||
]]],
|
||||
|
||||
@@ -48,6 +48,14 @@ Vue.component('r-m-l-workorder-admin', {
|
||||
<traffic-light :deadline="row.deadlineDate" :status="row.status"/>
|
||||
<i :class="getStatusColumn(row.status).icon" :title="getStatusColumn(row.status).text"></i>
|
||||
<span class="ml-2">{{ getStatusColumn(row.status).text }}</span>
|
||||
<tt-button
|
||||
v-if="row.status === 'intervention_required'"
|
||||
icon="ml-2 fas fa-check-circle text-success"
|
||||
@click="setToProblemSolved(row)"
|
||||
additional-class="btn-link btn-sm p-0"
|
||||
title="Auftrag auf Problem behoben setzen"
|
||||
/>
|
||||
|
||||
</template>
|
||||
|
||||
<template v-slot:companyname="{ row }">
|
||||
@@ -287,6 +295,30 @@ Vue.component('r-m-l-workorder-admin', {
|
||||
} catch (e) {
|
||||
window.notify('error', 'Ein Netzwerkfehler ist aufgetreten.');
|
||||
}
|
||||
},
|
||||
async setToProblemSolved(row) {
|
||||
// add a browser dialog to add some text
|
||||
const text = prompt('Bitte geben Sie einen kurzen Text für den Eintrag ein:', '');
|
||||
|
||||
if (!text) {
|
||||
window.notify('error', 'Bitte geben Sie einen Text ein.');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await axios.post(`${window.TT_CONFIG.BASE_PATH}/RMLWorkorderAdmin/setToProblemSolved`, {
|
||||
workorderId: row.id,
|
||||
text: text
|
||||
});
|
||||
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.');
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -320,7 +352,7 @@ Vue.component('rml-documentation-viewer-admin', {
|
||||
<tt-file-gallery :files="docs" @selection-changed="selectedDocs = $event" selectable />
|
||||
</div>
|
||||
<div class="col-lg-6">
|
||||
<div class="card mb-3">
|
||||
<div class="card mb-3" v-if="selectedDocs.length > 0"></div>
|
||||
<div class="card-header"><h5><i class="fas fa-exclamation-triangle text-danger mr-2"></i>Korrektur anfordern</h5></div>
|
||||
<div class="card-body">
|
||||
<p class="small text-muted">Wählen Sie die zu korrigierenden Dokumente aus der Galerie aus und geben Sie einen Grund an.</p>
|
||||
|
||||
@@ -54,7 +54,7 @@ Vue.component('r-m-l-workorder-company', {
|
||||
</tt-table-crud>
|
||||
</tt-card>
|
||||
|
||||
<tt-modal v-if="rescheduleData" :show="true" title="Termin verschieben" @close="closeRescheduleModal" @submit="rescheduleAppointment">
|
||||
<tt-modal v-if="rescheduleData" :show="true" :delete="false" title="Termin verschieben" @update:show="closeRescheduleModal" @submit="rescheduleAppointment">
|
||||
<p><strong>Auftrag:</strong> #{{ rescheduleData.workorder.id }}</p>
|
||||
<tt-date-picker
|
||||
label="Neuer Termin"
|
||||
@@ -224,7 +224,7 @@ Vue.component('documentation-manager', {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card mt-3" v-if="['assigned', 'scheduled', 'correction_requested'].includes(workorder.status)">
|
||||
<div class="card mt-3" v-if="['assigned', 'scheduled', 'correction_requested', 'problem_solved'].includes(workorder.status)">
|
||||
<div class="card-header bg-danger text-white"><h5><i class="fas fa-hard-hat mr-2"></i>Eingriff benötigt</h5></div>
|
||||
<div class="card-body">
|
||||
<p class="small text-muted">Falls ein Problem auftritt, das ein Eingreifen erfordert, melden Sie es hier.</p>
|
||||
@@ -297,15 +297,20 @@ Vue.component('documentation-manager', {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<tt-modal v-if="interventionData" :show="true" title="Eingriff anfordern" @close="interventionData = null" @submit="requestIntervention">
|
||||
<tt-modal v-if="interventionData" :show="true" :delete="false" title="Eingriff anfordern" @update:show="interventionData = null" @submit="requestIntervention">
|
||||
<tt-select
|
||||
label="Art des Problems"
|
||||
:options="[{value: 'stuck', text: 'Ab X Laufmeter stecken geblieben'}, {value: 'no_air', text: 'Keine Luftverbindung'}, {value: 'other', text: 'Sonstiges'}]"
|
||||
:options="[
|
||||
{value: 'stuck', text: 'Ab X Laufmeter stecken geblieben'},
|
||||
{value: 'stuck_fcp', text: 'Vom FCP nach HÜP nach X Laufmetern stecken geblieben'},
|
||||
{value: 'stuck_hup', text: 'Vom HÜP nach FCP nach X Laufmetern stecken geblieben'},
|
||||
{value: 'no_air', text: 'Keine Luftverbindung'},
|
||||
{value: 'other', text: 'Sonstiges'}]"
|
||||
v-model="interventionData.type"
|
||||
sm
|
||||
row
|
||||
/>
|
||||
<tt-input v-if="interventionData.type === 'stuck'" label="Distanz (Meter)" type="number" v-model="interventionData.distance" sm row required />
|
||||
<tt-input v-if="['stuck', 'stuck_fcp', 'stuck_hup'].includes(interventionData.type)" label="Distanz (Meter)" type="number" v-model="interventionData.distance" sm row required />
|
||||
<tt-textarea v-if="interventionData.type === 'other'" label="Grund" v-model="interventionData.otherReason" sm row required />
|
||||
</tt-modal>
|
||||
</div>
|
||||
@@ -505,7 +510,13 @@ Vue.component('documentation-manager', {
|
||||
if (type === 'stuck') {
|
||||
if (!distance || isNaN(distance)) return window.notify('error', 'Bitte eine gültige Distanz eingeben.');
|
||||
journalText = `Ab ${distance} Laufmeter stecken geblieben.`;
|
||||
} else if (type === 'no_air') {
|
||||
} else if (type === 'stuck_fcp') {
|
||||
if (!distance || isNaN(distance)) return window.notify('error', 'Bitte eine gültige Distanz eingeben.');
|
||||
journalText = `Vom FCP nach HÜP nach ${distance} Laufmetern stecken geblieben.`;
|
||||
} else if (type === 'stuck_hup') {
|
||||
if (!distance || isNaN(distance)) return window.notify('error', 'Bitte eine gültige Distanz eingeben.');
|
||||
journalText = `Vom HÜP nach FCP nach ${distance} Laufmetern stecken geblieben.`;
|
||||
} else if (type === 'no_air') {
|
||||
journalText = 'Keine Luftverbindung.';
|
||||
} else if (type === 'other') {
|
||||
if (!otherReason.trim()) return window.notify('error', 'Bitte geben Sie einen Grund an.');
|
||||
|
||||
Reference in New Issue
Block a user