where("version_gantt_id", $id)->count() == 0) { $this->cloneTemplate($id, $proyek_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; $dataHeader->type = "header"; $dataHeader->text = $dataHeader->name; $finalData[] = $dataHeader; $data = Activity::where('version_gantt_id', $id)->where('parent_id', $dataHeader->id)->orderBy('id', 'asc')->get(); }else{ $data = Activity::where('version_gantt_id', $id)->whereNull('parent_id')->orderBy('id', '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; $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('id', 'asc')->get(); foreach($data as $objRow){ $objRow->parent = $parent_id; $objRow->text = $objRow->name; $objRow->progress = (int)$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; }elseif(empty($dataChildren)){ $objRow->type = "task"; }else{ $objRow->type = "project"; } $finalData[] = $objRow; $finalData = array_merge($finalData, $dataChildren); } return $finalData; } private function cloneTemplate($id, $proyek_id) { $project = Project::find($proyek_id); $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'=> 'header', 'created_by'=>$this->currentName, ]); $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(); $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 ]); $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(); $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 ]); $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; $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; if($data->type_activity!='header') $dataUpdate['type_activity'] = $request->type; 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); } 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 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 = (int) $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); } // 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; $activityStack = []; foreach ($data['activities'] as $i => $activity_row) { $startDate = \DateTime::createFromFormat('d-m-y', $activity_row['start_date']); $endDate = \DateTime::createFromFormat('d-m-y', $activity_row['end_date']); $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'); $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; 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 ($activity->level > $lastStack->level) $lastStackIsNotRight = false; } while ($lastStackIsNotRight); } if ($levelEqualWithLastStack) { array_pop($activityStack); } } $activity->parent_id = $activityStack[count($activityStack) - 1]->id ?? null; // 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 (!empty($activity_row['predecessor'])) { $key = array_search($activity_row['predecessor'], array_column($data['activities'], 'no')); if (!$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' => $diff > 1 ? $diff : 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); } }