From a3a2dee71d997d7ee84adb35846a83528ed314bd Mon Sep 17 00:00:00 2001 From: wahyuun Date: Tue, 15 Aug 2023 17:11:44 +0700 Subject: [PATCH] clean code --- .../API/ActivityDokumenController.php | 97 ++- .../Controllers/API/ProjectController.php | 597 +++++++++++++++++- .../API/ProjectDokumenController.php | 106 +++- app/Http/Controllers/API/RoleController.php | 107 +++- app/Models/AssignMaterial.php | 44 +- app/Models/Menu.php | 7 +- app/Models/Project.php | 47 +- app/Models/UserToActivity.php | 67 +- routes/api.php | 1 + 9 files changed, 954 insertions(+), 119 deletions(-) diff --git a/app/Http/Controllers/API/ActivityDokumenController.php b/app/Http/Controllers/API/ActivityDokumenController.php index 09af47f..2086364 100644 --- a/app/Http/Controllers/API/ActivityDokumenController.php +++ b/app/Http/Controllers/API/ActivityDokumenController.php @@ -4,8 +4,103 @@ namespace App\Http\Controllers\API; use App\Http\Controllers\Controller; use Illuminate\Http\Request; +use App\Models\ActivityDokumen; class ActivityDokumenController extends Controller { - // + + public function dokumenByActivityId($id) + { + if (empty($id) || !is_int((int)$id)) { + return response()->json(['status' => 'failed', 'message' => 'activity id is required!', 'code' => 400], 400); + } + + $dataDokumen = ActivityDokumen::where("activity_id", $id)->get(); + return response()->json(['status' => 'success', 'data' => $dataDokumen, 'code' => 200], 200); + } + + public function delete($id) + { + if (empty($id) || !is_int((int)$id)) { + return response()->json(['status' => 'failed', 'message' => 'Id is required!', 'code' => 400], 400); + } + + $document = ActivityDokumen::find($id); + + if (!$document) { + return response()->json(['status' => 'failed', 'message' => 'Data not found!', 'code' => 404], 404); + } + + if (file_exists($this->pathActivityDocument . $document->file)) { + unlink($this->pathActivityDocument . $document->file); + } + + $document->delete(); + return response()->json(['status' => 'success', 'message' => 'Dokumen deleted successfully!', 'code' => 200], 200); + } + + public function uploadProjectDokumen(Request $request) + { + if (!$request->hasFile('dokumen')) { + return response()->json(['status' => 'failed', 'message' => 'file is required!', 'code' => 400], 400); + } + + $activity_id = $request->activity_id; + $document = $request->file('dokumen'); + $name = $document->getClientOriginalName(); + + $result = $document->move($this->pathActivityDocument, $name); + + if (!$result) { + return response()->json(['status' => 'failed', 'message' => 'Upload failed!', 'code' => 500], 500); + } + + $data = [ + 'activity_id' => (int)$activity_id, + 'file' => $name, + 'description' => $request->description + ]; + + $result = ActivityDokumen::create($data); + + if (!$result) { + unlink($this->pathActivityDocument . $name); + return response()->json(['status' => 'failed', 'message' => 'Upload failed!', 'code' => 500], 500); + } + + return response()->json(['status' => 'success', 'message' => 'Upload success!', 'code' => 200], 200); + } + + public function searchDocProject(Request $request) + { + $payload = $request->all(); + + $dataBuilder = $this->setUpPayload($payload, 'm_document_activity'); + $builder = $dataBuilder['builder']; + $countBuilder = $dataBuilder['count']; + $dataGet = $builder->get(); + $totalRecord = $countBuilder->count(); + + return response()->json(['status' => 'success', 'code' => 200, 'data' => $dataGet, 'totalRecord' => $totalRecord], 200); + } + + public function downloadDokumen($id) + { + if (empty($id) || !is_int((int)$id)) { + return response()->json(['status' => 'failed', 'message' => 'Id is required!', 'code' => 400], 400); + } + + $document = ActivityDokumen::find($id); + + if (!$document) { + return response()->json(['status' => 'failed', 'message' => 'Data not found!', 'code' => 400], 400); + } + + if (file_exists($this->pathActivityDocument . $document->file)) { + $pathToFile = $this->pathActivityDocument . $document->file; + return response()->download($pathToFile); + } + + return response()->json(['status' => 'failed', 'message' => 'Data not found!', 'code' => 400], 400); + } } diff --git a/app/Http/Controllers/API/ProjectController.php b/app/Http/Controllers/API/ProjectController.php index df3bb15..7ed779c 100644 --- a/app/Http/Controllers/API/ProjectController.php +++ b/app/Http/Controllers/API/ProjectController.php @@ -3,9 +3,604 @@ namespace App\Http\Controllers\API; use App\Http\Controllers\Controller; + use Illuminate\Http\Request; +use App\Models\{ + Project, + UserToProyek, + Activity, + UserToActivity, + User, + AssignMaterial, + DokumenProject, + FolderDocumentProyek, + ProjectCharter, + ProjectApproval, + ProjectPhase, + ProjectType, + ProjectMileStone, + ProjectParticipants, + ShowHideColumn, + VersionGantt, + Image, + CommentActivity, + Link, + ActivityDokumen, + Holiday, + ReportActivity, + OfficeHours +}; +use Illuminate\Support\Facades\{DB, Artisan, Validator}; +use App\Helpers\MasterFunctionsHelper; +use App\Models\ReportActivityMaterial; + +const API_GEOLOCATION = "https://nominatim.oslogdev.com/search/ADDR?format=json&addressdetails=1&limit=1"; class ProjectController extends Controller { - // + + public function add(Request $request) + { + $validator = Validator::make($request->all(), [ + 'nama' => 'required', + 'mulai_proyek' => 'required', + 'akhir_proyek' => 'required', + 'rencana_biaya' => 'required', + 'type_proyek_id' => 'required', + 'created_by' => '', + 'phase_id' => '' + ]); + + if ($validator->fails()) { + return response()->json(['status' => 'failed', 'message' => 'Failed to add data!', 'code' => 500], 500); + } + + $validated = $validator->validated(); + + $validated['created_by'] = $this->currentName; + if (empty($validated['phase_id'])) { + $validated['phase_id'] = 1; + } + + $result = Project::create($validated); + + if (!$result) { + return response()->json(['status' => 'failed', 'message' => 'Failed to add data!', 'code' => 500], 500); + } + + $this->createOfficeHours($result->id); + $dataResultInsert = Project::where([ + ['nama', $validated['nama']], + ['mulai_proyek', $validated['mulai_proyek']] + ])->first(); + + return response()->json(['status' => 'success', 'message' => 'Data added!', 'data_result' => $dataResultInsert, 'code' => 200], 200); + } + + public function edit($id) + { + if (empty($id) || !is_int((int)$id)) + return response()->json(['status' => 'failed', 'message' => 'id is required!', 'code' => 400], 400); + + $result = Project::find($id); + + if (!$result) + return response()->json(['status' => 'failed', 'message' => 'Data not found!', 'code' => 404], 404); + + return response()->json(['status' => 'success', 'code' => 200, 'data' => $result], 200); + } + + public function update(Request $request, $id) + { + if (empty($id) || !is_int((int)$id)) + return response()->json(['status' => 'failed', 'message' => 'id is required!', 'code' => 400], 400); + + $data = Project::find($id); + + if (!$data) + return response()->json(['status' => 'failed', 'message' => 'Data not found!', 'code' => 404], 404); + + $result = $data->update($request->all()); + + if (!$result) + return response()->json(['status' => 'failed', 'message' => 'Failed to update!', 'code' => 500], 500); + + return response()->json(['status' => 'success', 'message' => 'Data updated!', 'code' => 200], 200); + } + + private function createOfficeHours($proyek_id) + { + $dataCreate = array( + "proyek_id" => $proyek_id, + "monday_start" => "08:00:00", + "monday_end" => "16:00:00", + "tuesday_start" => "08:00:00", + "tuesday_end" => "16:00:00", + "wednesday_start" => "08:00:00", + "wednesday_end" => "16:00:00", + "thursday_start" => "08:00:00", + "thursday_end" => "16:00:00", + "friday_start" => "08:00:00", + "friday_end" => "16:00:00", + "saturday_start" => "08:00:00", + "saturday_end" => "16:00:00", + "sunday_start" => "08:00:00", + "sunday_end" => "16:00:00", + "created_by" => $this->currentName + ); + + OfficeHours::create($dataCreate); + + return true; + } + + public function delete($id) + { + $data = Project::find($id); + + if (!$data) { + return response()->json(['status' => 'failed', 'message' => 'Data not found!', 'code' => 404], 404); + } + + $this->deleteRelative($id); + + if (!$data->delete()) { + return response()->json(['status' => 'failed', 'message' => 'Delete failed!', 'code' => 500], 500); + } + + return response()->json(['status' => 'success', 'message' => 'Data deleted!', 'code' => 200], 200); + } + + private function deleteRelative($project_id) + { + UserToProyek::where('proyek_id', $project_id)->delete(); + UserToActivity::where('proyek_id', $project_id)->delete(); + AssignMaterial::where('proyek_id', $project_id)->delete(); + ProjectCharter::where('proyek_id', $project_id)->delete(); + ProjectApproval::where('proyek_id', $project_id)->delete(); + ProjectMileStone::where('proyek_id', $project_id)->delete(); + ProjectParticipants::where('proyek_id', $project_id)->delete(); + $this->deleteVersionGantt($project_id); + $this->deleteDokumenProject($project_id); + } + + private function deleteVersionGantt($project_id) + { + $dataVg = VersionGantt::where("proyek_id", $project_id)->pluck("id"); + $vhIds = $dataVg->all(); + $activity = Activity::whereIn("version_gantt_id", $vhIds)->pluck('id'); + $activityIds = $activity->all(); + $dataRa = ReportActivity::whereIn("activity_id", $activityIds)->get(); + foreach ($dataRa as $ra) { + $images = Image::where("ref_id", $ra->id)->where("category", "report_activity")->get(); + foreach ($images as $image) { + if (file_exists($this->pathImage . $image->image)) { + unlink($this->pathImage . $image->image); + } + } + Image::where("ref_id", $ra->id)->where("category", "report_activity")->delete(); + } + $dataAd = ActivityDokumen::whereIn("activity_id", $activityIds)->get(); + foreach ($dataAd as $ad) { + if (file_exists($this->pathActivityDocument . $ad->file)) { + unlink($this->pathActivityDocument . $ad->file); + } + } + ActivityDokumen::whereIn("activity_id", $activityIds)->delete(); + CommentActivity::whereIn("activity_id", $activityIds)->delete(); + Holiday::where("proyek_id", $project_id)->delete(); + VersionGantt::where("proyek_id", $project_id)->delete(); + Link::whereIn("version_gantt_id", $vhIds)->delete(); + ShowHideColumn::whereIn("version_gantt_id", $vhIds)->delete(); + Activity::whereIn("version_gantt_id", $vhIds)->delete(); + ReportActivity::whereIn("activity_id", $activityIds)->delete(); + } + + private function deleteDokumenProject($project_id) + { + $dataDokumen = DokumenProject::where([ + ["type_dokumen", "project-document-out-folder"], + ['ref_id', $project_id] + ])->get(); + + foreach ($dataDokumen as $dokumen) { + if (file_exists($this->pathDocument . $dokumen->file)) { + unlink($this->pathDocument . $dokumen->file); + } + } + DokumenProject::where([ + ["type_dokumen", "project-document-out-folder"], + ['ref_id', $project_id] + ])->delete(); + + $dataFolder = FolderDocumentProyek::where('proyek_id', $project_id)->pluck("id"); + $ref_ids = $dataFolder->all(); + $dataDokumen = DokumenProject::where("type_dokumen", "project-document-in-folder")->whereIn('ref_id', $ref_ids)->get(); + foreach ($dataDokumen as $dokumen) { + if (file_exists($this->pathDocument . $dokumen->file)) { + unlink($this->pathDocument . $dokumen->file); + } + } + + DokumenProject::where("type_dokumen", "project-document-in-folder")->whereIn('ref_id', $ref_ids)->delete(); + } + + public function search(Request $request) + { + $payload = $request->all(); + + $dataBuilder = $this->setUpPayload($payload, 'm_proyek'); + $builder = $dataBuilder['builder']; + $countBuilder = $dataBuilder['count']; + $dataGet = $builder->get(); + $totalRecord = $countBuilder->count(); + + return response()->json(['status' => 'success', 'code' => 200, 'data' => $dataGet, 'totalRecord' => $totalRecord], 200); + } + + public function list() + { + $data = Project::orderByDesc('id')->get(); + $countData = $data->count(); + + if (!$data) { + return response()->json(['status' => 'failed', 'message' => 'Data not found!', 'code' => 404], 404); + } + + $scheduleWarningThreshold = 10; + $scheduleDangerThreshold = 5; + foreach ($data as $d) { + $progress = $costVariance = $actualCost = 0; + $lastActivity = null; + $scheduleHealth = "on-track"; + $rootActivity = Activity::whereNull('parent_id')->where('proyek_id', $d->id)->orderByDesc('version_gantt_id')->first(); + if ($rootActivity) { + $costVariance = (int)$d->rencana_biaya - (int)$rootActivity->biaya_actual; + $actualCost = $rootActivity->biaya_actual ?? 0; + $progress = $rootActivity->persentase_progress ?? 0; + + $timeleft = strtotime($d->mulai_proyek) - strtotime($rootActivity->end_date); + $date1 = new \DateTime(date("Y-m-d", strtotime($d->mulai_proyek))); + $date2 = new \DateTime(date("Y-m-d", strtotime($rootActivity->end_date))); + $daysRemaining = $date2->diff($date1); + $daysRemaining = $daysRemaining->d; + + if ($daysRemaining <= $scheduleDangerThreshold) { + $scheduleHealth = "danger"; + } elseif ($daysRemaining <= $scheduleWarningThreshold) { + $scheduleHealth = "warning"; + } + $lastActivity = date("d/m/Y", strtotime($rootActivity->end_date)); + } + $d->plannedInterval = date("d/m/Y", strtotime($d->mulai_proyek)) . " - " . date("d/m/Y", strtotime($d->akhir_proyek)); + $d->plannedCost = $d->rencana_biaya; + $d->actualCost = $actualCost; + $d->lastActivity = $lastActivity ?? "-"; + $d->costVariance = $costVariance; + $d->costHealth = $d->budget_health; + $d->scheduleHealth = $scheduleHealth; + $d->progress = $progress; + $d->lastGanttId = VersionGantt::where("proyek_id", $d->id)->orderByDesc('id')->first()->id ?? null; + $d->manpower = UserToProyek::where("proyek_id", $d->id)->count() ?? 0; + $d->projectManager = Project::query() + ->join('m_users', 'm_users.id', '=', 'm_proyek.pm_id') + ->where('m_proyek.id', $d->id) + ->pluck('m_users.name') + ->first(); + if ($d->area_kerja != '') { + $d->geolocation = $this->httpReq($d->area_kerja); + $d->geolocation = []; + } else { + $d->geolocation = []; + } + } + + $totalPlannedCost = array_sum(array_map('intval', array_column($data->toArray(), 'plannedCost'))); + $totalActualCost = $data->sum('actualCost'); + $manpowers = User::count(); + $projectsOnDanger = Project::where('budget_health', 'overrun')->count(); + $projectPhases = ProjectPhase::orderBy('order', 'asc')->pluck('name'); + $projectTypes = ProjectType::orderBy('id', 'asc')->pluck('name'); + try { + $projectsByPhase = Project::query() + ->selectRaw('m_proyek_phase.name, m_proyek_phase.color, COUNT(*) as total') + ->join('m_proyek_phase', 'm_proyek_phase.id', '=', 'm_proyek.phase_id') + ->groupBy('m_proyek_phase.name', 'm_proyek_phase.color') + ->get(); + } catch (\Exception $e) { + return response()->json(['message' => $e->getMessage()]); + } + try { + $projectsByType = Project::query() + ->selectRaw('m_type_proyek.name, COUNT(*) as total') + ->join('m_type_proyek', 'm_type_proyek.id', '=', 'm_proyek.type_proyek_id') + ->groupBy('m_type_proyek.name') + ->get(); + } catch (\Exception $e) { + return response()->json(['message' => $e->getMessage()]); + } + + return response()->json( + [ + 'status' => 'success', + 'code' => 200, + 'data' => $data, + 'totalRecord' => $countData, + 'totalPlannedCost' => $totalPlannedCost, + 'totalActualCost' => $totalActualCost, + 'totalRevenue' => $totalPlannedCost - $totalActualCost, + 'manpowers' => $manpowers, + 'projectsOnDanger' => $projectsOnDanger, + 'projectPhases' => $projectPhases, + 'projectsByPhase' => $projectsByPhase, + 'projectTypes' => $projectTypes, + 'projectsByType' => $projectsByType, + ], + 200 + ); + } + + public function getListProjectTask($id) + { + $data = UserToActivity::select("assign_hr_to_activity.user_id as user_id", "m_proyek.*") + ->where("assign_hr_to_activity.user_id", $id) + ->join('m_proyek', 'assign_hr_to_activity.proyek_id', '=', 'm_proyek.id') + ->groupBy("m_proyek.proyek_id") + ->get(); + + if ($data->isNotEmpty()) : + return response()->json(['status' => 'success', 'code' => 200, 'data' => $data], 200); + else : + return response()->json(['status' => 'failed', 'message' => 'Data not found!', 'code' => 404], 404); + endif; + } + + public function getSCurve(Request $request) + { + $data = MasterFunctionsHelper::getSCurve($request); + return response()->json(['status' => 'success', 'code' => 200, 'data' => $data], 200); + } + + public function calculateSCurve(Request $request) + { + $sCurve = Project::select('scurve')->where('id', $request->project_id)->first(); + return response()->json(['status' => 'success', 'code' => 200, 'data' => json_decode($sCurve->scurve)], 200); + } + + public function sCurveCommand(Request $request) + { + Artisan::call('calculate:scurve', [ + 'project_id' => $request->project_id + ]); + } + + public function getLinearSCurve(Request $request) + { + $data = MasterFunctionsHelper::getLinearSCurve($request); + return response()->json(['status' => 'success', 'code' => 200, 'data' => $data], 200); + } + + public function synchronizeReport($gantt_id) + { + $activities = Activity::where("version_gantt_id", $gantt_id)->get(); + $reports = []; + + foreach ($activities as $activity) { + $activity_id = $activity->id; + $countReports = ReportActivityMaterial::where('activity_id', $activity_id)->count(); + if ($countReports === 1) { + $dataReports = ReportActivityMaterial::where('activity_id', $activity_id)->orderBy('report_date')->get(); + foreach ($dataReports as $dr) { + $reports[] = array( + 'activity_id' => $activity_id, + 'min_date' => $dr->report_date, + 'max_date' => date_modify(date_create($dr->report_date), "1 days") + ); + } + } + if ($countReports > 1) { + $firstReport = ReportActivityMaterial::where('activity_id', $activity_id)->orderBy('report_date')->first(); + $lastReport = ReportActivityMaterial::where('activity_id', $activity_id)->orderByDesc('report_date')->first(); + $reports[] = array( + 'activity_id' => $activity_id, + 'min_date' => $firstReport->report_date, + 'max_date' => date_modify(date_create($lastReport->report_date), "1 days") + ); + } + $activity->reports = $reports; + } + + for ($i = 0; $i < count($reports); $i++) { + $activity = Activity::find($reports[$i]['activity_id']); + $activity->start_date = $reports[$i]['min_date']; + $activity->end_date = $reports[$i]['max_date']; + $activity->save(); + } + + return response()->json(['status' => 'success', 'message' => 'Synchronize to report success!', 'code' => 200], 200); + } + + public function setBaseline($gantt_id) + { + $activities = Activity::where("version_gantt_id", $gantt_id)->get(); + + foreach ($activities as $activity) { + $activity->update([ + "planned_start" => $activity->start_date, + "planned_end" => $activity->end_date, + ]); + } + + return response()->json(['status' => 'success', 'message' => 'Set baseline success!', 'code' => 200], 200); + } + + public function getInvoiceIntegration(Request $request) + { + // $search = urlencode($request->search); + // if(empty($search)) + // return response()->json(['status'=>'error', 'message'=>'Empty query string!'], 400); + // $url = str_replace("SEARCH", $search, config('api.adw').'/project_cost?project_no=SEARCH'); + + $response = null; + + // return response()->json(['status'=>'success', 'data'=> $response, 'code'=>200], 200); + return response()->json(['status' => 'success', 'data' => '', 'code' => 200], 200); + } + + public function detail($id) + { + if (empty($id) || !is_int((int)$id)) { + return response()->json(['status' => 'failed', 'message' => 'id is required!', 'code' => 400], 400); + } + + $result = Project::find($id); + + if (empty($result)) { + return response()->json(['status' => 'failed', 'message' => 'Data not found!', 'code' => 404], 404); + } + + $gantt = MasterFunctionsHelper::getLatestGantt($id); + $result->projectManager = User::where('id', $result->pm_id)->value('name'); + $result->header = Activity::whereNull('parent_id')->where("proyek_id", $id)->where("version_gantt_id", $gantt['last_gantt_id'])->first(); + return response()->json(['status' => 'success', 'code' => 200, 'data' => $result, 'gantt' => $gantt], 200); + } + + public function getOverdueActivities(Request $request) + { + $payload = $request->all(); + if (empty($payload['id']) || !is_int((int)$payload['id'])) { + return response()->json(['status' => 'failed', 'message' => 'id is required!', 'code' => 400], 400); + } + + $result = Project::find($payload['id']); + + if (!$result) { + return response()->json(['status' => 'failed', 'message' => 'Project not found!', 'code' => 404], 404); + } + //TODO possible overdue bug + if (isset($payload['till_date'])) : + $overdueActivities = Activity::where('proyek_id', $payload['id'])->whereNotNull('parent_id')->where('persentase_progress', '!=', 100)->whereDate('end_date', '<=', $payload['till_date'])->orderBy('end_date', 'asc')->get(); + else : + $overdueActivities = Activity::where('proyek_id', $payload['id'])->whereNotNull('parent_id')->where('persentase_progress', '!=', 100)->orderBy('end_date', 'asc')->get(); + endif; + + $result->overdueActivities = $overdueActivities; + + return response()->json(['status' => 'success', 'code' => 200, 'data' => $result], 200); + } + + public function getReportDistribution(Request $request) + { + $payload = $request->all(); + + if (empty($payload['project_id']) || !is_int((int)$payload['project_id'])) { + return response()->json(['status' => 'failed', 'message' => 'id is required!', 'code' => 400], 400); + } + + $reports = DB::table('assign_material_to_activity as ama') + ->select( + 'u.name', + 'a.name as activity_name', + 'ama.qty_planning', + 'ram.qty as qty_real', + 'rm.description as material_name', + 'rm.uom as material_unit', + 'ram.lat', + 'ram.lon', + 'ram.description as report_notes', + 'ram.report_date' + ) + ->join('report_activity_material as ram', 'ram.assign_material_id', '=', 'ama.id') + ->join('m_req_material as rm', 'rm.id', '=', 'ama.material_id') + ->join('m_activity as a', 'a.id', '=', 'ama.activity_id') + ->join('m_users as u', 'u.id', '=', 'ram.user_id') + ->where('ama.proyek_id', '=', $payload['project_id']) + ->whereNotNull('ram.lat') + ->whereBetween('ram.report_date', [$payload['start_date'], $payload['end_date']]); + + return response()->json(['status' => 'success', 'code' => 200, 'data' => $reports], 200); + } + + public function getManpower($proyek_id) + { + $manCount = UserToProyek::where('proyek_id', $proyek_id)->count(); + return response()->json(['totalRecord' => $manCount]); + } + + public function getAssignedHR($gantt_id) + { + $results = UserToActivity::select('assign_hr_to_activity.proyek_id', 'assign_hr_to_activity.user_id', 'm_activity.id', 'm_activity.name', 'm_activity.start_date', 'm_activity.end_date') + ->join('m_activity', 'm_activity.id', '=', 'assign_hr_to_activity.activity_id') + ->where('assign_hr_to_activity.version_gantt_id', $gantt_id) + ->get(); + return response()->json(['data' => $results]); + } + + public function dashboard($id) + { + $data = DB::table('m_proyek as mp') + ->select( + 'mp.kode_sortname', + 'mp.nama as name_project', + 'mp.mulai_proyek as start', + 'mp.akhir_proyek as finish', + 'mp.rencana_biaya', + 'mp.company', + 'mp.currency_symbol', + 'mu.name as pm', + 'mp.budget_health' + ) + ->join('m_users as mu', 'mu.id', '=', 'mp.pm_id') + ->where('mp.id', $id) + ->first(); + + if (!$data) { + return response()->json(['status' => 'failed', 'message' => 'Data tidak ditemukan!', 'code' => 404], 404); + } + + $manpowers = UserToProyek::where('proyek_id', $id)->count(); + $rootActivity = Activity::whereNull('parent_id')->where('proyek_id', $id)->orderByDesc('version_gantt_id')->first(); + + $actualCost = $rootActivity->biaya_actual ?? 0; + $progress = $rootActivity->persentase_progress ?? 0; + + $commentActivity = DB::table('m_comment_activity as mca') + ->select( + 'mca.activity_id', + 'mca.comment as comment', + 'mca.created_by as comment_by', + 'mca.created_at as comment_created', + 'ma.name as activity' + ) + ->join('m_activity as ma', 'ma.id', '=', 'mca.activity_id') + ->where('ma.proyek_id', $id) + ->orderBy('comment_by') + ->take(2) + ->get(); + + $data->actual_cost = $actualCost; + $data->progress = $progress; + $data->comment = $commentActivity; + $data->man_power = $manpowers; + + return response()->json(['status' => 'success', 'code' => 200, 'data' => $data], 200); + } + + private function httpReq($search) + { + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, str_replace("ADDR", $search, API_GEOLOCATION)); + + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_VERBOSE, true); + curl_setopt($ch, CURLOPT_STDERR, fopen('php://stderr', 'w')); + + $info = curl_getinfo($ch); + + $output = curl_exec($ch); + curl_close($ch); + + return json_decode($output); + } } diff --git a/app/Http/Controllers/API/ProjectDokumenController.php b/app/Http/Controllers/API/ProjectDokumenController.php index 9bd3d8f..b61fd92 100644 --- a/app/Http/Controllers/API/ProjectDokumenController.php +++ b/app/Http/Controllers/API/ProjectDokumenController.php @@ -4,8 +4,112 @@ namespace App\Http\Controllers\API; use App\Http\Controllers\Controller; use Illuminate\Http\Request; +use App\Models\DokumenProject; class ProjectDokumenController extends Controller { - // + public function dokumenByProyekId($id) + { + if (empty($id) || !is_int((int)$id)) { + return response()->json(['status' => 'failed', 'message' => 'project id is required!', 'code' => 400], 400); + } + + $document = DokumenProject::where("ref_id", $id)->get(); + + if (empty($document)) { + return response()->json(['status' => '', 'message' => 'Data not found!', 'code' => 404], 404); + } else { + return response()->json(['status' => 'success', 'data' => $document, 'code' => 200], 200); + } + } + + public function delete($id) + { + if (empty($id) || !is_int((int)$id)) { + return response()->json(['status' => 'failed', 'message' => 'id is required!', 'code' => 400], 400); + } + + $document = DokumenProject::find($id); + if (!$document) { + return response()->json(['status' => 'failed', 'message' => 'Data not found!', 'code' => 400], 400); + } + + if (file_exists($this->pathDocument . $document->file)) { + unlink($this->pathDocument . $document->file); + } + + $document->delete(); + + return response()->json(['status' => 'success', 'message' => 'Data deleted!', 'code' => 200], 200); + } + + public function uploadProjectDokumen(Request $request) + { + if ($request->hasFile('dokumen')) { + $request->validate([ + 'dokumen' => 'mimes:png,jpg,pdf,jpeg,gif' + ]); + + $document = $request->file('dokumen'); + $ref_id = $request->ref_id; + $name = $document->getClientOriginalName(); + + $result = $document->move($this->pathDocument, $name); + if ($result) { + $data = [ + 'ref_id' => (int)$ref_id, + 'file' => $name, + 'type_dokumen' => isset($request->type_dokumen) ? $request->type_dokumen : 'project-document' + ]; + + $result = DokumenProject::create($data); + + if (!$result) { + unlink($this->pathDocument . $name); + return response()->json(['status' => 'failed', 'message' => 'Upload failed!', 'code' => 500], 500); + } + return response()->json(['status' => 'success', 'message' => 'Upload successful!', 'code' => 200], 200); + } + return response()->json(['status' => 'failed', 'message' => 'Upload failed!', 'code' => 500], 500); + } + return response()->json(['status' => 'failed', 'message' => 'File is required!', 'code' => 400], 400); + } + + public function searchDocProject(Request $request) + { + $payload = $request->all(); + + $dataBuilder = $this->setUpPayload($payload, 'document_project'); + $builder = $dataBuilder['builder']; + $countBuilder = $dataBuilder['count']; + $dataGet = $builder->get(); + $totalRecord = $countBuilder->count(); + + return response()->json(['status' => 'success', 'code' => 200, 'data' => $dataGet, 'totalRecord' => $totalRecord], 200); + } + + public function downloadDokumen($id) + { + if (empty($id) || !is_int((int)$id)) { + return response()->json(['status' => 'failed', 'message' => 'Id is required!', 'code' => 400], 400); + } + + $document = DokumenProject::find($id); + + if (!$document) { + return response()->json(['status' => 'failed', 'message' => 'Data not found!', 'code' => 404], 404); + } + + if (!file_exists($this->pathDocument . $document->file)) { + return response()->json(['status' => 'failed', 'message' => 'Data not found!', 'code' => 404], 404); + } + + $pathToFile = $this->pathDocument . $document->file; + $name = pathinfo($pathToFile, PATHINFO_FILENAME) . "." . pathinfo($pathToFile, PATHINFO_EXTENSION); + $headers = [ + 'Content-Disposition' => 'attachment; filename="' . $name . '"' + ]; + + return response()->download($pathToFile, $name, $headers); + } } diff --git a/app/Http/Controllers/API/RoleController.php b/app/Http/Controllers/API/RoleController.php index 544edfb..fa077ae 100644 --- a/app/Http/Controllers/API/RoleController.php +++ b/app/Http/Controllers/API/RoleController.php @@ -4,8 +4,113 @@ namespace App\Http\Controllers\API; use App\Http\Controllers\Controller; use Illuminate\Http\Request; +use App\Models\Role; +use Illuminate\Support\Facades\Validator; class RoleController extends Controller { - // + + public function add(Request $request) + { + $validator = Validator::make($request->all(), [ + 'name' => 'required', + 'description' => 'required', + 'created_by' => '' + ]); + + if ($validator->fails()) { + return response()->json(['status' => 'failed', 'message' => 'Failed to add data!', 'code' => 500], 500); + } + + $validated = $validator->validated(); + $validated['created_by'] = $this->currentName; + + Role::create($validated); + return response()->json(['status' => 'success', 'message' => 'Data added!', 'code' => 200], 200); + } + + public function edit($id) + { + if (empty($id) || !is_int((int)$id)) { + return response()->json(['status' => 'failed', 'message' => 'id is required!', 'code' => 400], 400); + } + + $result = Role::find($id); + + if (!$result) { + return response()->json(['status' => 'failed', 'message' => 'Data not found!', 'code' => 404], 404); + } else { + return response()->json(['status' => 'success', 'code' => 200, 'data' => $result], 200); + } + } + + public function update(Request $request, $id) + { + if (empty($id) || !is_int((int)$id)) { + return response()->json(['status' => 'failed', 'message' => 'id is required!', 'code' => 400], 400); + } + + $data = Role::find($id); + $validated = $request->validate([ + 'name' => 'required', + 'description' => 'required' + ]); + + if (!$data) { + return response()->json(['status' => 'failed', 'message' => 'Data not found!', 'code' => 404], 404); + } + + $result = $data->update($validated); + + if (!$result) { + return response()->json(['status' => 'failed', 'message' => 'Failed to update the data!', 'code' => 500], 500); + } else { + return response()->json(['status' => 'success', 'message' => 'Data updated!', 'code' => 200], 200); + } + } + + public function delete($id) + { + if (empty($id) || !is_int((int)$id)) { + return response()->json(['status' => 'failed', 'message' => 'id is required!', 'code' => 400], 400); + } + + $data = Role::find($id); + + if (!$data) { + return response()->json(['status' => 'failed', 'message' => 'Data not found!', 'code' => 404], 404); + } + + $delete = $data->delete(); + + if (!$delete) { + return response()->json(['status' => 'failed', 'message' => 'Failed to delete!', 'code' => 500], 500); + } else { + return response()->json(['status' => 'success', 'message' => 'Data deleted!', 'code' => 200], 200); + } + } + + public function search(Request $request) + { + $payload = $request->all(); + + $dataBuilder = $this->setUpPayload($payload, 'm_roles'); + $builder = $dataBuilder['builder']; + $countBuilder = $dataBuilder['count']; + $dataGet = $builder->get(); + $totalRecord = $countBuilder->count(); + + return response()->json(['status' => 'success', 'code' => 200, 'data' => $dataGet, 'totalRecord' => $totalRecord], 200); + } + + public function list() + { + $countData = Role::count(); + + if (empty($countData)) { + return response()->json(['status' => 'failed', 'message' => 'failed get list role, please try again later!', 'code' => 400], 400); + } else { + return response()->json(['status' => 'success', 'code' => 200, 'data' => $data, 'totalRecord' => $countData], 200); + } + } } diff --git a/app/Models/AssignMaterial.php b/app/Models/AssignMaterial.php index f821302..d8935e4 100644 --- a/app/Models/AssignMaterial.php +++ b/app/Models/AssignMaterial.php @@ -8,37 +8,31 @@ use App\Models\Activity; class AssignMaterial extends Model { - protected $table = 'assign_material_to_activity'; + protected $table = 'assign_material_to_activity', $guarded = ['id']; const CREATED_AT = 'created_at'; const UPDATED_AT = 'updated_at'; - protected $fillable = [ - 'proyek_id', 'activity_id', 'material_id', 'qty_planning', - 'budget', 'plan_date', 'status_activity', 'type', - 'created_at', 'created_by', 'updated_at', 'updated_by' - ]; - - protected $casts = [ + protected $casts = [ 'id' => 'integer', 'budget' => 'string', ]; - public static function boot() { - parent::boot(); - - static::created(function($data) { - $activity = Activity::find($data->activity_id); - $material = RequestMaterial::where("id", $data->material_id)->first(); - $activity->rencana_biaya += floatval($material->price) * floatval($data->qty_planning); - $activity->save(); - }); - - static::deleted(function($data) { - $activity = Activity::where('id', $data->activity_id)->first(); - $activity->rencana_biaya -= floatval($data->budget) * floatval($data->qty_planning); - $activity->save(); - }); - - } + public static function boot() + { + parent::boot(); + + static::created(function ($data) { + $activity = Activity::find($data->activity_id); + $material = RequestMaterial::where("id", $data->material_id)->first(); + $activity->rencana_biaya += floatval($material->price) * floatval($data->qty_planning); + $activity->save(); + }); + + static::deleted(function ($data) { + $activity = Activity::where('id', $data->activity_id)->first(); + $activity->rencana_biaya -= floatval($data->budget) * floatval($data->qty_planning); + $activity->save(); + }); + } } diff --git a/app/Models/Menu.php b/app/Models/Menu.php index ca70232..db4bb4e 100644 --- a/app/Models/Menu.php +++ b/app/Models/Menu.php @@ -6,13 +6,8 @@ use Illuminate\Database\Eloquent\Model; class Menu extends Model { - protected $table = 'm_menu'; + protected $table = 'm_menu', $guarded = ['id']; const CREATED_AT = 'created_at'; const UPDATED_AT = 'updated_at'; - - protected $fillable = [ - 'parent_id', 'icon', 'name', 'alias_name', 'url', 'sequence', - 'created_at', 'created_by', 'updated_at', 'updated_by' - ]; } diff --git a/app/Models/Project.php b/app/Models/Project.php index 622eb47..ae120e4 100644 --- a/app/Models/Project.php +++ b/app/Models/Project.php @@ -6,49 +6,8 @@ use Illuminate\Database\Eloquent\Model; class Project extends Model { - protected $table = 'm_proyek'; - - const CREATED_AT = 'created_at'; - const UPDATED_AT = 'updated_at'; - - protected $fillable = [ - 'kode_sortname', - 'jumlah_stakeholder', - 'nama', - 'mulai_proyek', - 'akhir_proyek', - 'area_kerja', - 'lokasi_kantor', - 'rencana_biaya', - 'biaya_actual', - 'company', - 'pm_id', - 'type_proyek_id', - 'divisi_id', - 'persentase_progress', - 'keterangan', - 'durasi_proyek', - 'progress_by_worklog', - 'status', - 'currency_simbol', - 'currency_code', - 'currency_name', - 'project_objectives', - 'considered_success_when', - 'potential_risk', - 'testing_environment', - 'currency_code', - 'currency_symbol', - 'currency_name', - 'budget_health', - 'phase_id', - 'calculation_status', - 'scurve', - 'created_at', - 'created_by', - 'updated_at', - 'updated_by' - ]; - + protected $table = 'm_proyek', $guarded = ['id']; + const CREATED_AT = 'created_at'; + const UPDATED_AT = 'updated_at'; } diff --git a/app/Models/UserToActivity.php b/app/Models/UserToActivity.php index 76f948a..92a311d 100644 --- a/app/Models/UserToActivity.php +++ b/app/Models/UserToActivity.php @@ -7,55 +7,42 @@ use App\Models\Activity; class UserToActivity extends Model { - protected $table = 'assign_hr_to_activity'; + protected $table = 'assign_hr_to_activity', $guarded = ['id']; const CREATED_AT = 'created_at'; const UPDATED_AT = 'updated_at'; - protected $fillable = [ - 'user_id', - 'proyek_id', - 'version_gantt_id', - 'role_proyek_id', - 'activity_id', - 'created_at', - 'created_by', - 'updated_at', - 'updated_by' - ]; + public static function boot() + { + parent::boot(); - public static function boot() { - parent::boot(); + static::created(function ($data) { + $activity = Activity::find($data->activity_id); + $getWorkingHours = UserToProyek::where('user_id', $data->user_id)->where('proyek_id', $activity->proyek_id)->first(); - static::created(function($data) { - $activity = Activity::find($data->activity_id); - $getWorkingHours = UserToProyek::where('user_id', $data->user_id)->where('proyek_id', $activity->proyek_id)->first(); + $salary = ($getWorkingHours->standart_rate * $activity->duration) * ($getWorkingHours->max_used / 100); - $salary = ($getWorkingHours->standart_rate * $activity->duration) * ($getWorkingHours->max_used / 100); + if ($getWorkingHours->uom_standart_rate == "Hour") + $salary = ($getWorkingHours->standart_rate * 8) * $activity->duration * ($getWorkingHours->max_used / 100); - if($getWorkingHours->uom_standart_rate == "Hour") - $salary = ($getWorkingHours->standart_rate * 8) * $activity->duration * ($getWorkingHours->max_used / 100); + $activity->rencana_biaya += $salary; + $activity->save(); + }); - $activity->rencana_biaya += $salary; - $activity->save(); - }); + static::deleted(function ($data) { + $activity = Activity::find($data->activity_id); - static::deleted(function($data) { - $activity = Activity::find($data->activity_id); - - $getWorkingHours = UserToProyek::where('user_id', $data->user_id)->where('proyek_id', $activity->proyek_id)->first(); - $salary = ($getWorkingHours->standart_rate * $activity->duration) * ($getWorkingHours->max_used / 100); - if($getWorkingHours->uom_standart_rate == "Hour"){ - $salary = ($getWorkingHours->standart_rate * 8) * $activity->duration * ($getWorkingHours->max_used / 100); - } - - $activity->rencana_biaya -= $salary; - if ($activity->rencana_biaya < 0) { - $activity->rencana_biaya = 0; - } - $activity->save(); - }); - - } + $getWorkingHours = UserToProyek::where('user_id', $data->user_id)->where('proyek_id', $activity->proyek_id)->first(); + $salary = ($getWorkingHours->standart_rate * $activity->duration) * ($getWorkingHours->max_used / 100); + if ($getWorkingHours->uom_standart_rate == "Hour") { + $salary = ($getWorkingHours->standart_rate * 8) * $activity->duration * ($getWorkingHours->max_used / 100); + } + $activity->rencana_biaya -= $salary; + if ($activity->rencana_biaya < 0) { + $activity->rencana_biaya = 0; + } + $activity->save(); + }); + } } diff --git a/routes/api.php b/routes/api.php index d5e97bd..cf96819 100644 --- a/routes/api.php +++ b/routes/api.php @@ -64,6 +64,7 @@ use Illuminate\Support\Facades\Route; // cors Middleware Route::middleware('cors')->group(function () { + // Authentication Route::post('/login', AuthController::class); // Menu Route Route::group(['prefix' => 'menu', 'controller' => MenuController::class], function () {