select([ 'work_permit_documents.id', 'work_permit_documents.name_surname', 'work_permit_documents.company', 'work_permit_documents.certificates_number', 'work_permit_documents.duty', 'work_permit_documents.document_number', 'work_permit_documents.attorney', 'work_permit_documents.attorney_date', 'work_permit_documents.zone as project', 'work_permit_documents.sign_order as personnel_sign_order', 'subcontractors.company_name_ru', 'subcontractors.company_name_en', 'subcontractors.job_description', 'subcontractors.company_code', 'subcontractors.operation_type', 'subcontractors.city', 'subcontractors.address', 'subcontractors.logo', 'subcontractors.sign_order as company_sign_order' ]) ->join("subcontractors", "work_permit_documents.company", "subcontractors.company_name_ru") ->orderBy('subcontractors.operation_type') ->orderBy('work_permit_documents.sign_order'); // Apply project filter if provided if ($request->has('project') && !empty($request->project)) { $query->where('work_permit_documents.zone', 'LIKE', '%' . $request->project . '%'); } $workPermitUsers = $query->get(); $projectMapping = []; // Parse comma-separated projects and organize foreach ($workPermitUsers as $user) { $projectParts = explode(',', $user->project); foreach ($projectParts as $singleProject) { $singleProject = trim($singleProject); if (empty($singleProject)) continue; if ($request->has('project') && !empty($request->project)) { if (stripos($singleProject, $request->project) === false) { continue; } } if (!isset($projectMapping[$singleProject])) { $projectMapping[$singleProject] = []; } // Avoid duplicates in mapping $found = false; foreach ($projectMapping[$singleProject] as $existingUser) { if ($existingUser->name_surname === $user->name_surname && $existingUser->operation_type === $user->operation_type && $existingUser->personnel_sign_order === $user->personnel_sign_order) { $found = true; break; } } if (!$found) { // Enhance user object with placeholders $user->placeholders = $this->generatePlaceholders($user, $workPermitColumns, $subcontractorColumns); $projectMapping[$singleProject][] = $user; } } } // Group into hiearchy: Project -> Operation Type -> Companies -> Users $response = []; foreach ($projectMapping as $projectName => $users) { $operationGroups = collect($users)->groupBy('operation_type'); $projectData = [ 'project_name' => $projectName, 'operation_types' => [] ]; foreach ($operationGroups as $operationType => $operationGroup) { $companies = []; $byCompany = collect($operationGroup)->groupBy('company_name_ru'); foreach ($byCompany as $companyName => $companyUsers) { $companies[] = [ 'company_name' => $companyName, 'company_sign_order' => $companyUsers->first()->company_sign_order, 'users' => $companyUsers->sortBy('personnel_sign_order')->values()->all() ]; } $projectData['operation_types'][] = [ 'type' => $operationType, 'companies' => $companies ]; } $response[] = $projectData; } // Sort alphabetical by project name usort($response, function($a, $b) { return strcmp($a['project_name'], $b['project_name']); }); return response()->json([ 'status' => 'success', 'data' => $response ]); } catch (\Exception $e) { return response()->json([ 'status' => 'error', 'message' => $e->getMessage() ], 500); } } /** * Generate placeholders for a user */ private function generatePlaceholders($user, $wpColumns, $sbColumns) { $job = $user->job_description ?? ''; $fso = $user->company_sign_order ?? ''; $pso = $user->personnel_sign_order ?? ''; $prefix = "{$job}{$fso}_{$pso}_"; $placeholders = [ 'work_permit' => [], 'subcontractor' => [], 'common' => [ 'name_surname' => "{" . $prefix . "name_surname}", 'company_name' => "{" . $prefix . "company_name}", 'certificate_no' => "{" . $prefix . "certificate_no}", 'duty' => "{" . $prefix . "duty}", ] ]; foreach ($wpColumns as $col) { $placeholders['work_permit'][$col] = "{" . $prefix . $col . "}"; } foreach ($sbColumns as $col) { $placeholders['subcontractor'][$col] = "{" . $prefix . "sub_" . $col . "}"; } return $placeholders; } }