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 static function getSCurveCarausell($request) { $allGantt = []; if (!is_int($request->gantt_id) && !is_int($request->project_id) && !is_int($request->period)) { if (isset($request->gantt_id)) { $allGantt[] = $request->gantt_id; } else { $allGantt[] = MasterFunctionsHelper::getLatestGantt($request->project_id); } } else { $allGantt[] = MasterFunctionsHelper::getLatestGantt($request->project_id); } foreach ($allGantt as $gantt) { if (!isset($gantt['last_gantt_id'])) { $ganttId = $gantt; } else { $ganttId = $gantt['last_gantt_id']; } $gantt = VersionGantt::find($ganttId)->toArray(); 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 calculateProgressBasedOnReportMaterialOld($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; $minDate = Activity::where('version_gantt_id', $keyGantt['id'])->whereNull('parent_id')->pluck('start_date')->first(); $begin = new \DateTime($minDate); $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")); $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(); if ($keyPlanM->duration) { $weekCount = $keyPlanM->duration / 7; $weeklyPlan = $weekCount >= 1 ? $sumVolPlan->ttl_qty_plan / $weekCount : $sumVolPlan->ttl_qty_plan / $weekCount / 7; // $weeklyProgress = $sumVolPlan->ttl_qty_plan * $keyPlanM->bobot_planning; $weeklyProgress = $weeklyPlan / $sumVolPlan->ttl_qty_plan * $keyPlanM->bobot_planning; // $bobotHari = $keyPlanM->bobot_planning / $keyPlanM->duration; } else { // $weeklyProgress = 0; $weekCount = 1 / 7; $weeklyPlan = $weekCount >= 1 ? $sumVolPlan->ttl_qty_plan / $weekCount : $sumVolPlan->ttl_qty_plan / $weekCount / 7; // $weeklyProgress = $sumVolPlan->ttl_qty_plan * $keyPlanM->bobot_planning; $weeklyProgress = $weeklyPlan / $sumVolPlan->ttl_qty_plan * $keyPlanM->bobot_planning; } // $weeklyPlan = $weekCount > 0 ? $keyPlanM->bobot_planning / $weekCount : 0; // $weeklyProgress = $weeklyPlan * $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, ); $today = new DateTime(); $date = new DateTime($dt->format("Y-m-d")); if (isset($dataPayload['period']) && $dataPayload['period'] == 'week') { $tempTtlPercentPlan += $sumPercentagePlan; $tempTtlPercentActual += $sumPercentageActual; $currentACWP += $totalACWP; $currentBCWP += $totalBCWP; $tempPercentage[] = array(round($tempTtlPercentPlan, 2), round($tempTtlPercentActual, 2)); $tempPercentagePlan[] = round($tempTtlPercentPlan, 2); $tempPercentagePlanWhr[] = ["weekly period", $tempPercentagePlan]; if ($date < $today) { $tempPercentageReal[] = round($tempTtlPercentActual, 2); } if ($tempTtlPercentPlan >= 100 && $tempTtlPercentActual >= 100) { break; } } else { $tempPercentage[] = array(round($sumPercentagePlan, 2), round($sumPercentageActual, 2)); $tempPercentagePlan[] = round($sumPercentagePlan, 2); if ($date < $today) { $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 calculateProgressBasedOnReportMaterial($keyGantt) { DB::enableQueryLog(); $dataFinal = []; $dataPayload = []; $dataPayload['period'] = 'week'; // $totalACWP = 0; // $totalBCWP = 0; // $tempPercentage = []; $dataProject = Project::find($keyGantt['proyek_id']); if (isset($dataPayload['end_date']) && $dataPayload['end_date'] > $dataProject->akhir_proyek) { $dataPayload['end_date'] = $dataProject->akhir_proyek; } if (!Activity::where("version_gantt_id", $keyGantt['id'])->first()) return $dataFinal; $activityQueryBuilder = Activity::where('version_gantt_id', $keyGantt['id'])->whereNull('parent_id'); $activityData = $activityQueryBuilder->first(); $minDate = $activityQueryBuilder->pluck('start_date')->first(); $begin = new \DateTime($minDate); $begin = $begin->modify('-1 day'); 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('P1D'); } 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('P1D'); } $period = new \DatePeriod($begin, $interval, $end); // $arr_ActualM = []; $tempDate = []; // $tempPercentagePlan = []; // $tempPercentagePlanWhr = []; // $tempPercentageReal = []; // $tempTtlPercentPlan = 0; // $tempTtlPercentActual = 0; // $currentACWP = 0; // $currentBCWP = 0; $dataActivityPlanDate = []; $progressPlanKomulatifWeek = []; $progressActualKomulatifWeek = []; $progressPlanBar = 0; $dateWeek = []; $tmpProgressPlanWeek = 0; $tmpProgressActualWeek = 0; foreach ($period as $dt) { $loopDay = $dt->format("Y-m-d"); //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('m_activity') ->where('type_activity', 'task') ->where('bobot_planning', '>', 0) ->where('version_gantt_id', $keyGantt['id']) ->whereDate('planned_start', '<=', $loopDay) ->whereDate('planned_end', '>=', $loopDay) ->select('name', 'bobot_planning', 'biaya_actual', 'duration', 'persentase_progress', 'id', 'planned_start', 'planned_end') ->get(); $dataActualM = DB::table('report_activity_material as ram') ->join('m_activity as ma', 'ma.id', '=', 'ram.activity_id') ->select( 'ram.activity_id', 'ram.qty as qty_actual', 'ma.bobot_planning', 'ma.name', DB::raw('(SELECT SUM(amta.qty_planning) FROM assign_material_to_activity amta WHERE amta.activity_id = ram.activity_id) AS qty_plan'), DB::raw('(SELECT SUM(ram.qty) FROM report_activity_material ram WHERE ram.activity_id = ma.id) AS sum_qty_actual'), DB::raw('(SELECT DISTINCT status_activity FROM assign_material_to_activity amta WHERE amta.activity_id = ram.activity_id) AS status_activity'), DB::raw('(SELECT COUNT(id) FROM report_activity_material ram WHERE ram.activity_id = ma.id) AS count_report') ) ->where('ram.report_date', $loopDay) ->where('ma.version_gantt_id', $keyGantt['id']) ->get(); $dataActivityPlan = []; $dataActivityActual = []; $today = date('Y-m-d'); // if (new \DateTime($loopDay) < $today) { // $statusCutOfDate = true; // } // $progressPlanKomulatifWeek[] = array('date' => $loopDay, 'progress' =>round($tmpProgressPlanWeek, 2)); // // loop cut off day // if ($loopDay <= $today) { // // $tempPercentageReal[] = round($tempTtlPercentActual, 2); // $progressActualKomulatifWeek[] = round($tmpProgressActualWeek, 2); // $progressPlanBar[] = array('date' => $loopDay, 'progress' =>round($tmpProgressPlanWeek, 2));//$progressPlanKomulatifWeek; // // $progressPlanKomulatifWeek[] += round($tmpProgressPlanWeek, 2); // } $dateWeek[] = [$loopDay]; // $progressPlanKomulatifWeek[] += $tmpProgressPlanWeek; // loop per activity by day foreach ($dataPlanM as $keyPlanM) { # hitung untuk persentase progress planning // if($keyPlanM->duration == 0){ // $duration = 2; // Tanggal awal $startDate = new DateTime($keyPlanM->planned_start); // Tanggal akhir $endDate = new DateTime($keyPlanM->planned_end); // Menghitung selisih hari $interval = $startDate->diff($endDate); // Mengambil hasil selisih hari $duration = (int) $interval->days + 1; // }else{ // $duration = $keyPlanM->duration + 2; // } // $startPlan = new DateTime($keyPlanM->planned_start); // $endPlan = new DateTime($keyPlanM->planned_end); // $interval = $startPlan->diff($endPlan); // // Mengambil hasil selisih hari // $duration = $interval->days; $progressPlanWeek = $keyPlanM->bobot_planning / $duration; $dataActivityPlan[] = array( 'progressPlanDay' => $progressPlanWeek, 'name' => $keyPlanM->name, 'bobot_p' => $keyPlanM->bobot_planning, 'duration' => $keyPlanM->duration ); $tmpProgressPlanWeek += $progressPlanWeek; } // hitung progress actual foreach ($dataActualM as $keyActualM) { # hitung untuk persentase progress actual // $progressActualWeek = ((((($keyActualM->qty_actual / $keyActualM->sum_qty_actual) * 100) / $keyActualM->qty_plan)*100)*$keyActualM->bobot_planning)/100; // jika total report > dari planning if ($keyActualM->sum_qty_actual > $keyActualM->qty_plan) { $progressActualWeek = ($keyActualM->qty_actual / $keyActualM->sum_qty_actual) * $keyActualM->bobot_planning; } else { // jika total report < dari planning // $progressActualWeek = ((($keyActualM->qty_actual / $keyActualM->sum_qty_actual) * 100) / $keyActualM->qty_plan)*$keyActualM->bobot_planning; if ($keyActualM->qty_actual == 0) { $progressActualWeek = 0; } else { $progressActualWeek = ($keyActualM->qty_actual / $keyActualM->qty_plan) * $keyActualM->bobot_planning; } } if ($keyActualM->status_activity == 'done') { $progressActualWeek = $keyActualM->bobot_planning / $keyActualM->count_report; } else { $progressActualWeek = $progressActualWeek > ($keyActualM->bobot_planning * 95) / 100 ? ($keyActualM->bobot_planning * 95) / 100 : $progressActualWeek; } $dataActivityActual[] = array( 'progressActualDay' => $progressActualWeek, 'qty_act' => $keyActualM->qty_actual, 'bobot_p' => $keyActualM->bobot_planning, 'qty_plan' => $keyActualM->qty_plan, 'status_activity' => $keyActualM->status_activity, 'sum_qty_actual' => $keyActualM->sum_qty_actual, 'name' => $keyActualM->name ); $tmpProgressActualWeek += $progressActualWeek; } $progressPlanKomulatifWeek[] = round($tmpProgressPlanWeek, 2); // loop cut off day if ($loopDay <= $today) { if(round($tmpProgressActualWeek, 2) > $activityData['persentase_progress']) { $progressActualKomulatifWeek[] = $activityData['persentase_progress']; } else { $progressActualKomulatifWeek[] = round($tmpProgressActualWeek, 2); } // For Planning $progressPlanBar = round($tmpProgressPlanWeek, 2); } $dataActivityPlanDate[] = array( "date" => $loopDay, "statusWeek" => new \DateTime($loopDay) == new \DateTime($loopDay . ' Friday') ? true : false, "activity-plan" => $dataActivityPlan, "activity-actual" => $dataActivityActual, "tmpProgressActualWeek" => $tmpProgressActualWeek, "progressPlanWeek" => $tmpProgressPlanWeek ); } $dataFinal[] = array( // "date" => $dateWeek, "proyek_name" => $dataProject->nama, "data" => [ "date" => $dateWeek, "percentagePlan" => $progressPlanKomulatifWeek, "percentageReal" => $progressActualKomulatifWeek, "data_details" => $dataActivityPlanDate, "progressPlanToDay" => $progressPlanBar ], // "gantt" => $keyGantt ); return $dataFinal; } public function calculateSCurveOld($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); $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(); if ($keyPlanM->duration) { $weekCount = $keyPlanM->duration / 7; $weeklyPlan = $weekCount >= 1 ? $sumVolPlan->ttl_qty_plan / $weekCount : $sumVolPlan->ttl_qty_plan / $weekCount / 7; // $weeklyProgress = $sumVolPlan->ttl_qty_plan * $keyPlanM->bobot_planning; $weeklyProgress = $weeklyPlan / $sumVolPlan->ttl_qty_plan * $keyPlanM->bobot_planning; // $bobotHari = $keyPlanM->bobot_planning / $keyPlanM->duration; } else { // $weeklyProgress = 0; $weekCount = 1 / 7; $weeklyPlan = $weekCount >= 1 ? $sumVolPlan->ttl_qty_plan / $weekCount : $sumVolPlan->ttl_qty_plan / $weekCount / 7; // $weeklyProgress = $sumVolPlan->ttl_qty_plan * $keyPlanM->bobot_planning; $weeklyProgress = $weeklyPlan / $sumVolPlan->ttl_qty_plan * $keyPlanM->bobot_planning; } // $weeklyPlan = $sumVolPlan->ttl_qty_plan / $weekCount; // $weeklyProgress = 80; $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, ); $today = new DateTime(); $date = new DateTime($dt->format("Y-m-d")); 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]; if ($date < $today) { $tempPercentageReal[] = round($tempTtlPercentActual, 2); } // if ($tempTtlPercentPlan >= 100 && $tempTtlPercentActual >= 100) { // break; // } } else { $tempPercentage[] = array(round($sumPercentagePlan, 2), round($sumPercentageActual, 2)); $tempPercentagePlan[] = round($sumPercentagePlan, 2); if ($date < $today) { $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]; // $lastReal = $tempPercentageReal[count($tempPercentageReal) < 1 ? count($tempPercentageReal) : count($tempPercentageReal) - 1]; // $totalBCWP = $lastReal * $dataProject->rencana_biaya / 100; $dataResponse = array( "date" => $tempDate, "start" => $minDate, "begin" => $begin, // "periode" => $period, "end" => $end, "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 calculateSCurve($projectId) { DB::enableQueryLog(); $dataFinal = []; $dataPayload = []; $dataPayload['period'] = 'week'; $dataProject = Project::find($projectId); if (isset($dataPayload['end_date']) && $dataPayload['end_date'] > $dataProject->akhir_proyek) { $dataPayload['end_date'] = $dataProject->akhir_proyek; } $minDate = $dataProject->mulai_proyek; $begin = new \DateTime($minDate); $begin = $begin->modify('-1 day'); if (isset($dataPayload['end_date'])) { $maxDate = $dataPayload['end_date']; $end = new \DateTime($maxDate . ' Friday'); $interval = new \DateInterval('P1D'); } else { $maxDate = $dataProject->akhir_proyek; $end = new \DateTime($maxDate); $end = new \DateTime($end->format('Y-m-d') . ' Friday'); $interval = new \DateInterval('P1D'); } $period = new \DatePeriod($begin, $interval, $end); $tempDate = []; $dataActivityPlanDate = []; $progressPlanKomulatifWeek = []; $progressActualKomulatifWeek = []; $dateWeek = []; $tmpProgressPlanWeek = 0; $tmpProgressActualWeek = 0; foreach ($period as $dt) { $loopDay = $dt->format("Y-m-d"); $tempDate[] = array($dt->format("Y-m-d")); $dataPlanM = []; $dataActualM = []; $dataPlanM = DB::table('m_activity') ->where('type_activity', 'task') ->where('bobot_planning', '>', 0) ->where('proyek_id', $projectId) ->whereDate('planned_start', '<=', $loopDay) ->whereDate('planned_end', '>=', $loopDay) ->select('name', 'bobot_planning', 'biaya_actual', 'duration', 'persentase_progress', 'id', 'planned_start', 'planned_end') ->get(); $dataActualM = DB::table('report_activity_material as ram') ->join('m_activity as ma', 'ma.id', '=', 'ram.activity_id') ->select( 'ram.activity_id', 'ram.qty as qty_actual', 'ma.bobot_planning', 'ma.name', DB::raw('(SELECT SUM(amta.qty_planning) FROM assign_material_to_activity amta WHERE amta.activity_id = ram.activity_id) AS qty_plan'), DB::raw('(SELECT SUM(ram.qty) FROM report_activity_material ram WHERE ram.activity_id = ma.id) AS sum_qty_actual'), DB::raw('(SELECT DISTINCT status_activity FROM assign_material_to_activity amta WHERE amta.activity_id = ram.activity_id) AS status_activity'), DB::raw('(SELECT COUNT(id) FROM report_activity_material ram WHERE ram.activity_id = ma.id) AS count_report') ) ->where('ram.report_date', $loopDay) ->where('ma.proyek_id', $projectId) ->get(); $dataActivityPlan = []; $dataActivityActual = []; $today = date('Y-m-d'); // Hitung Plan $dateWeek[] = [$loopDay]; foreach ($dataPlanM as $keyPlanM) { # hitung untuk persentase progress planning // if($keyPlanM->duration == 0){ // $duration = 2; // Tanggal awal $startDate = new DateTime($keyPlanM->planned_start); // Tanggal akhir $endDate = new DateTime($keyPlanM->planned_end); // Menghitung selisih hari $interval = $startDate->diff($endDate); // Mengambil hasil selisih hari $duration = (int) $interval->days + 1; // }else{ // $duration = $keyPlanM->duration + 2; // } // $startPlan = new DateTime($keyPlanM->planned_start); // $endPlan = new DateTime($keyPlanM->planned_end); // $interval = $startPlan->diff($endPlan); // // Mengambil hasil selisih hari // $duration = $interval->days; // 2023-07-26 $progressPlanWeek = $keyPlanM->bobot_planning / $duration; $dataActivityPlan[] = array( 'progressPlanDay' => $progressPlanWeek, 'name' => $keyPlanM->name, 'bobot_p' => $keyPlanM->bobot_planning, 'duration' => $keyPlanM->duration ); $tmpProgressPlanWeek += $progressPlanWeek; } // hitung progress actual foreach ($dataActualM as $keyActualM) { # hitung untuk persentase progress actual // $progressActualWeek = ((((($keyActualM->qty_actual / $keyActualM->sum_qty_actual) * 100) / $keyActualM->qty_plan)*100)*$keyActualM->bobot_planning)/100; // jika total report > dari planning if ($keyActualM->sum_qty_actual > $keyActualM->qty_plan) { $progressActualWeek = (($keyActualM->qty_actual / $keyActualM->sum_qty_actual) * 100) * $keyActualM->bobot_planning / 100; } else { // jika total report < dari planning // $progressActualWeek = ((($keyActualM->qty_actual / $keyActualM->sum_qty_actual) * 100) / $keyActualM->qty_plan)*$keyActualM->bobot_planning; if ($keyActualM->qty_actual == 0) { $progressActualWeek = 0; } else { $progressActualWeek = ($keyActualM->qty_actual / $keyActualM->qty_plan) * $keyActualM->bobot_planning; } } if ($keyActualM->status_activity == 'done') { // if($keyActualM->sum_qty_actual > $keyActualM->qty_plan){ // } // if($progressActualWeek > $keyActualM->bobot_planning){ // $progressActualWeek = $keyActualM->bobot_planning; // }else if($keyActualM->qty_actual == 0){ // $progressActualWeek = $keyActualM->bobot_planning; // }else if($keyActualM->qty_plan == $keyActualM->sum_qty_actual){ $progressActualWeek = $keyActualM->bobot_planning / $keyActualM->count_report; // }else { // $progressActualWeek = $progressActualWeek; // } // $progressActualWeek = $progressActualWeek > $keyActualM->bobot_planning ? $keyActualM->bobot_planning : $progressActualWeek; // jika report lebih dari 1 x, maka harusnya di bagi sabanyak jumlah report, // contoh ada 3 report, report ke 1 adalah 5 maka 100/3 dan di looping } else { $progressActualWeek = $progressActualWeek > ($keyActualM->bobot_planning * 95) / 100 ? ($keyActualM->bobot_planning * 95) / 100 : $progressActualWeek; } $dataActivityActual[] = array( 'progressActualDay' => $progressActualWeek, 'qty_act' => $keyActualM->qty_actual, 'bobot_p' => $keyActualM->bobot_planning, 'qty_plan' => $keyActualM->qty_plan, 'status_activity' => $keyActualM->status_activity, 'sum_qty_actual' => $keyActualM->sum_qty_actual, 'name' => $keyActualM->name ); $tmpProgressActualWeek += $progressActualWeek; } $progressPlanKomulatifWeek[] += round($tmpProgressPlanWeek, 2); if (new \DateTime($loopDay . ' Friday') <= new \DateTime($today . ' Friday')) { $progressActualKomulatifWeek[] += round($tmpProgressActualWeek, 2); } $dataActivityPlanDate[] = array( "date" => $loopDay, "statusWeek" => new \DateTime($loopDay) == new \DateTime($loopDay . ' Friday') ? true : false, "activity-plan" => $dataActivityPlan, "activity-actual" => $dataActivityActual, "tmpProgressActualWeek" => $tmpProgressActualWeek, "progressPlanWeek" => $tmpProgressPlanWeek ); } $dataFinal[] = array( // "date" => $dateWeek, "proyek_name" => $dataProject->nama, "data" => [ "date" => $dateWeek, "percentagePlan" => $progressPlanKomulatifWeek, "percentageReal" => $progressActualKomulatifWeek // "data_details" => $dataActivityPlanDate ] ); return $dataFinal; } // public function calculateSCurveForProgressTree($hierarchyId) // { // DB::enableQueryLog(); // // $hierarchyGantts = []; // if (isset($hierarchyId)) { // $hierarchy = HierarchyFtth::findOrFail($hierarchyId); // $projectId = $hierarchy->project_id; // // if (isset($hierarchy)) { // // $hierarchyGantts = VersionGantt::where('hierarchy_ftth_id', $hierarchyId)->get()->toArray(); // // } // } // $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"); // } // $minDate = $dataProject->mulai_proyek; // $begin = new \DateTime($minDate); // $begin = $begin->modify('-1 day'); // 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('P1D'); // } else { // $maxDate = $dataProject->akhir_proyek; // $end = new \DateTime($maxDate); // $end = new \DateTime($end->format('Y-m-d') . ' Friday'); // // $end->modify('next Friday'); // // $end->modify('next Friday'); // $interval = new \DateInterval('P1D'); // } // $period = new \DatePeriod($begin, $interval, $end); // // $arr_ActualM = []; // $tempDate = []; // // $tempPercentagePlan = []; // // $tempPercentagePlanWhr = []; // // $tempPercentageReal = []; // // $tempTtlPercentPlan = 0; // // $tempTtlPercentActual = 0; // // $currentACWP = 0; // // $currentBCWP = 0; // $dataActivityPlanDate = []; // $progressPlanKomulatifWeek = []; // $progressActualKomulatifWeek = []; // $dateWeek = []; // $tmpProgressPlanWeek = 0; // $tmpProgressActualWeek = 0; // foreach ($period as $dt) { // $loopDay = $dt->format("Y-m-d"); // //new \Datetime($dt->format("Y-m-d")); // // $minSevenDays = $minSevenDays->modify('-7 day')->format("Y-m-d"); // $tempDate[] = array($dt->format("Y-m-d")); // $dataPlanM = []; // $dataActualM = []; // // if (count($hierarchyGantts) > 0) { // // foreach ($hierarchyGantts as $key => $gantt) { // // $dataPlanM[] = DB::table('m_activity') // // ->where('type_activity', 'task') // // ->where('bobot_planning', '>', 0) // // ->where('version_gantt_id', $gantt['id']) // // ->whereDate('planned_start', '<=', $loopDay) // // ->whereDate('planned_end', '>=', $loopDay) // // ->select('name', 'bobot_planning', 'biaya_actual', 'duration', 'persentase_progress', 'id', 'planned_start', 'planned_end') // // ->get()->toArray(); // // $dataActualM[] = DB::table('report_activity_material as ram') // // ->join('m_activity as ma', 'ma.id', '=', 'ram.activity_id') // // ->select('ram.activity_id', 'ram.qty as qty_actual', 'ma.bobot_planning', 'ma.name', // // DB::raw('(SELECT SUM(amta.qty_planning) FROM assign_material_to_activity amta WHERE amta.activity_id = ram.activity_id) AS qty_plan'), // // DB::raw('(SELECT SUM(ram.qty) FROM report_activity_material ram WHERE ram.activity_id = ma.id) AS sum_qty_actual'), // // DB::raw('(SELECT DISTINCT status_activity FROM assign_material_to_activity amta WHERE amta.activity_id = ram.activity_id) AS status_activity'), // // DB::raw('(SELECT COUNT(id) FROM report_activity_material ram WHERE ram.activity_id = ma.id) AS count_report') // // ) // // ->where('ram.report_date', $loopDay) // // ->where('ma.version_gantt_id', $gantt['id']) // // ->get()->toArray(); // // } // // } else { // $dataPlanM = DB::table('m_hierarchy_ftth as mhf') // ->join('m_version_gantt as mvg', 'mvg.hierarchy_ftth_id', '=', 'mhf.id') // ->join('m_activity as ma', 'ma.version_gantt_id', '=', 'mvg.id') // ->where('ma.type_activity', 'task') // ->where('ma.bobot_planning', '>', 0) // ->where('mhf.project_id', $projectId) // ->whereDate('planned_start', '<=', $loopDay) // ->whereDate('planned_end', '>=', $loopDay) // ->select('ma.name', 'ma.bobot_planning', 'ma.biaya_actual', 'ma.duration', 'ma.persentase_progress', 'ma.id', 'ma.planned_start', 'ma.planned_end') // ->get(); // $dataActualM = DB::table('m_hierarchy_ftth as mhf') // ->join('m_version_gantt as mvg', 'mvg.hierarchy_ftth_id', '=', 'mhf.id') // ->join('m_activity as ma', 'ma.version_gantt_id', '=', 'mvg.id') // ->join('report_activity_material as ram', 'ram.activity_id', '=', 'ma.id') // ->select( // 'ram.activity_id', // 'ram.qty as qty_actual', // 'ma.bobot_planning', // 'ma.name', // DB::raw('(SELECT SUM(amta.qty_planning) FROM assign_material_to_activity amta WHERE amta.activity_id = ram.activity_id) AS qty_plan'), // DB::raw('(SELECT SUM(ram.qty) FROM report_activity_material ram WHERE ram.activity_id = ma.id) AS sum_qty_actual'), // DB::raw('(SELECT DISTINCT status_activity FROM assign_material_to_activity amta WHERE amta.activity_id = ram.activity_id) AS status_activity'), // DB::raw('(SELECT COUNT(id) FROM report_activity_material ram WHERE ram.activity_id = ma.id) AS count_report') // ) // ->where('ram.report_date', $loopDay) // // ->where('ma.proyek_id', $projectId) // ->where('mhf.project_id', $projectId) // ->get(); // // } // $dataActivityPlan = []; // $dataActivityActual = []; // $today = date('Y-m-d'); // if (new \DateTime($loopDay) == new \DateTime($loopDay . ' Friday')) { // $progressPlanKomulatifWeek[] += round($tmpProgressPlanWeek, 2); // if (new \DateTime($loopDay . ' Friday') <= new \DateTime($today . ' Friday')) { // // $tempPercentageReal[] = round($tempTtlPercentActual, 2); // $progressActualKomulatifWeek[] += round($tmpProgressActualWeek, 2); // } // $dateWeek[] = [$loopDay]; // } // // $progressPlanKomulatifWeek[] += $tmpProgressPlanWeek; // // if (count($dataPlanM) > 0 && count($dataPlanM[0]) > 0) { // foreach ($dataPlanM as $keyPlanM) { // # hitung untuk persentase progress planning // // if($keyPlanM->duration == 0){ // // $duration = 2; // // Tanggal awal // if (count($keyPlanM) == 0) { // continue; // } // $startDate = new DateTime($keyPlanM->planned_start); // // Tanggal akhir // $endDate = new DateTime($keyPlanM->planned_end); // // Menghitung selisih hari // $interval = $startDate->diff($endDate); // // Mengambil hasil selisih hari // $duration = (int) $interval->days + 1; // // }else{ // // $duration = $keyPlanM->duration + 2; // // } // // $startPlan = new DateTime($keyPlanM->planned_start); // // $endPlan = new DateTime($keyPlanM->planned_end); // // $interval = $startPlan->diff($endPlan); // // // Mengambil hasil selisih hari // // $duration = $interval->days; // // 2023-07-26 // $progressPlanWeek = $keyPlanM->bobot_planning / $duration; // $dataActivityPlan[] = array( // 'progressPlanDay' => $progressPlanWeek, // 'name' => $keyPlanM->name, // 'bobot_p' => $keyPlanM->bobot_planning, // 'duration' => $keyPlanM->duration // ); // $tmpProgressPlanWeek += $progressPlanWeek; // } // // } // // hitung progress actual // // if (count($dataActualM) > 0 && count($dataActualM[0]) > 0) { // foreach ($dataActualM as $keyActualM) { // if (count($keyPlanM) == 0) { // continue; // } // # hitung untuk persentase progress actual // // $progressActualWeek = ((((($keyActualM->qty_actual / $keyActualM->sum_qty_actual) * 100) / $keyActualM->qty_plan)*100)*$keyActualM->bobot_planning)/100; // // jika total report > dari planning // if ($keyActualM->sum_qty_actual > $keyActualM->qty_plan) { // $progressActualWeek = (($keyActualM->qty_actual / $keyActualM->sum_qty_actual) * 100) * $keyActualM->bobot_planning / 100; // } else { // // jika total report < dari planning // // $progressActualWeek = ((($keyActualM->qty_actual / $keyActualM->sum_qty_actual) * 100) / $keyActualM->qty_plan)*$keyActualM->bobot_planning; // if ($keyActualM->qty_actual == 0) { // $progressActualWeek = 0; // } else { // $progressActualWeek = ($keyActualM->qty_actual / $keyActualM->qty_plan) * $keyActualM->bobot_planning; // } // } // if ($keyActualM->status_activity == 'done') { // // if($keyActualM->sum_qty_actual > $keyActualM->qty_plan){ // // } // // if($progressActualWeek > $keyActualM->bobot_planning){ // // $progressActualWeek = $keyActualM->bobot_planning; // // }else if($keyActualM->qty_actual == 0){ // // $progressActualWeek = $keyActualM->bobot_planning; // // }else if($keyActualM->qty_plan == $keyActualM->sum_qty_actual){ // $progressActualWeek = $keyActualM->bobot_planning / $keyActualM->count_report; // // }else { // // $progressActualWeek = $progressActualWeek; // // } // // $progressActualWeek = $progressActualWeek > $keyActualM->bobot_planning ? $keyActualM->bobot_planning : $progressActualWeek; // // jika report lebih dari 1 x, maka harusnya di bagi sabanyak jumlah report, // // contoh ada 3 report, report ke 1 adalah 5 maka 100/3 dan di looping // } else { // $progressActualWeek = $progressActualWeek > ($keyActualM->bobot_planning * 95) / 100 ? ($keyActualM->bobot_planning * 95) / 100 : $progressActualWeek; // } // $dataActivityActual[] = array( // 'progressActualDay' => $progressActualWeek, // 'qty_act' => $keyActualM->qty_actual, // 'bobot_p' => $keyActualM->bobot_planning, // 'qty_plan' => $keyActualM->qty_plan, // 'status_activity' => $keyActualM->status_activity, // 'sum_qty_actual' => $keyActualM->sum_qty_actual, // 'name' => $keyActualM->name // ); // $tmpProgressActualWeek += $progressActualWeek; // } // // } // $dataActivityPlanDate[] = array( // "date" => $loopDay, // "statusWeek" => new \DateTime($loopDay) == new \DateTime($loopDay . ' Friday') ? true : false, // "activity-plan" => $dataActivityPlan, // "activity-actual" => $dataActivityActual, // "tmpProgressActualWeek" => $tmpProgressActualWeek, // "progressPlanWeek" => $tmpProgressPlanWeek // ); // } // $dataFinal[] = array( // // "date" => $dateWeek, // "proyek_name" => $dataProject->nama, // "data" => [ // "date" => $dateWeek, // "percentagePlan" => $progressPlanKomulatifWeek, // "percentageReal" => $progressActualKomulatifWeek // // "data_details" => $dataActivityPlanDate // ] // ); // return $dataFinal; // } public function calculateSCurveForProgressTree($hierarchyId) { $hierarchy = HierarchyFtth::findOrFail($hierarchyId); $averageProgress = VersionGantt::where('hierarchy_ftth_id', $hierarchy['id']) ->avg('progress'); return $averageProgress; } 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 = []; $tempPercentage = []; $tempPercentagePlan = []; $tempPercentagePlanWhr = []; $tempPercentageReal = []; $tempTtlPercentPlan = 0; $tempTtlPercentActual = 0; $currentACWP = 0; $currentBCWP = 0; $totalACWP = 0; $totalBCWP = 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; } }