where("version_gantt_id", $id)->count() == 0) { if (!$gantt->hierarchy_ftth_id) { $this->cloneTemplate($id, $proyek_id); } else { $this->cloneTemplate($id, $proyek_id, $gantt->hierarchy_ftth_id); } } $dataGantt = $this->getDataActivity($id); return response()->json(['status' => 'success', 'data' => $dataGantt, 'code' => 200], 200); } private function getDataActivity($id) { $checkHeader = Activity::where('version_gantt_id', $id)->where('type_activity', 'header')->count(); $finalData = []; if ($checkHeader > 0) { $dataHeader = Activity::where('version_gantt_id', $id)->where('type_activity', 'header')->first(); $startDate = date_create($dataHeader->start_date); $endDate = date_create($dataHeader->end_date); $dataHeader->start_date = date_format($startDate, "Y-m-d H:i:s"); $dataHeader->end_date = date_format($endDate, "Y-m-d H:i:s"); $dataHeader->progress = $dataHeader->persentase_progress / 100; $dataHeader->planned_start = isset($dataHeader->planned_start) ? date_format(date_create($dataHeader->planned_start), "Y-m-d H:i:s") : NULL; $dataHeader->planned_end = isset($dataHeader->planned_end) ? date_format(date_create($dataHeader->planned_end), "Y-m-d H:i:s") : NULL; $actualStart = $this->getFirstLastDateActivity($dataHeader->id, "start"); $dataHeader->actual_start = date_format(date_create($actualStart), "Y-m-d"); $actualEnd = $this->getFirstLastDateActivity($dataHeader->id, "end"); $dataHeader->actual_end = isset($actualEnd) ? date_format(date_create($actualEnd), "Y-m-d") : NULL; $dataHeader->type = "header"; $dataHeader->text = $dataHeader->name; $finalData[] = $dataHeader; $data = Activity::where('version_gantt_id', $id)->where('parent_id', $dataHeader->id)->orderBy('sortorder', 'asc')->get(); } else { $data = Activity::where('version_gantt_id', $id)->whereNull('parent_id')->orderBy('sortorder', 'asc')->get(); } foreach ($data as $objRow) { $type = "project"; $dataChildren = $this->getChildren($id, $objRow->id); $startDate = date_create($objRow->start_date); $endDate = date_create($objRow->end_date); if ($objRow->type_activity == "milestone") $type = $objRow->type_activity; if (empty($dataChildren)) $type = "task"; $objRow->text = $objRow->name; $objRow->parent = $objRow->parent_id ? $objRow->parent_id : null; $objRow->start_date = date_format($startDate, "Y-m-d H:i:s"); $objRow->end_date = date_format($endDate, "Y-m-d H:i:s"); $objRow->planned_start = isset($objRow->planned_start) ? date_format(date_create($objRow->planned_start), "Y-m-d H:i:s") : NULL; $objRow->planned_end = isset($objRow->planned_end) ? date_format(date_create($objRow->planned_end), "Y-m-d H:i:s") : NULL; $actualStart = $this->getFirstLastDateActivity($objRow->id, "start"); $objRow->actual_start = isset($actualStart) ? date_format(date_create($actualStart), "Y-m-d") : NULL; $actualEnd = $this->getFirstLastDateActivity($objRow->id, "end"); $objRow->actual_end = isset($actualEnd) ? date_format(date_create($actualEnd), "Y-m-d") : NULL; $objRow->progress = $objRow->persentase_progress / 100; $objRow->type = $type; $finalData[] = $objRow; $finalData = array_merge($finalData, $dataChildren); } $dataLink = Link::where('version_gantt_id', $id)->get(); $finalLink = []; foreach ($dataLink as $objRow) { $dataRow = array( 'id' => $objRow->id, 'source' => $objRow->s_activity_id, 'target' => $objRow->t_activity_id, 'type' => $objRow->type_link, 'code' => $objRow->code_link ); if ($objRow->lag) $dataRow['lag'] = $objRow->lag; $finalLink[] = $dataRow; } $resultData = array( "data" => $finalData, "links" => $finalLink ); return $resultData; } private function getChildren($gantt_id, $parent_id) { $finalData = []; $data = Activity::where('version_gantt_id', $gantt_id)->where('parent_id', $parent_id)->orderBy('sortorder', 'asc')->get(); foreach ($data as $objRow) { $objRow->parent = $parent_id; $objRow->text = $objRow->name; $objRow->progress = (float) $objRow->persentase_progress / 100; $startDate = date_create($objRow->start_date); $endDate = date_create($objRow->end_date); $objRow->start_date = date_format($startDate, "Y-m-d H:i:s"); $objRow->end_date = date_format($endDate, "Y-m-d H:i:s"); $objRow->planned_start = isset($objRow->planned_start) ? date_format(date_create($objRow->planned_start), "Y-m-d H:i:s") : NULL; $objRow->planned_end = isset($objRow->planned_end) ? date_format(date_create($objRow->planned_end), "Y-m-d H:i:s") : NULL; $dataChildren = $this->getChildren($gantt_id, $objRow->id); if ($objRow->type_activity == "milestone") { $objRow->type = $objRow->type_activity; $objRow->actual_start = isset($objRow->actual_start) ? date_format(date_create($objRow->actual_start), "Y-m-d") : NULL; } elseif (empty($dataChildren)) { $objRow->type = "task"; $objRow->actual_start = isset($objRow->actual_start) ? date_format(date_create($objRow->actual_start), "Y-m-d") : NULL; $objRow->actual_end = isset($objRow->actual_end) ? date_format(date_create($objRow->actual_end), "Y-m-d") : NULL; if(isset($objRow->actual_start)){ $objRow->auto_scheduling = false; } } else { $objRow->type = "project"; $actualStart = $this->getFirstLastDateActivity($objRow->id, "start"); $objRow->actual_start = isset($actualStart) ? date_format(date_create($actualStart), "Y-m-d") : NULL; $actualEnd = $this->getFirstLastDateActivity($objRow->id, "end"); $objRow->actual_end = isset($actualEnd) ? date_format(date_create($actualEnd), "Y-m-d") : NULL; } $finalData[] = $objRow; $finalData = array_merge($finalData, $dataChildren); } return $finalData; } public function getActivityFirst($parentId){ $activity = Activity::where('parent_id', $parentId)->orderByRaw('actual_start ASC')->first(); if (!isset($activity)) { return null; } if($activity->type_activity == "task"){ // Log::info("activity ", [$activity]); return $activity->actual_start; }else{ return $this->getActivityFirst($activity->id); } } public function getFirstLastDateActivity($id, $params){ if($params == "start"){ $data = Activity::select('id', 'parent_id', 'name', 'actual_start')->where('parent_id', $id)->get(); }else{ $data = Activity::select('id', 'parent_id', 'name', 'actual_end')->where('parent_id', $id)->get(); } $parent = Activity::findOrFail($id); $dataFinal=[]; foreach ($data as $val) { $activity = $this->getchildActivityForActual($val->id, $params); $dataFinal[] = $val; $dataFinal = array_merge($dataFinal, $activity); } if($params == "start"){ $actualStartValues = array_column(array_filter($dataFinal, function($item) { return isset($item['actual_start']); }), 'actual_start'); $returnActualStartOrEnd = count($actualStartValues) > 0 ? min($actualStartValues) : null; if (isset($parent)) { $parent->actual_start = $returnActualStartOrEnd; $parent->save(); } }else{ $actualEndValues = array_column(array_filter($dataFinal, function($item) { return isset($item['actual_end']); }), 'actual_end'); $returnActualStartOrEnd = count($actualEndValues) == count($dataFinal) ? max($actualEndValues) : null; if (isset($parent)) { $parent->actual_end = $returnActualStartOrEnd; $parent->save(); } } // return json_encode(["min"=>$minActualStart, "max"=>$maxActualStart]); return $returnActualStartOrEnd; } public function getchildActivityForActual($parent, $params){ if($params == "start"){ $activity = Activity::select('id', 'actual_start')->where('parent_id', $parent)->get(); }else{ $activity = Activity::select('id', 'actual_end')->where('parent_id', $parent)->get(); } $temp = []; foreach($activity as $val1){ $getChild = $this->getchildActivityForActual($val1->id, $params); $temp[] = $val1; $temp = array_merge($temp, $getChild); } return $temp; } public function getActivityLast($parentId){ $activity = Activity::where('parent_id', $parentId)->orderByRaw('actual_end DESC')->first(); if (!isset($activity)) { return null; } if($activity->type_activity == "task"){ // Log::info("activity ", [$activity]); return $activity->actual_end; }else{ return $this->getActivityLast($activity->id); } } private function cloneTemplate($id, $proyek_id, $hierarchy_ftth_id = null) { $project = Project::find($proyek_id); if ($hierarchy_ftth_id) { $gantt = VersionGantt::find($id); $rootActivity = Activity::create([ 'version_gantt_id' => $id, 'proyek_id' => $proyek_id, 'name' => $gantt->name_version, 'start_date' => $project->mulai_proyek, 'end_date' => $project->akhir_proyek, 'rencana_biaya' => $project->rencana_biaya, 'type_activity' => 'project', 'created_by' => $this->currentName, 'sortorder' => 1 ]); } else { $rootActivity = Activity::create([ 'version_gantt_id' => $id, 'proyek_id' => $proyek_id, 'name' => $project->nama, 'kode_sortname' => $project->kode_sortname, 'start_date' => $project->mulai_proyek, 'end_date' => $project->akhir_proyek, 'rencana_biaya' => $project->rencana_biaya, 'type_activity' => 'project', 'created_by' => $this->currentName, 'sortorder' => 1 ]); } $resultTypeProject = TemplateGantt::where('proyek_type_id', $project->type_proyek_id) ->whereNull('parent_id') ->orderByRaw('id ASC') ->get(); foreach ($resultTypeProject as $objRow) { $childActivities = TemplateGantt::where("parent_id", $objRow->id)->count(); $max = Activity::where('version_gantt_id', $id)->max('sortorder'); $resultNew = Activity::create([ 'type_activity' => $childActivities > 0 ? "project" : "task", 'version_gantt_id' => $id, 'parent_id' => $rootActivity->id, 'proyek_id' => $proyek_id, 'name' => $objRow->name_activity, 'start_date' => date("Y-m-d H:i:s"), 'end_date' => date("Y-m-d H:i:s"), 'created_by' => $this->currentName, 'sortorder' => $max + 1 ]); $this->getChildrenTemplate($id, $objRow->id, $project->type_project_id, $proyek_id, $resultNew->id, $project->mulai_proyek); } } private function getChildrenTemplate($id, $parent_id, $type_proyek_id, $proyek_id, $parent_new, $firstDay) { $data = TemplateGantt::where('parent_id', $parent_id)->orderByRaw('id ASC')->get(); foreach ($data as $objRow) { $childActivities = TemplateGantt::where("parent_id", $objRow->id)->count(); $max = Activity::where('version_gantt_id', $id)->max('sortorder'); $resultNew = Activity::create([ 'type_activity' => $childActivities > 0 ? "project" : "task", 'version_gantt_id' => $id, 'parent_id' => $parent_new, 'proyek_id' => $proyek_id, 'name' => $objRow->name_activity, 'start_date' => $firstDay, 'end_date' => $firstDay, 'created_by' => $this->currentName, 'sortorder' => $max + 1 ]); $this->getChildrenTemplate($id, $objRow->id, $type_proyek_id, $proyek_id, $resultNew->id, $firstDay); } } public function add(Request $request) { $this->validate($request, [ 'version_gantt_id' => 'required' ]); $data = $request->all(); $data['name'] = $request->text; $data['persentase_progress'] = $request->progress; $data['created_by'] = $this->currentName; $max = Activity::where('version_gantt_id', $request->version_gantt_id)->max('sortorder'); $data['sortorder'] = $max + 1; if (!isset($data['type_activity'])) { $data['type_activity'] = "task"; } $parent = $data['parent_id'] ?? null; if ($parent) { $parentData = Activity::find($parent); if ($parentData->parent_id) { $parentData->update(["type_activity" => "project"]); } CommentActivity::where('activity_id', $parent)->delete(); UserToActivity::where('activity_id', $parent)->delete(); } if (!$result = Activity::create($data)) return response()->json(['status' => 'failed', 'action' => 'error', 'code' => 500], 500); return response()->json(['status' => 'success', 'action' => 'inserted', 'tid' => $result->id, '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); if (!$result = Activity::find($id)) 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', 'action' => 'error', 'message' => 'id is required!', 'code' => 400], 400); $updateBobot = true; if (!$data = Activity::find($id)) return response()->json(['status' => 'failed', 'action' => 'error', 'message' => 'Data not found!', 'code' => 404], 404); $dataUpdate = $request->all(); $dataUpdate['name'] = $request->text; $dataUpdate['persentase_progress'] = $request->progress * 100; $dataUpdate['updated_by'] = $this->currentName; unset($dataUpdate['sortorder']); if ($data->type_activity != 'header') $dataUpdate['type_activity'] = $request->type; if ($request->has("target")) { $this->updateOrder($id, $request->target); } if (!$data->update($dataUpdate)) return response()->json(['status' => 'failed', 'action' => 'error', 'message' => 'data activity failed updated!', 'code' => 400], 400); return response()->json(['status' => 'success', 'update_bobot' => $updateBobot, 'data' => $dataUpdate, 'action' => 'updated', 'message' => 'Activity updated!', 'code' => 200], 200); } private function updateOrder($taskId, $target) { $nextTask = false; $targetId = $target; if (strpos($target, "next:") === 0) { $targetId = substr($target, strlen("next:")); $nextTask = true; } if ($targetId == "null") return; $targetOrder = Activity::find($targetId)->sortorder; if ($nextTask) $targetOrder++; Activity::where("sortorder", ">=", $targetOrder)->increment("sortorder"); $updatedTask = Activity::find($taskId); $updatedTask->sortorder = $targetOrder; $updatedTask->save(); } public function updateRegular(Request $request, $id) { if (empty($id) || !is_int((int) $id)) return response()->json(['status' => 'failed', 'message' => 'id is required!', 'code' => 400], 400); $data = Activity::find($id); if (!$data = Activity::find($id)) return response()->json(['status' => 'failed', 'message' => 'Data not found!', 'code' => 404], 404); if (!$data->update($request->all())) return response()->json(['status' => 'failed', 'message' => 'Failed to update!', 'code' => 500], 500); return response()->json(['status' => 'success', 'message' => 'Activity Updated!', 'code' => 200], 200); } public function updateSchedule($ganttId){ if (empty($ganttId) || !is_int((int) $ganttId)) return response()->json(['status' => 'failed', 'message' => 'id is required!', 'code' => 400], 400); $activities = Activity::where('version_gantt_id', $ganttId)->get(); if (!$activities) return response()->json(['status' => 'failed', 'message' => 'Activities not found!', 'code' => 404], 404); $duration = 0; foreach ($activities as $key => $activity) { $assignMaterial = AssignMaterial::where('activity_id', $activity->id)->first(); if (isset($assignMaterial)) { $statusActivity = $assignMaterial->status_activity; } else { $statusActivity = ''; } if (isset($activity->planned_start) && isset($activity->planned_end) && $statusActivity != "done") { // todo check report for no report / progress == 0 $today = new DateTime(); $endDate = new DateTime($activity->end_date); $startDate = new DateTime($activity->start_date); $plannedStart = new DateTime($activity->planned_start); $plannedEnd = new DateTime($activity->planned_end); $duration = MasterFunctionsHelper::countDays($ganttId, $plannedStart, $plannedEnd); if ($today >= $endDate) { $endDate = $today; $bobotPlanning = (int) $activity->bobot_planning; $rerataBobot = $duration > 0 ? $bobotPlanning / $duration : 0; $bobotActual = (int) $activity->persentase_progress/100 * $bobotPlanning; $sisaBobot = $bobotPlanning - $bobotActual; $sisaHari = $rerataBobot > 0 ? $sisaBobot / $rerataBobot : 0; $endDate->modify("+".ceil($sisaHari)." Days"); $actualDuration = MasterFunctionsHelper::countDays($ganttId, $startDate, $endDate); $activity->duration = $actualDuration; $activity->end_date = $endDate; $activity->save(); } } } return response()->json(['status' => 'success', 'message' => 'Activities Updated!', 'code' => 200], 200); } public function batchUpdate(Request $request, $ganttId) { $entities = $request->all(); if (empty($ganttId) || !is_int((int) $ganttId)) return response()->json(['status' => 'failed', 'message' => 'id is required!', 'code' => 400], 400); $activity = Activity::where('version_gantt_id',$ganttId)->get(); $link = Link::where('version_gantt_id', $ganttId)->get(); if (!$activity) return response()->json(['status' => 'failed', 'message' => 'Activity not found!', 'code' => 404], 404); if (!$link) return response()->json(['status' => 'failed', 'message' => 'Link not found!', 'code' => 404], 404); foreach ($entities as $entity) { if ($entity['entity'] == "task") { $activityToUpdate = $activity->firstWhere('id', $entity['data']['id']); $entity['data']['name'] = $entity['data']['text']; $entity['data']['persentase_progress'] = $entity['data']['progress'] * 100; if (isset($entity['data']['rencana_biaya'])) { $entity['data']['rencana_biaya'] = str_replace(",", ".", $entity['data']['rencana_biaya']); } if (isset($entity['data']['target'])) { $this->updateOrder($entity['data']['id'], $entity['data']['target']); } if (!$activityToUpdate->update($entity['data'])) return response()->json(['status' => 'failed', 'message' => 'Failed to update activity !', 'code' => 500], 500); $updatedJobsDone = $activityToUpdate->jobs_done; } else if ($entity['entity'] == "link") { $linkToUpdate = $link->firstWhere('id', $entity['data']['id']); if (!$linkToUpdate->update($entity['data'])) return response()->json(['status' => 'failed', 'message' => 'Failed to update link !', 'code' => 500], 500); } } return response()->json(['status' => 'success', 'message' => 'Activity Updated!', 'code' => 200], 200); } public function delete($id) { if (!$data = Activity::find($id)) return response()->json(['status' => 'failed', 'action' => 'error', 'message' => 'Data not found!', 'code' => 404], 404); if (!$data->delete()) return response()->json(['status' => 'failed', 'action' => 'error', 'message' => 'data activity failed deleted!', 'code' => 500], 500); return response()->json(['status' => 'success', "action" => "deleted", 'message' => 'data activity successfully deleted!', 'code' => 200], 200); } public function getUpdate($id) { if (!$data = Activity::find($id)) return response()->json(['status' => 'failed', 'action' => 'error', 'message' => 'Data not found!', 'code' => 400], 400); $data->progress = (float) $data->persentase_progress / 100; $data->rencana_biaya = str_replace(".", ",", $data->rencana_biaya); return response()->json(['status' => 'success', "data" => $data, 'code' => 200], 200); } public function search(Request $request) { $dataBuilder = $this->setUpPayload($request->all(), 'm_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 searchAnalysisPrep(Request $request) { $data = $request->all(); $dataGet = DB::table('m_activity') ->select('m_activity.name') ->where('m_activity.proyek_id', $data['columns'][0]['value']) ->where('m_activity.type_activity', 'task') // ->where('m_activity.persentase_progress', '>', 0) ->groupByRaw('m_activity.name') ->get(); return response()->json(['status' => 'success', 'code' => 200, 'data' => $dataGet ], 200); } public function searchAnalysis(Request $request) { $dataBuilder = $this->setUpPayload($request->all(), 'm_activity'); $builder = $dataBuilder['builder']; $dataGet = $builder->select( 'selfTable.name', 'persentase_progress', 'selfTable.start_date', 'selfTable.end_date', 'duration', 'm_version_gantt.name_version', DB::raw('STRING_AGG(m_users.name, \',\') as user_name'), DB::raw('SUM(report_activity_material.qty) as qty'), 'assign_material_to_activity.qty_planning', 'assign_material_to_activity.id as join_third_id') ->join('m_version_gantt', 'm_version_gantt.id', '=', 'selfTable.version_gantt_id') ->leftJoin('assign_hr_to_activity', 'assign_hr_to_activity.activity_id', '=', 'selfTable.id') ->leftJoin('m_users', 'assign_hr_to_activity.user_id', '=', 'm_users.id') ->leftJoin('report_activity_material', 'report_activity_material.activity_id', '=', 'selfTable.id') ->join('assign_material_to_activity', 'assign_material_to_activity.activity_id', '=', 'selfTable.id') ->groupBy("selfTable.id") ->groupBy("selfTable.name") ->groupBy("selfTable.persentase_progress") ->groupBy("m_version_gantt.name_version") ->groupBy("assign_material_to_activity.qty_planning") ->groupBy("assign_material_to_activity.id") ->get(); return response()->json(['status' => 'success', 'code' => 200, 'data' => $dataGet ], 200); } // before upload file public function importOld(Request $request) { $data = $request->all(); $data['created_by'] = $this->currentName; Activity::where('version_gantt_id', $data['ganttId'])->delete(); $projectId = VersionGantt::where('id', $data['ganttId'])->first()->proyek_id; $dayOffs = VersionGantt::where('id', $data['ganttId'])->first()->config_dayoff; $activityStack = []; $hasWeight = false; foreach ($data['activities'] as $key => $value) { if (isset($value['weight']) && $value['weight'] != null && $value['weight'] != 0) { $hasWeight = true; break; } } if (!$hasWeight) { foreach ($data['activities'] as $key => $value) { if ($key == 0) { $data['activities'][$key]['weight'] = 100; } else { $parentWeight = 0; $siblingsCount = 1; $i = $key; while ($i > 0) { if ($data['activities'][$i - 1]['level'] == $data['activities'][$key]['level'] - 1) { $parentWeight = $data['activities'][$i - 1]['weight']; break; } if ($data['activities'][$key]['level'] == $data['activities'][$i]['level']) { $siblingsCount++; } $i--; } $i = $key + 1; while ($i < count($data['activities'])) { if ($data['activities'][$i]['level'] == $data['activities'][$key]['level'] - 1) { break; } // Log::info('level '.$data['activities'][$key]['level'].' i level '.$data['activities'][$i]['level']); if ($data['activities'][$key]['level'] == $data['activities'][$i]['level']) { $siblingsCount++; } $i++; } $data['activities'][$key]['weight'] = $parentWeight / $siblingsCount; } } ; } $projectStart = Project::select('mulai_proyek')->where('id', $projectId)->first(); foreach ($data['activities'] as $i => $activity_row) { $startDate = new \DateTime($projectStart->mulai_proyek); $endDate = clone $startDate; $endDate->modify('-1 day'); $daysRemaining = $activity_row['duration']; // Loop until the remaining days become zero while ($daysRemaining > 0) { $endDate->modify('+1 day'); // Check if the current day is a day off (Sunday or Saturday) $currentDayOfWeek = (int) $endDate->format('w'); if (strpos($dayOffs, (string) $currentDayOfWeek) !== false) { continue; // Skip the day off and continue to the next day } $daysRemaining--; // Decrease the remaining days by one } $endDate->setTime(23, 59, 59); $input['name'] = $activity_row['name']; $input['proyek_id'] = $projectId; $input['version_gantt_id'] = $data['ganttId']; $input['parent_id'] = null; $input['start_date'] = $startDate->format('Y-m-d'); $input['end_date'] = $endDate->format('Y-m-d H:i:sO'); $input['duration'] = $activity_row['duration']; $input['bobot_planning'] = $activity_row['weight']; $input['persentase_progress'] = 0; $input['type_activity'] = $i == 0 ? "header" : "task"; $input['created_by'] = $this->currentName; $input['sortorder'] = $activity_row['no']; if (!$activity = Activity::create($input)) { Activity::where('version_gantt_id', $data['ganttId'])->delete(); return response()->json(['status' => 'error', 'message' => 'Input failed on ' . $activity['name'], 'code' => 500], 500); } $data['activities'][$i]['activity_id'] = $activity->id; if ($i == 0) { $activity->type_activity = "project"; $activity->save(); $activity->level = $activity_row['level']; array_push($activityStack, $activity); continue; } $activity->level = $activity_row['level']; if ($lastStack = end($activityStack)) { $levelLowerThanLastStack = $activity->level < $lastStack->level; $levelEqualWithLastStack = $activity->level == $lastStack->level; if ($levelLowerThanLastStack) { $lastStackIsNotRight = $levelLowerThanLastStack; do { array_pop($activityStack); $lastStack = end($activityStack); if ($lastStack) { if ($activity->level > $lastStack->level) $lastStackIsNotRight = false; } else { $lastStackIsNotRight = false; } } while ($lastStackIsNotRight); } if ($levelEqualWithLastStack) { array_pop($activityStack); } } $activity->parent_id = $activityStack[count($activityStack) - 1]->id ?? null; array_push($activityStack, $activity); // there should be better way to except / filter attribute level before save because it's cause error // cant use except() / filter() on $activity collection somehow unset($activity->level); $activity->save(); $activity->level = $activity_row['level']; if (@$activityStack[count($activityStack) - 1]->level != $activity->level && $activity->level != $data['activities'][$i - 1]['level']) { array_push($activityStack, $activity); } if ($activity->level < @$data['activities'][$i + 1]['level']) { unset($activity->level); $activity->type_activity = "project"; $activity->save(); $activity->level = $activity_row['level']; } if (isset($data['activities'][$i]['nik']) && $data['activities'][$i]['nik'] != '') { $user = User::where("ktp_number", $data['activities'][$i]['nik'])->first(); $userProyek = UserToProyek::where("user_id", $user->id) ->where("proyek_id", $projectId) ->first(); $dataInsert = array( "user_id" => $user->id, "activity_id" => $activity->id, "role_proyek_id" => $userProyek->project_role, "proyek_id" => $projectId, "created_by" => $this->currentName, "version_gantt_id" => $data['ganttId'] ); UserToActivity::create($dataInsert); } if (!empty($activity_row['predecessor'])) { $key = array_search($activity_row['predecessor'], array_column($data['activities'], 'no')); if (!isset($data['activities'][$key]['activity_id']) || !$predecessorActivity = Activity::find($data['activities'][$key]['activity_id'])) continue; $predecessorFinishDate = new \DateTime($predecessorActivity->end_date); $interval = $predecessorFinishDate->diff(new \DateTime($activity->start_date)); $diff = $interval->days; Link::create([ 'created_by' => $this->currentName, 's_activity_id' => $predecessorActivity->id, 't_activity_id' => $activity->id, 'type_link' => 0, 'code_link' => 'FS', 'version_gantt_id' => $data['ganttId'], 'lag' => null, ]); } } return response()->json(['stack' => $activityStack, 'status' => 'success', 'message' => 'Data imported!', 'projectId' => $projectId, 'code' => 200], 200); } private function getLatestGantt($id) { $maxGanttId = VersionGantt::where("proyek_id", $id)->max("id"); $data = array( "last_gantt_id" => $maxGanttId, "proyek_id" => $id ); return $data; } public function getCalculateCurvaS(Request $request) // for adw (plan & actual == date) { $dataPayload = $request->all(); $allGantt = []; if (isset($dataPayload['gannt_id'])) { $allGantt = $dataPayload['gannt_id']; } else { foreach ($dataPayload['project_id'] as $val) { $allGantt[] = $this->getLatestGantt($val); } } $dataFinal = []; foreach ($allGantt as $keyGantt) { $dataProject = Project::find($keyGantt['proyek_id']); $dataHeader = Activity::where('type_activity', 'header')->where("proyek_id", $keyGantt['proyek_id'])->where("version_gantt_id", $keyGantt['last_gantt_id'])->first(); if ($dataHeader) { $totalRencanaBudget = Activity::where('parent_id', $dataHeader->id)->where("proyek_id", $keyGantt['proyek_id'])->where("version_gantt_id", $keyGantt['last_gantt_id'])->sum("rencana_biaya"); } else { $totalRencanaBudget = Activity::whereNull('parent_id')->where("proyek_id", $keyGantt['proyek_id'])->where("version_gantt_id", $keyGantt['last_gantt_id'])->sum("rencana_biaya"); } $minDate = DB::table('assign_material_to_activity as ama') ->where("ama.proyek_id", $keyGantt['proyek_id']) ->join('m_activity as a', 'a.id', '=', 'ama.activity_id') ->where('a.version_gantt_id', '=', $keyGantt['last_gantt_id']) ->min("plan_date"); $maxDate = DB::table('assign_material_to_activity as ama') ->where("ama.proyek_id", $keyGantt['proyek_id']) ->join('m_activity as a', 'a.id', '=', 'ama.activity_id') ->where('a.version_gantt_id', '=', $keyGantt['last_gantt_id']) ->max("plan_date"); $begin = new \DateTime($minDate); $end = new \DateTime($maxDate); $end2 = new \DateTime($maxDate); $interval = \DateInterval::createFromDateString('1 day'); $period = new \DatePeriod($begin, $interval, $end); $arr_ActualM = []; $tempDate = []; $tempPercentage = []; $tempTtlPercentPlan = 0; $tempTtlPercentActual = 0; $currentACWP = 0; $budgetControlACWP = 0; $currentProgressActivity = 0; $currentBCWP = 0; $budgetControlBCWP = 0; foreach ($period as $dt) { $dataPlanM = DB::table('assign_material_to_activity as ama') ->select('ama.activity_id', 'ama.qty_planning', 'ama.plan_date', 'ama.start_activity', 'a.bobot_planning', 'a.biaya_actual', 'a.duration', 'a.persentase_progress') ->join('m_activity as a', 'a.id', '=', 'ama.activity_id') ->where('ama.proyek_id', '=', $keyGantt['proyek_id']) ->where('a.version_gantt_id', '=', $keyGantt['last_gantt_id']) ->whereDate('ama.plan_date', $dt->format("Y-m-d")) ->get(); $dataActualM = DB::table('report_activity_material as ram') ->select('ram.activity_id', 'ram.qty', 'ram.report_date', 'a.bobot_planning', 'a.biaya_actual', 'a.duration', 'a.persentase_progress') ->join('m_activity as a', 'a.id', '=', 'ram.activity_id') ->where('a.version_gantt_id', '=', $keyGantt['last_gantt_id']) ->where('a.proyek_id', '=', $keyGantt['proyek_id']) ->whereDate('ram.report_date', $dt->format("Y-m-d")) ->get(); $dataTempPlan = []; $x = 0; $sumPercentagePlan = 0; $totalACWP = isset($totalACWP) ? $totalACWP : 0; $totalBCWP = isset($totalBCWP) ? $totalBCWP : 0; foreach ($dataPlanM as $keyPlanM) { $sumVolPlan = DB::table('assign_material_to_activity') ->select('activity_id', DB::raw('SUM(qty_planning) as ttl_qty_plan')) ->where('activity_id', '=', $keyPlanM->activity_id) ->groupBy('activity_id') ->first(); $dataTempPlan[$x]['activity_id'] = $keyPlanM->activity_id; $dataTempPlan[$x]['qty_plan'] = $keyPlanM->qty_planning; $dataTempPlan[$x]['plan_date'] = $keyPlanM->plan_date; $dataTempPlan[$x]['start_activity'] = $keyPlanM->start_activity; $dataTempPlan[$x]['bobot_planning'] = $keyPlanM->bobot_planning; $dataTempPlan[$x]['ttl_plan'] = $sumVolPlan->ttl_qty_plan; $dataTempPlan[$x]['biaya_actual'] = $keyPlanM->biaya_actual; $dataTempPlan[$x]['duration'] = $keyPlanM->duration; $dataTempPlan[$x]['persentase_progress'] = $keyPlanM->persentase_progress; $dataTempPlan[$x]['percentage'] = ($keyPlanM->qty_planning / $sumVolPlan->ttl_qty_plan) * $keyPlanM->bobot_planning; $sumPercentagePlan += ($keyPlanM->qty_planning / $sumVolPlan->ttl_qty_plan) * $keyPlanM->bobot_planning; $totalBCWP += (((($keyPlanM->persentase_progress * $keyPlanM->bobot_planning) / 100) / $keyPlanM->duration) * $totalRencanaBudget) / 100; $dataTempPlan[$x]['totalBCWP'] = $totalBCWP; $x++; } $w = 0; $dataTempReport = []; $sumPercentageActual = 0; foreach ($dataActualM as $keyActualM) { $sumVolActual = DB::table('assign_material_to_activity') ->select('activity_id', DB::raw('SUM(qty_planning) as ttl_qty_plan')) ->where('activity_id', '=', $keyActualM->activity_id) ->groupBy('activity_id') ->first(); $dataTempReport[$w]['activity_id'] = $keyActualM->activity_id; $dataTempReport[$w]['qty'] = $keyActualM->qty; $dataTempReport[$w]['report_date'] = $keyActualM->report_date; $dataTempReport[$w]['bobot_planning'] = $keyActualM->bobot_planning; $dataTempReport[$w]['ttl_plan'] = $sumVolActual->ttl_qty_plan; $dataTempReport[$w]['biaya_actual'] = $keyActualM->biaya_actual; $dataTempReport[$w]['duration'] = $keyActualM->duration; $dataTempReport[$w]['persentase_progress'] = $keyActualM->persentase_progress; $dataTempReport[$w]['percentage'] = ($keyActualM->qty / $sumVolActual->ttl_qty_plan) * $keyActualM->bobot_planning; $sumPercentageActual += ($keyActualM->qty / $sumVolActual->ttl_qty_plan) * $keyActualM->bobot_planning; $totalACWP += $keyActualM->biaya_actual / $keyActualM->duration; $dataTempReport[$w]['totalacwp'] = $totalACWP; $w++; } $arr_ActualM[] = array( 'date' => $dt->format("Y-m-d"), 'percentPlan' => $sumPercentagePlan, 'percentActual' => $sumPercentageActual, 'plan' => $dataTempPlan, 'actual' => $dataTempReport, ); if (isset($dataPayload['period']) && $dataPayload['period'] == 'week') { if ($dt->format("w") == 1) { if ($totalACWP > 0) { $budgetControlACWP = $currentACWP + $totalACWP; } if ($totalBCWP > 0) { $budgetControlBCWP = $currentBCWP + $totalBCWP; } $tempTtlPercentPlan += $sumPercentagePlan; $tempTtlPercentActual += $sumPercentageActual; $currentACWP += $totalACWP; $currentBCWP += $totalBCWP; $tempPercentage[] = array(round($tempTtlPercentPlan, 2), round($tempTtlPercentActual, 2)); $tempDate[] = array($dt->format("Y-m-d"), 0, 0); } else if ($dt->format("Y-m-d") == $end2->format("Y-m-d")) { $tempTtlPercentPlan += $sumPercentagePlan; $tempTtlPercentActual += $sumPercentageActual; $currentACWP += $totalACWP; $currentBCWP += $totalBCWP; $tempPercentage[] = array(round($tempTtlPercentPlan, 2), round($tempTtlPercentActual, 2)); $tempDate[] = array($dt->format("Y-m-d"), 0, 0); $tempTtlPercentPlan = 0; $tempTtlPercentActual = 0; } } else { $tempPercentage[] = array(round($sumPercentagePlan, 2), round($sumPercentageActual, 2)); $tempDate[] = array($dt->format("Y-m-d"), 0, 0); } } if (round($totalACWP, 0) > $totalRencanaBudget) { $estimatedCost = round($totalACWP, 0) + 0; } else { $estimatedCost = ($totalRencanaBudget + 0); } $costDeviation = $totalRencanaBudget - $estimatedCost; if ($costDeviation > 0) { $potential = "SAVING"; } else { $potential = $costDeviation == 0 ? "ON BUDGET" : "OVERRUN"; } $dataResponse = array( "date" => $tempDate, "percentage" => $tempPercentage, "data_details" => $arr_ActualM, "budget_control" => array( "current_budget" => $totalRencanaBudget, "acwp" => round($totalACWP, 0), "bcwp" => round($totalBCWP, 0), "rem_to_complete" => ($totalRencanaBudget - round($totalACWP, 0)), "add_cost_to_complete" => 0, "estimated_at_completion" => $estimatedCost, "cost_deviation" => $costDeviation, "potential" => $potential, ) ); $dataFinal[] = array( "proyek_name" => $dataProject->nama, "data" => $dataResponse, "allGant" => $allGantt ); } return response()->json(['status' => 'success', 'code' => 200, 'data' => $dataFinal], 200); } public function import(Request $request) { $data = $request->all(); $data['created_by'] = $this->currentName; Activity::where('version_gantt_id', $data['gantt_id'])->delete(); $projectId = VersionGantt::where('id', $data['gantt_id'])->first()->proyek_id; // get data excel $excel = TmpImport::latest('id')->first(); return response()->json(['stack' => $excel, 'status' => 'success', 'message' => 'Data imported!', 'data' => $data, 'code' => 200], 200); } public function uploadTmpImport(Request $request) { if ($request->hasFile('dokumen')) { $document = $request->file('dokumen'); $gantt_id = $request->gantt_id; $name = $document->getClientOriginalName(); $result = $document->move($this->pathTmpImport, $name); if ($result) { $data = [ 'gantt_id' => (int) $gantt_id, 'file' => $name, 'type_dokumen' => $request->type_dokumen ]; $result = TmpImport::create($data); if (!$result) { unlink($this->pathTmpImport . $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 importUpdate(Request $request) { $data = $request->all(); foreach ($data as $value) { $activity = Activity::find($value['id']); $activity->duration = $value['duration']; $activity->start_date = $value['start_date']; $activity->end_date = $value['end_date']; $activity->save(); } return response()->json(['status' => 'success', 'data' => $request, 'message' => 'Update successful!', 'code' => 200], 200); } }