'id', 'text' => 'Auftrag-Nr.'], ['key' => 'preorderInfo', 'text' => 'Kunde / Projekt', 'modal' => false, 'table' => ['sortable' => false, 'filter' => false]], ['key' => 'companyName', 'text' => 'Zuständige Firma', 'modal' => false, 'table' => ['filter' => 'search']], ['key' => 'status', 'text' => 'Status', 'modal' => ['items' => [ ['value' => 'new', 'text' => 'Neu', 'icon' => 'fas fa-star text-primary'], ['value' => 'assigned', 'text' => 'Zugewiesen', 'icon' => 'fas fa-user-check text-info'], ['value' => 'scheduled', 'text' => 'Terminiert', 'icon' => 'fas fa-calendar-check text-warning'], ['value' => 'documented', 'text' => 'Dokumentiert', 'icon' => 'fas fa-file-alt text-success'], ['value' => 'completed', 'text' => 'Abgeschlossen', 'icon' => 'fas fa-check-double text-secondary'], ]], 'table' => ['filter' => 'iconSelect']], ['key' => 'deadlineDate', 'text' => 'Deadline', 'modal' => false, 'table' => ['filter' => 'date']], ['key' => 'appointmentDate', 'text' => 'Termin', 'modal' => false, 'table' => ['filter' => 'date']], ['key' => 'actions', 'text' => 'Aktionen', 'modal' => false, 'table' => ['filter' => false, 'sortable' => false]], ]; protected array $additionalJSVariables = ['RML_ADMIN' => '0', 'COMPANY_ID' => '0']; protected function prepareCrudConfig() { // Assume 'RMLAdmin' is a permission. if ($this->user->can('RMLAdmin')) { $this->additionalJSVariables['RML_ADMIN'] = '1'; } else { // If not an admin, find the user's associated company ID $company = RMLWorkorderCompanyModel::getAll(['addressId' => $this->user->address_id], 1); if ($company) { $this->additionalJSVariables['COMPANY_ID'] = $company[0]->id; } else { // If user is not an RML admin and not linked to a company, they see nothing. $this->sendError('Access Denied. You are not associated with a registered RML company.', 403); } } } protected function getAction() { // First, automatically create workorders for any new preorders with status 220. // In a production environment, this might be a separate cron job. $this->createWorkordersFromPreorders(); $json = json_decode(file_get_contents('php://input'), true); $pagination = $json['pagination'] ?? ['page' => 1, 'per_page' => 10]; $filters = $json['filters'] ?? []; $order = $json['order'] ?? ['key' => 'id', 'order' => 'DESC']; // If user is a company, filter by their companyId if ($this->user->can('RMLAdmin') === false) { $company = RMLWorkorderCompanyModel::getAll(['addressId' => $this->user->address_id], 1); if($company) { $filters['companyId'] = $company[0]->id; } } $workorders = RMLWorkorderModel::getAll($filters, $pagination['per_page'], ($pagination['page'] - 1) * $pagination['per_page'], $order); $totalCount = RMLWorkorderModel::count($filters); // Enhance rows with data from other tables $rows = []; foreach($workorders as $workorder) { $row = (array)$workorder; $preorder = new Preorder($workorder->preorderId); // Placeholder for actual Preorder retrieval $anschlussadresse = ''; if ($preorder->building_id) { $anschlussadresse = "{$preorder->building->street}
{$preorder->building->zip} {$preorder->building->city}"; } elseif ($preorder->adb_hausnummer_id) { $anschlussadresse = "{$preorder->adb_hausnummer->strasse->name} {$preorder->adb_hausnummer->hausnummer}"; if ($preorder->adb_hausnummer->stiege) { $anschlussadresse .= "/{$preorder->adb_hausnummer->stiege}"; } if ($preorder->adb_wohneinheit_id && (string)$preorder->adb_wohneinheit) { $anschlussadresse .= "
{$preorder->adb_wohneinheit}"; } $anschlussadresse .= "
{$preorder->adb_hausnummer->plz->plz} {$preorder->adb_hausnummer->ortschaft->name}"; } $kunde = ($preorder->company) ? $preorder->company : "{$preorder->firstname} {$preorder->lastname}"; $kunde .= "
{$preorder->street}"; if ($preorder->housenumber) { $kunde .= " {$preorder->housenumber}"; } $kunde .= "
{$preorder->zip} {$preorder->city}"; $kontakt = ($preorder->phone) ? "{$preorder->phone}
" : ''; $kontakt .= ($preorder->email) ? $preorder->email : ''; $row['preorderInfo'] = "Anschlussadresse: {$anschlussadresse}
" . "Kunde: {$kunde}
" . "Kontakt: {$kontakt}
" . "OAID: {$preorder->oaid}"; // Get Company Name if($workorder->companyId) { $company = RMLWorkorderCompanyModel::get($workorder->companyId); $row['companyName'] = $company->name ?? 'N/A'; } else { $row['companyName'] = 'Nicht zugewiesen'; } $rows[] = $row; } $pagination = [ 'page' => $pagination['page'], 'per_page' => $pagination['per_page'], 'filtered_available' => $totalCount, 'total_rows' => $totalCount, ]; self::returnJson([ 'rows' => $rows, 'pagination' => $pagination ]); } private function createWorkordersFromPreorders() { // Fetch all active preorders where the status code is 220 $newPreorders = PreorderModel::searchActive(['status_code' => 220]); // If no new preorders are found, there's nothing to do if (empty($newPreorders)) { return; } // Iterate through each preorder that needs a workorder foreach ($newPreorders as $preorder) { // Check if a workorder for this preorder already exists to prevent duplicates $existingWorkorder = RMLWorkorderModel::getFirst(['preorderId' => $preorder->id]); // If no workorder exists, create a new one if (!$existingWorkorder) { RMLWorkorderModel::create([ 'preorderId' => $preorder->id, 'status' => 'new', 'create' => time(), 'createBy' => $this->user->id // The logged-in user creating the record ]); } } } protected function assignWorkorderAction() { if (!$this->user->can('RMLAdmin')) self::sendError("Permission denied.", 403); $post = json_decode(file_get_contents('php://input'), true); if (empty($post['workorderId']) || empty($post['companyId'])) { self::sendError("Required fields are missing."); } if (!$rmlWorkorder = RMLWorkorderModel::get($post['workorderId'])) self::sendError("Workorder not found."); RMLWorkorderModel::update( array_merge((array) $rmlWorkorder, [ 'id' => $post['workorderId'], 'companyId' => $post['companyId'], 'status' => 'assigned', 'assignmentDate' => time(), 'deadlineDate' => strtotime('+6 weeks') ]) ); self::returnJson(['success' => true, 'message' => 'Auftrag erfolgreich zugewiesen.']); } protected function scheduleAppointmentAction() { $post = json_decode(file_get_contents('php://input'), true); if (empty($post['workorderId']) || empty($post['appointmentDate'])) { self::sendError("Required fields are missing."); } RMLWorkorderModel::update([ 'id' => $post['workorderId'], 'appointmentDate' => $post['appointmentDate'], 'status' => 'scheduled' ]); self::returnJson(['success' => true, 'message' => 'Termin erfolgreich gespeichert.']); } protected function uploadDocumentationAction() { $file = $_FILES['file'] ?? null; if (!$file || $file['error'] !== UPLOAD_ERR_OK) { self::returnJson(['error' => 'File upload failed']); return; } $workorderId = $_POST['workorderId'] ?? null; $description = $_POST['description'] ?? ''; $documentType = $_POST['documentType'] ?? 'general'; if(!$workorderId) { self::returnJson(['error' => 'Workorder ID is missing.']); return; } try { $uploaded = mfUpload::handleFormUpload("file", false, "/RMLWorkorder"); RMLWorkorderDocumentationModel::create([ 'workorderId' => $workorderId, 'fileId' => $uploaded->id, 'description' => $description, 'documentType' => $documentType, 'create' => time(), 'createBy' => $this->user->id ]); // Set status to 'documented' if it was 'scheduled' or 'assigned' $workorder = RMLWorkorderModel::get($workorderId); if(in_array($workorder->status, ['assigned', 'scheduled'])) { RMLWorkorderModel::update(['id' => $workorderId, 'status' => 'documented']); } self::returnJson(['success' => true, 'fileId' => $uploaded->id, 'fileName' => $file['name']]); } catch (Exception $e) { self::returnJson(['error' => 'Upload error: ' . $e->getMessage()]); } } protected function getDocumentationAction() { if(empty($this->request->workorderId)) self::sendError("Workorder ID missing."); $docs = RMLWorkorderDocumentationModel::getAll(['workorderId' => $this->request->workorderId]); // Enhance with file names foreach($docs as $doc) { $file = new File($doc->fileId); $doc->fileName = $file->filename; } self::returnJson($docs); } protected function completeWorkorderAction() { $post = json_decode(file_get_contents('php://input'), true); if(empty($post['workorderId'])) self::sendError("Workorder ID missing."); $workorder = RMLWorkorderModel::get($post['workorderId']); if(!$workorder) self::sendError("Workorder not found."); // Update Preorder status to 245 // PreorderModel::update(['id' => $workorder->preorderId, 'status_code' => 245]); // Update Workorder status RMLWorkorderModel::update([ 'id' => $workorder->id, 'status' => 'completed' ]); self::returnJson(['success' => true, 'message' => 'Auftrag abgeschlossen. Preorder wurde aktualisiert.']); } // Action to get companies for the assignment modal protected function getCompaniesAction() { if(!$this->user->can('RMLAdmin')) self::sendError("Permission denied.", 403); $companies = RMLWorkorderCompanyModel::getAll(); $items = array_map(fn($c) => ['value' => $c->id, 'text' => $c->name], $companies); self::returnJson($items); } }