first()->config_dayoff; $diff = date_diff($start, $end); $endCount = clone $end; $duration = $diff->days + 1; $daysRemaining = $duration; // Loop until the remaining days become zero while ($daysRemaining > 0) { $endCount->modify('-1 day'); // Check if the current day is a day off (Sunday or Saturday) $currentDayOfWeek = (int) $endCount->format('w'); if (strpos($dayOffs, (string) $currentDayOfWeek) !== false) { // continue; // Skip the day off and continue to the next day $duration--; } $daysRemaining--; // Decrease the remaining days by one } return $duration; } public function getLatestGantt($id) { $maxGanttId = VersionGantt::where("proyek_id", $id)->max("id"); if (!$maxGanttId) { $data = array( "proyek_id" => $id ); } else { $data = array( "last_gantt_id" => $maxGanttId, "proyek_id" => $id ); } return $data; } // dipake di dashboard project & bod public function getSCurve($request) { $allGantt = []; if (!is_int($request)) { $dataPayload = $request->all(); if (isset($dataPayload['gantt_id'])) { $allGantt[] = $dataPayload['gantt_id']; } else { $allGantt[] = MasterFunctionsHelper::getLatestGantt($dataPayload['project_id']); } } else { $allGantt[] = MasterFunctionsHelper::getLatestGantt($request); } foreach ($allGantt as $gantt) { if (!isset($gantt['last_gantt_id'])) { $ganttId = $gantt; } else { $ganttId = $gantt['last_gantt_id']; } $gantt = VersionGantt::find($ganttId)->toArray(); // foreach ($gantt as $key => $value) { // Log::info('gantt '.$value.' index '.$key); // } if (isset($gantt['calculation_type'])) { if ($gantt['calculation_type'] == 'simple') { // to do return MasterFunctionsHelper::calculateProgressBasedOnSimple($gantt); } else { return MasterFunctionsHelper::calculateProgressBasedOnReportMaterial($gantt); } } } } public function getLinearSCurve($request) { $ftths = HierarchyFtth::where('project_id', $request->project_id)->get(); $ttlProgress = 0; $ttlPlanning = 0; foreach ($ftths as $ftth) { $progress = VersionGantt::where('hierarchy_ftth_id', $ftth->id)->sum('progress'); $planning = VersionGantt::where('hierarchy_ftth_id', $ftth->id)->sum('bobot'); $ttlProgress += $progress; $ttlPlanning += $planning; } $minDate = Project::select('mulai_proyek')->where('id', $request->project_id)->first(); $maxDate = Project::select('akhir_proyek')->where('id', $request->project_id)->first(); $begin = new \DateTime($minDate->mulai_proyek . ' Monday'); $end = new \DateTime($maxDate->akhir_proyek . ' Friday'); $interval = new \DateInterval('P7D'); $period = new \DatePeriod($begin, $interval, $end); $dates = iterator_to_array($period); $count = count($dates); $avgProgress = $ttlProgress / $ttlPlanning / $count * 100; $avgPlanning = $ttlPlanning / $ttlPlanning / $count * 100; $progressData = []; $planningData = []; $dates = []; $tempProgress = 0; $tempPlanning = 0; array_push($progressData, round($tempProgress, 2)); array_push($planningData, round($tempPlanning, 2)); foreach ($period as $p) { $tempProgress += $avgProgress; $tempPlanning += $avgPlanning; array_push($progressData, round($tempProgress, 2)); array_push($planningData, round($tempPlanning, 2)); array_push($dates, $p->format("Y-m-d")); } $dataResponse = array( "percentagePlan" => $planningData, "percentageReal" => $progressData, "date" => $dates, ); $dataFinal[] = array( "data" => $dataResponse, ); return $dataFinal; } public function calculateProgressBasedOnReportMaterial($keyGantt) { DB::enableQueryLog(); $dataFinal = []; $dataPayload = []; $dataPayload['period'] = 'week'; $totalACWP = 0; $totalBCWP = 0; $tempPercentage = []; $dataProject = Project::find($keyGantt['proyek_id']); $dataHeader = Activity::where('type_activity', 'header')->where("proyek_id", $keyGantt['proyek_id'])->where("version_gantt_id", $keyGantt['id'])->first(); if (isset($dataPayload['end_date']) && $dataPayload['end_date'] > $dataProject->akhir_proyek) { $dataPayload['end_date'] = $dataProject->akhir_proyek; } if ($dataHeader) { $totalRencanaBudget = Activity::where('parent_id', $dataHeader->id)->where("proyek_id", $keyGantt['proyek_id'])->where("version_gantt_id", $keyGantt['id'])->sum("rencana_biaya"); } else { $totalRencanaBudget = Activity::whereNull('parent_id')->where("proyek_id", $keyGantt['proyek_id'])->where("version_gantt_id", $keyGantt['id'])->sum("rencana_biaya"); } if (!Activity::where("version_gantt_id", $keyGantt['id'])->first()) return $dataFinal; $alreadyHasReport = DB::table('report_activity_material as a') ->select('a.id') ->join('m_activity as b', 'b.id', '=', 'a.activity_id') ->where('b.version_gantt_id', '=', $keyGantt['id']) ->exists(); // note : delete this // if(!$alreadyHasReport) // return $dataFinal; $minDate = Activity::where('version_gantt_id', $keyGantt['id'])->whereNull('parent_id')->pluck('start_date')->first(); $begin = new \DateTime($minDate . ' Monday'); $begin->modify('last Monday'); if (isset($dataPayload['end_date'])) { $maxDate = $dataPayload['end_date']; $end = new \DateTime($maxDate . ' Friday'); $end->modify('next Friday'); $end->modify('next Friday'); /* $interval = \DateInterval::createFromDateString('1 day'); */// should be using this but its bugged $interval = new \DateInterval('P7D'); } else { $actualMaxDate = 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['id']) ->max("a.end_date"); // plan date overlapped with assign_material_to_activity's, it should be m_activity's $plannedMaxDate = 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['id']) ->max("a.planned_end"); // plan date overlapped with assign_material_to_activity's, it should be m_activity' $maxDate = max(new \DateTime($plannedMaxDate), new \DateTime($actualMaxDate)); $end = new \DateTime($maxDate->format('Y-m-d') . ' Friday'); $end->modify('next Friday'); $end->modify('next Friday'); $interval = new \DateInterval('P7D'); } $period = new \DatePeriod($begin, $interval, $end); $arr_ActualM = []; $tempDate = []; $tempPercentagePlan = []; $tempPercentagePlanWhr = []; $tempPercentageReal = []; $tempTtlPercentPlan = 0; $tempTtlPercentActual = 0; $currentACWP = 0; $currentBCWP = 0; foreach ($period as $dt) { $minSevenDays = new \Datetime($dt->format("Y-m-d")); $minSevenDays = $minSevenDays->modify('-7 day')->format("Y-m-d"); $tempDate[] = array($dt->format("Y-m-d")); // $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['id']) // ->whereDate('ama.plan_date', '<=',$dt->format("Y-m-d")) // ->whereDate('ama.plan_date', '>', $minSevenDays) // ->get(); $activities = DB::table('m_activity AS a') ->join('assign_material_to_activity AS amta', 'amta.activity_id', '=', 'a.id') ->where('a.type_activity', 'task') ->where('a.bobot_planning', '>', 0) ->where('a.version_gantt_id', $keyGantt['id']) ->whereDate('amta.plan_date', '<=', $dt->format("Y-m-d")) ->whereDate('amta.plan_date', '>', $minSevenDays) ->select('a.bobot_planning', 'a.biaya_actual', 'a.duration', 'a.persentase_progress', 'a.id'); $dataPlanM = DB::table('m_activity AS a') ->join('assign_hr_to_activity AS ahta', 'ahta.activity_id', '=', 'a.id') ->where('a.type_activity', 'task') ->where('a.bobot_planning', '>', 0) ->where('a.version_gantt_id', $keyGantt['id']) ->whereDate('a.start_date', '<=', $dt->format("Y-m-d")) ->whereDate('a.start_date', '>', $minSevenDays) ->select('a.bobot_planning', 'a.biaya_actual', 'a.duration', 'a.persentase_progress', 'a.id') ->union($activities) ->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['id']) ->where('a.proyek_id', '=', $keyGantt['proyek_id']) ->whereDate('ram.report_date', '<=', $dt->format("Y-m-d")) ->whereDate('ram.report_date', '>', $minSevenDays) ->get(); $dataTempPlan = []; $x = 0; $sumPercentagePlan = 0; $totalACWP = isset($totalACWP) ? $totalACWP : 0; $totalBCWP = isset($totalBCWP) ? $totalBCWP : 0; foreach ($dataPlanM as $keyPlanM) { // $sumVolPlan = DB::table(function ($query) use ($keyGantt) { // $query->select('a.*') // ->from('m_activity AS a') // ->join('assign_material_to_activity as amta', 'amta.activity_id', '=', 'a.id') // ->where('a.type_activity', 'task') // ->where('a.bobot_planning', '>', 0) // ->where('a.version_gantt_id', $keyGantt['id']) // ->unionAll(function ($query) use ($keyGantt) { // $query->select('a.*') // ->from('m_activity AS a') // ->join('assign_hr_to_activity as ahta', 'ahta.activity_id', '=', 'a.id') // ->where('a.type_activity', 'task') // ->where('a.bobot_planning', '>', 0) // ->where('a.version_gantt_id', $keyGantt['id']); // }) // ->orderBy('id', 'asc'); // }, 'subquery') // ->sum('bobot_planning'); $sumVolPlan = DB::table('assign_material_to_activity') ->select('activity_id', DB::raw('SUM(qty_planning) as ttl_qty_plan')) ->where('activity_id', '=', $keyPlanM->id) ->groupBy('activity_id') ->first(); $weekCount = $keyPlanM->duration / 7; $weeklyPlan = $weekCount > 0 ? $sumVolPlan->ttl_qty_plan / $weekCount : 0; $weeklyProgress = $weeklyPlan / $sumVolPlan->ttl_qty_plan * $keyPlanM->bobot_planning; $dataTempPlan[$x]['activity_id'] = $keyPlanM->id; $dataTempPlan[$x]['bobot_planning'] = $keyPlanM->bobot_planning; $dataTempPlan[$x]['ttl_plan'] = $sumVolPlan; $dataTempPlan[$x]['biaya_actual'] = $keyPlanM->biaya_actual; $dataTempPlan[$x]['duration'] = $keyPlanM->duration; $dataTempPlan[$x]['persentase_progress'] = $keyPlanM->persentase_progress; try { $dataTempPlan[$x]['percentage'] = $keyPlanM->bobot_planning; $sumPercentagePlan += $weeklyProgress; if (isset($keyPlanM->duration) && $keyPlanM->duration > 0) $totalBCWP += (((($keyPlanM->persentase_progress * $keyPlanM->bobot_planning) / 100) / $keyPlanM->duration) * $totalRencanaBudget) / 100; else $totalBCWP = 0; $dataTempPlan[$x]['totalBCWP'] = $totalBCWP; } catch (\DivisionByZeroError $e) { return response()->json(['message' => $e->getMessage()]); } $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(); $sumReportActual = DB::table('report_activity_material') ->where('activity_id', $keyActualM->activity_id) ->sum('qty'); $reportCount = DB::table('report_activity_material')->where('activity_id', '=', $keyActualM->activity_id)->count(); $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; try { // assign_material_to_activity $checkStatusActivity = DB::table('assign_material_to_activity') ->select('activity_id', 'status_activity') ->where('activity_id', '=', $keyActualM->activity_id) ->orderBy('status_activity', 'ASC') ->first(); $dataTempReport[$w]['percentage'] = ($keyActualM->qty / $sumVolActual->ttl_qty_plan) * $keyActualM->bobot_planning; // $sumPercentageActual+=($keyActualM->qty/$sumVolActual->ttl_qty_plan)*$keyActualM->bobot_planning; // if($keyActualM->qty/$sumVolActual->ttl_qty_plan >= 1){ if ($checkStatusActivity->status_activity == 'done') { $sumPercentageActual += $keyActualM->bobot_planning / $reportCount; // $sumPercentageActual = $sumPercentageActual > $keyGantt['progress'] ? $keyGantt['progress'] : $sumPercentageActual; } else { if ($keyActualM->qty / $sumVolActual->ttl_qty_plan >= 1 || (int) $sumVolActual->ttl_qty_plan == (int) $sumReportActual) { $sumPercentageActual += (($keyActualM->qty / $sumVolActual->ttl_qty_plan) * $keyActualM->bobot_planning) * (95 / 100); // $sumPercentageActual = $sumPercentageActual > $keyGantt['progress'] ? $keyGantt['progress'] : $sumPercentageActual; } else { $sumPercentageActual += ($keyActualM->qty / $sumVolActual->ttl_qty_plan) * $keyActualM->bobot_planning; // $sumPercentageActual = $sumPercentageActual > $keyGantt['progress'] ? $keyGantt['progress'] : $sumPercentageActual; } } // }else { // if($checkStatusActivity->status_activity == 'done'){ // $sumPercentageActual+=($keyActualM->qty/$keyActualM->qty)*$keyActualM->bobot_planning; // }else{ // $sumPercentageActual+=($keyActualM->qty/$sumVolActual->ttl_qty_plan)*$keyActualM->bobot_planning; // } // } $totalACWP += $keyActualM->duration > 0 ? $keyActualM->biaya_actual / $keyActualM->duration : 0; } catch (\DivisionByZeroError $e) { return response()->json(['message' => $e->getMessage()]); } $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') { $tempTtlPercentPlan += $sumPercentagePlan; $tempTtlPercentActual += $sumPercentageActual; // if($tempTtlPercentPlan >= 100 || $tempTtlPercentActual >= $keyGantt['progress'];){ // if($tempTtlPercentActual >= 100) // $tempTtlPercentActual = 100; // if($tempTtlPercentPlan >= 100) // $tempTtlPercentPlan = 100; // if($tempTtlPercentActual >= $keyGantt['progress']) // $tempTtlPercentActual = $keyGantt['progress']; // todo // if ($tempTtlPercentPlan >= 100) // $tempTtlPercentPlan = 100; // $sumPercentageActual > $keyGantt['progress'] ? $keyGantt['progress'] : $sumPercentageActual // } $currentACWP += $totalACWP; $currentBCWP += $totalBCWP; $tempPercentage[] = array(round($tempTtlPercentPlan, 2), round($tempTtlPercentActual, 2)); $tempPercentagePlan[] = round($tempTtlPercentPlan, 2); $tempPercentagePlanWhr[] = ["weekly period", $tempPercentagePlan]; $tempPercentageReal[] = round($tempTtlPercentActual, 2); if ($tempTtlPercentPlan >= 100 && $tempTtlPercentActual >= 100) { break; } } else { $tempPercentage[] = array(round($sumPercentagePlan, 2), round($sumPercentageActual, 2)); $tempPercentagePlan[] = round($sumPercentagePlan, 2); $tempPercentageReal[] = round($sumPercentageActual, 2); } } try { if (round($totalACWP, 0) > $totalRencanaBudget) { $estimatedCost = round($totalACWP, 0) + 0; } else { $estimatedCost = ($totalRencanaBudget + 0); } } catch (\DivisionByZeroError $e) { return response()->json([ 'message' => $e->getMessage(), "line" => 566, 'gantt' => $keyGantt, ]); } $estimatedCost = $totalACWP > $totalRencanaBudget ? $totalACWP : $totalRencanaBudget; $costDeviation = $totalRencanaBudget - $estimatedCost; if ($costDeviation > 0) { $potential = "SAVING"; } else { $potential = $costDeviation == 0 ? "ON BUDGET" : "OVERRUN"; } $lastReal = $tempPercentageReal[count($tempPercentageReal) - 1]; $totalBCWP = $lastReal * $dataProject->rencana_biaya / 100; $dataResponse = array( "date" => $tempDate, "percentage" => $tempPercentage, "percentagePlan" => $tempPercentagePlan, "percentageReal" => $tempPercentageReal, "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, "gantt" => $keyGantt ); return $dataFinal; } public function calculateSCurve($projectId) { DB::enableQueryLog(); $dataFinal = []; $dataPayload = []; $dataPayload['period'] = 'week'; $totalACWP = 0; $totalBCWP = 0; $tempPercentage = []; $dataProject = Project::find($projectId); $dataHeader = Activity::where('type_activity', 'header')->where("proyek_id", $projectId)->first(); if (isset($dataPayload['end_date']) && $dataPayload['end_date'] > $dataProject->akhir_proyek) { $dataPayload['end_date'] = $dataProject->akhir_proyek; } if ($dataHeader) { $totalRencanaBudget = Activity::where('parent_id', $dataHeader->id)->where("proyek_id", $projectId)->sum("rencana_biaya"); } else { $totalRencanaBudget = Activity::whereNull('parent_id')->where("proyek_id", $projectId)->sum("rencana_biaya"); } $alreadyHasReport = DB::table('report_activity_material as a') ->select('a.id') ->join('m_activity as b', 'b.id', '=', 'a.activity_id') ->exists(); $minDate = $dataProject->mulai_proyek; $begin = new \DateTime($minDate . ' Monday'); $begin->modify('last Monday'); if (isset($dataPayload['end_date'])) { $maxDate = $dataPayload['end_date']; $end = new \DateTime($maxDate . ' Friday'); $end->modify('next Friday'); $end->modify('next Friday'); /* $interval = \DateInterval::createFromDateString('1 day'); */// should be using this but its bugged $interval = new \DateInterval('P7D'); } else { // $maxDate = DB::table('assign_material_to_activity as ama') // ->where("ama.proyek_id", $projectId) // ->join('m_activity as a', 'a.id', '=', 'ama.activity_id') // ->max("plan_date"); // plan date overlapped with assign_material_to_activity's, it should be m_activity's $maxDate = $dataProject->akhir_proyek; $end = new \DateTime($maxDate); $end->modify('next Friday'); $end->modify('next Friday'); $interval = new \DateInterval('P7D'); } $period = new \DatePeriod($begin, $interval, $end); $arr_ActualM = []; $tempDate = []; $tempPercentagePlan = []; $tempPercentagePlanWhr = []; $tempPercentageReal = []; $tempTtlPercentPlan = 0; $tempTtlPercentActual = 0; $currentACWP = 0; $currentBCWP = 0; foreach ($period as $dt) { $minSevenDays = new \Datetime($dt->format("Y-m-d")); $minSevenDays = $minSevenDays->modify('-7 day')->format("Y-m-d"); // $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['id']) // ->whereDate('ama.plan_date', '<=',$dt->format("Y-m-d")) // ->whereDate('ama.plan_date', '>', $minSevenDays) // ->get(); $activities = DB::table('m_activity AS a') ->join('assign_material_to_activity AS amta', 'amta.activity_id', '=', 'a.id') ->where('a.type_activity', 'task') ->where('a.bobot_planning', '>', 0) ->where('a.proyek_id', '=', $projectId) ->whereDate('amta.plan_date', '<=', $dt->format("Y-m-d")) ->whereDate('amta.plan_date', '>', $minSevenDays) ->select('a.bobot_planning', 'a.biaya_actual', 'a.duration', 'a.persentase_progress', 'a.id'); $dataPlanM = DB::table('m_activity AS a') ->join('assign_hr_to_activity AS ahta', 'ahta.activity_id', '=', 'a.id') ->where('a.type_activity', 'task') ->where('a.bobot_planning', '>', 0) ->where('a.proyek_id', '=', $projectId) ->whereDate('a.start_date', '<=', $dt->format("Y-m-d")) ->whereDate('a.start_date', '>', $minSevenDays) ->select('a.bobot_planning', 'a.biaya_actual', 'a.duration', 'a.persentase_progress', 'a.id') ->union($activities) ->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.proyek_id', '=', $projectId) ->whereDate('ram.report_date', '<=', $dt->format("Y-m-d")) ->whereDate('ram.report_date', '>', $minSevenDays) ->get(); $dataTempPlan = []; $x = 0; $sumPercentagePlan = 0; $totalACWP = isset($totalACWP) ? $totalACWP : 0; $totalBCWP = isset($totalBCWP) ? $totalBCWP : 0; foreach ($dataPlanM as $keyPlanM) { // $sumVolPlan = DB::table(function ($query) use ($projectId) { // $query->select('a.*') // ->from('m_activity AS a') // ->join('assign_material_to_activity as amta', 'amta.activity_id', '=', 'a.id') // ->where('a.type_activity', 'task') // ->where('a.bobot_planning', '>', 0) // ->where('a.proyek_id', $projectId) // ->unionAll(function ($query) use ($projectId) { // $query->select('a.*') // ->from('m_activity AS a') // ->join('assign_hr_to_activity as ahta', 'ahta.activity_id', '=', 'a.id') // ->where('a.type_activity', 'task') // ->where('a.bobot_planning', '>', 0) // ->where('a.proyek_id', $projectId); // })->orderBy('id', 'asc'); // }, 'subquery') // ->sum('bobot_planning'); $sumVolPlan = DB::table('assign_material_to_activity') ->select('activity_id', DB::raw('SUM(qty_planning) as ttl_qty_plan')) ->where('activity_id', '=', $keyPlanM->id) ->groupBy('activity_id') ->first(); $weekCount = $keyPlanM->duration / 7; $weeklyPlan = $sumVolPlan->ttl_qty_plan / $weekCount; $weeklyProgress = $weeklyPlan / $sumVolPlan->ttl_qty_plan * $keyPlanM->bobot_planning; $dataTempPlan[$x]['activity_id'] = $keyPlanM->id; $dataTempPlan[$x]['bobot_planning'] = $keyPlanM->bobot_planning; $dataTempPlan[$x]['ttl_plan'] = $sumVolPlan; $dataTempPlan[$x]['biaya_actual'] = $keyPlanM->biaya_actual; $dataTempPlan[$x]['duration'] = $keyPlanM->duration; $dataTempPlan[$x]['persentase_progress'] = $keyPlanM->persentase_progress; try { $dataTempPlan[$x]['percentage'] = $keyPlanM->bobot_planning; $sumPercentagePlan += $weeklyProgress; if (isset($keyPlanM->duration) && $keyPlanM->duration > 0) $totalBCWP += (((($keyPlanM->persentase_progress * $keyPlanM->bobot_planning) / 100) / $keyPlanM->duration) * $totalRencanaBudget) / 100; else $totalBCWP = 0; $dataTempPlan[$x]['totalBCWP'] = $totalBCWP; } catch (\DivisionByZeroError $e) { return response()->json(['message' => $e->getMessage()]); } $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(); if (!isset($sumVolActual)) { $sumVolActual = (object) [ 'activity_id' => $keyActualM->activity_id, 'ttl_qty_plan' => "0" ]; } $sumReportActual = DB::table('report_activity_material') ->where('activity_id', $keyActualM->activity_id) ->sum('qty'); $reportCount = DB::table('report_activity_material')->where('activity_id', '=', $keyActualM->activity_id)->count(); $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; try { // assign_material_to_activity $checkStatusActivity = DB::table('assign_material_to_activity') ->select('activity_id', 'status_activity') ->where('activity_id', '=', $keyActualM->activity_id) ->orderBy('status_activity', 'ASC') ->first(); if (!isset($checkStatusActivity)) { $checkStatusActivity = (object) [ 'activity_id' => $keyActualM->activity_id, 'status_activity' => 'open' ]; } if ($sumVolActual->ttl_qty_plan == "0") { $actual = 0; } else { $actual = $keyActualM->qty / $sumVolActual->ttl_qty_plan; } $dataTempReport[$w]['percentage'] = $actual * $keyActualM->bobot_planning; // $sumPercentageActual+=($keyActualM->qty/$sumVolActual->ttl_qty_plan)*$keyActualM->bobot_planning; // if($keyActualM->qty/$sumVolActual->ttl_qty_plan >= 1){ if ($checkStatusActivity->status_activity == 'done') { $sumPercentageActual += $keyActualM->bobot_planning / $reportCount; // $sumPercentageActual = $sumPercentageActual > $keyGantt['progress'] ? $keyGantt['progress'] : $sumPercentageActual; } else { if ( $actual >= 1 || (int) $sumVolActual->ttl_qty_plan == (int) $sumReportActual) { $sumPercentageActual += ($actual * $keyActualM->bobot_planning) * (95 / 100); // $sumPercentageActual = $sumPercentageActual > $keyGantt['progress'] ? $keyGantt['progress'] : $sumPercentageActual; } else { $sumPercentageActual += $actual * $keyActualM->bobot_planning; // $sumPercentageActual = $sumPercentageActual > $keyGantt['progress'] ? $keyGantt['progress'] : $sumPercentageActual; } } // }else { // if($checkStatusActivity->status_activity == 'done'){ // $sumPercentageActual+=($keyActualM->qty/$keyActualM->qty)*$keyActualM->bobot_planning; // }else{ // $sumPercentageActual+=($keyActualM->qty/$sumVolActual->ttl_qty_plan)*$keyActualM->bobot_planning; // } // } $totalACWP += $keyActualM->duration > 0 ? $keyActualM->biaya_actual / $keyActualM->duration : 0; } catch (\DivisionByZeroError $e) { return response()->json(['message' => $e->getMessage()]); } $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') { $tempTtlPercentPlan += $sumPercentagePlan; $tempTtlPercentActual += $sumPercentageActual; // todo // if ($tempTtlPercentPlan >= 100) // $tempTtlPercentPlan = 100; $currentACWP += $totalACWP; $currentBCWP += $totalBCWP; $tempPercentage[] = array(round($tempTtlPercentPlan, 2), round($tempTtlPercentActual, 2)); $tempPercentagePlan[] = round($tempTtlPercentPlan, 2); $tempPercentagePlanWhr[] = ["weekly period", $tempPercentagePlan]; $tempPercentageReal[] = round($tempTtlPercentActual, 2); if ($tempTtlPercentPlan >= 100 && $tempTtlPercentActual >= 100) { break; } } else { $tempPercentage[] = array(round($sumPercentagePlan, 2), round($sumPercentageActual, 2)); $tempPercentagePlan[] = round($sumPercentagePlan, 2); $tempPercentageReal[] = round($sumPercentageActual, 2); } $tempDate[] = array($dt->format("Y-m-d")); } try { if (round($totalACWP, 0) > $totalRencanaBudget) { $estimatedCost = round($totalACWP, 0) + 0; } else { $estimatedCost = ($totalRencanaBudget + 0); } } catch (\DivisionByZeroError $e) { return response()->json([ 'message' => $e->getMessage(), "line" => 566, ]); } $estimatedCost = $totalACWP > $totalRencanaBudget ? $totalACWP : $totalRencanaBudget; $costDeviation = $totalRencanaBudget - $estimatedCost; if ($costDeviation > 0) { $potential = "SAVING"; } else { $potential = $costDeviation == 0 ? "ON BUDGET" : "OVERRUN"; } $lastReal = $tempPercentageReal[count($tempPercentageReal) - 1]; $totalBCWP = $lastReal * $dataProject->rencana_biaya / 100; $dataResponse = array( "date" => $tempDate, "percentage" => $tempPercentage, "percentagePlan" => $tempPercentagePlan, "percentageReal" => $tempPercentageReal, "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, ); return $dataFinal; } public function calculateProgressBasedOnSimple($keyGantt) { DB::enableQueryLog(); $dataFinal = []; $dataPayload = []; $dataPayload['period'] = 'week'; $dataProject = Project::find($keyGantt['proyek_id']); $dataHeader = Activity::where('type_activity', 'header')->where("proyek_id", $keyGantt['proyek_id'])->where("version_gantt_id", $keyGantt['id'])->first(); if (isset($dataPayload['end_date']) && $dataPayload['end_date'] > $dataProject->akhir_proyek) { $dataPayload['end_date'] = $dataProject->akhir_proyek; } if ($dataHeader) { $totalRencanaBudget = Activity::where('parent_id', $dataHeader->id)->where("proyek_id", $keyGantt['proyek_id'])->where("version_gantt_id", $keyGantt['id'])->sum("rencana_biaya"); } else { $totalRencanaBudget = Activity::whereNull('parent_id')->where("proyek_id", $keyGantt['proyek_id'])->where("version_gantt_id", $keyGantt['id'])->sum("rencana_biaya"); } if (!Activity::where("version_gantt_id", $keyGantt['id'])->first()) return $dataFinal; // $alreadyHasReport = DB::table('report_activity_material as a') // ->select('a.id') // ->join('m_activity as b', 'b.id', '=', 'a.activity_id') // ->where('b.version_gantt_id', '=', $keyGantt['id']) // ->exists(); // if(!$alreadyHasReport) // return $dataFinal; $minDate = Activity::where('version_gantt_id', $keyGantt['id'])->whereNull('parent_id')->pluck('start_date')->first(); $begin = new \DateTime($minDate . ' Monday'); if (isset($dataPayload['end_date'])) { $maxDate = $dataPayload['end_date']; $end = new \DateTime($maxDate); /* $interval = \DateInterval::createFromDateString('1 day'); */// should be using this but its bugged $interval = new \DateInterval('P7D'); } else { // $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['id']) // ->max("plan_date"); // plan date overlapped with assign_material_to_activity's, it should be m_activity's $maxDate = Activity::where('version_gantt_id', $keyGantt['id'])->whereNull('parent_id')->pluck('end_date')->first(); $end = new \DateTime($maxDate . ' Friday'); $interval = new \DateInterval('P7D'); } $period = new \DatePeriod($begin, $interval, $end); $arr_ActualM = []; $tempDate = []; $tempPercentagePlan = []; $tempPercentagePlanWhr = []; $tempPercentageReal = []; $tempTtlPercentPlan = 0; $tempTtlPercentActual = 0; $currentACWP = 0; $currentBCWP = 0; foreach ($period as $dt) { $minSevenDays = new \Datetime($dt->format("Y-m-d")); $minSevenDays = $minSevenDays->modify('-7 day')->format("Y-m-d"); $dataPlanM = DB::table('m_activity') ->select('id as activity_id', 'bobot_planning', 'start_date', 'biaya_actual', 'duration', 'persentase_progress') // ->join('m_activity as a', 'a.id', '=', 'activity_id') ->where('proyek_id', '=', $keyGantt['proyek_id']) ->where('type_activity', '=', 'task') ->where('version_gantt_id', '=', $keyGantt['id']) ->whereDate('start_date', '<=', $dt->format("Y-m-d")) ->whereDate('start_date', '>', $minSevenDays) ->get(); $dataActualM = DB::table('m_activity as a') ->select('mapl.id as id_progress_log', 'mapl.activity_id', 'mapl.variance', 'mapl.created_at', 'a.bobot_planning', 'a.biaya_actual', 'a.duration', 'a.persentase_progress') ->join('m_activity_progress_log as mapl', 'a.id', '=', 'mapl.activity_id') ->where('a.version_gantt_id', '=', $keyGantt['id']) ->where('a.type_activity', '=', 'task') ->where('mapl.variance', '>', 0) ->where('a.proyek_id', '=', $keyGantt['proyek_id']) ->whereDate('mapl.created_at', '<=', $dt->format("Y-m-d")) ->whereDate('mapl.created_at', '>', $minSevenDays) ->get(); $dataTempPlan = []; $x = 0; $sumPercentagePlan = 0; $totalACWP = isset($totalACWP) ? $totalACWP : 0; $totalBCWP = isset($totalBCWP) ? $totalBCWP : 0; foreach ($dataPlanM as $keyPlanM) { $dataTempPlan[$x]['activity_id'] = $keyPlanM->activity_id; $dataTempPlan[$x]['qty_plan'] = $keyPlanM->bobot_planning; $dataTempPlan[$x]['plan_date'] = $keyPlanM->start_date; $dataTempPlan[$x]['start_activity'] = $keyPlanM->start_date; $dataTempPlan[$x]['bobot_planning'] = $keyPlanM->bobot_planning; $dataTempPlan[$x]['ttl_plan'] = $keyPlanM->bobot_planning; $dataTempPlan[$x]['biaya_actual'] = $keyPlanM->biaya_actual; $dataTempPlan[$x]['duration'] = $keyPlanM->duration; $dataTempPlan[$x]['persentase_progress'] = $keyPlanM->persentase_progress; try { $dataTempPlan[$x]['percentage'] = $keyPlanM->bobot_planning; $sumPercentagePlan += $keyPlanM->bobot_planning; $totalBCWP += 0; $dataTempPlan[$x]['totalBCWP'] = $totalBCWP; } catch (\DivisionByZeroError $e) { return response()->json(['message' => $e->getMessage()]); } $x++; } $w = 0; $dataTempReport = []; $sumPercentageActual = 0; foreach ($dataActualM as $keyActualM) { $sumVolActual = DB::table('m_activity_progress_log') ->select('id', DB::raw('SUM(variance) as ttl_percen_act')) ->where('id', '=', $keyActualM->id_progress_log) ->groupBy('id') ->first(); $dataTempReport[$w]['id_progress_log'] = $keyActualM->id_progress_log; // $dataTempReport [$w]['qty'] = $keyActualM->qty; $dataTempReport[$w]['report_date'] = $keyActualM->created_at; $dataTempReport[$w]['bobot_planning'] = $keyActualM->bobot_planning; // $dataTempReport [$w]['ttl_plan'] = $sumVolActual->ttl_percen_act ? $sumVolActual->ttl_percen_act : 0; $dataTempReport[$w]['biaya_actual'] = $keyActualM->biaya_actual; $dataTempReport[$w]['duration'] = $keyActualM->duration; $dataTempReport[$w]['persentase_progress'] = $keyActualM->persentase_progress; try { $dataTempReport[$w]['percentage'] = $sumVolActual->ttl_percen_act ? ($sumVolActual->ttl_percen_act / 100) * $keyActualM->bobot_planning : 0; $sumPercentageActual += $sumVolActual->ttl_percen_act ? ($sumVolActual->ttl_percen_act / 100) * $keyActualM->bobot_planning : 0; $totalACWP += $keyActualM->biaya_actual / $keyActualM->duration; } catch (\DivisionByZeroError $e) { return response()->json(['message' => $e->getMessage()]); } $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') { $tempTtlPercentPlan += $sumPercentagePlan; $tempTtlPercentActual += $sumPercentageActual; if ($tempTtlPercentPlan >= 100 || $tempTtlPercentActual >= 100) { if ($tempTtlPercentActual >= 100) $tempTtlPercentActual = 100; if ($tempTtlPercentPlan >= 100) $tempTtlPercentPlan = 100; } $currentACWP += $totalACWP; $currentBCWP += $totalBCWP; $tempPercentage[] = array(round($tempTtlPercentPlan, 2), round($tempTtlPercentActual, 2)); $tempPercentagePlan[] = round($tempTtlPercentPlan, 2); $tempPercentagePlanWhr[] = ["weekly period", $tempPercentagePlan]; $tempPercentageReal[] = round($tempTtlPercentActual, 2); if ($tempTtlPercentPlan >= 100 && $tempTtlPercentActual >= 100) { break; } } else { $tempPercentage[] = array(round($sumPercentagePlan, 2), round($sumPercentageActual, 2)); $tempPercentagePlan[] = round($sumPercentagePlan, 2); $tempPercentageReal[] = round($sumPercentageActual, 2); } $tempDate[] = array($dt->format("Y-m-d")); } try { if (round($totalACWP, 0) > $totalRencanaBudget) { $estimatedCost = round($totalACWP, 0) + 0; } else { $estimatedCost = ($totalRencanaBudget + 0); } } catch (\DivisionByZeroError $e) { return response()->json([ 'message' => $e->getMessage(), "line" => 566, 'gantt' => $keyGantt, ]); } $estimatedCost = $totalACWP > $totalRencanaBudget ? $totalACWP : $totalRencanaBudget; $costDeviation = $totalRencanaBudget - $estimatedCost; if ($costDeviation > 0) { $potential = "SAVING"; } else { $potential = $costDeviation == 0 ? "ON BUDGET" : "OVERRUN"; } $dataResponse = array( "date" => $tempDate, "percentage" => $tempPercentage, "percentagePlan" => $tempPercentagePlan, "percentageReal" => $tempPercentageReal, "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, "gantt" => $keyGantt, ); return $dataFinal; } }