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']); $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 = $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 = []; $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'); $statusCutOfDate = false; // if (new \DateTime($loopDay) < $today) { // $statusCutOfDate = true; // } 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; 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; } $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 ], "gantt" => $keyGantt ); return $dataFinal; } public function calculateSCurveVWahyu($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 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(); // $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_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'); 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 $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) { # 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) { 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 $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) { # 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 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; } }