diff --git a/app/Console/Commands/CalculateProgressGantt.php b/app/Console/Commands/CalculateProgressGantt.php new file mode 100644 index 0000000..f3b40c9 --- /dev/null +++ b/app/Console/Commands/CalculateProgressGantt.php @@ -0,0 +1,28 @@ +argument('hierarchy_id'); + $hierarchy = HierarchyFtth::findOrFail($hierarchy_id); + $project = Project::find($hierarchy->project_id); + + $data = MasterFunctionsHelper::calculateSCurveForProgressTree($hierarchy_id); + + $hierarchy->bobot_planning = 100; + $hierarchy->progress =round(((int) end($data[0]['data']['percentageReal']) / (int) end($data[0]['data']['percentagePlan'])) * 100, 2); + $hierarchy->save(); + } +} diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index a7fceee..726d069 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -14,7 +14,8 @@ class Kernel extends ConsoleKernel */ protected $commands = [ Commands\syncHumanResourceIntegration::class, - Commands\CalculateSCurve::class + Commands\CalculateSCurve::class, + Commands\CalculateProgressGantt::class ]; /** diff --git a/app/Helpers/MasterFunctionsHelper.php b/app/Helpers/MasterFunctionsHelper.php index 3acb597..ed7a377 100644 --- a/app/Helpers/MasterFunctionsHelper.php +++ b/app/Helpers/MasterFunctionsHelper.php @@ -192,44 +192,29 @@ class MasterFunctionsHelper return $dataFinal; } - public function calculateProgressBasedOnReportMaterial($keyGantt) + 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; - - $alreadyHasReport = DB::table('report_activity_material as a') - ->select('a.id') - ->join('m_activity as b', 'b.id', '=', 'a.activity_id') - ->where('b.version_gantt_id', '=', $keyGantt['id']) - ->exists(); - // note : delete this - // if(!$alreadyHasReport) - // return $dataFinal; - $minDate = Activity::where('version_gantt_id', $keyGantt['id'])->whereNull('parent_id')->pluck('start_date')->first(); - - $begin = new \DateTime($minDate . ' Monday'); + $begin = new \DateTime($minDate); $begin->modify('last Monday'); if (isset($dataPayload['end_date'])) { $maxDate = $dataPayload['end_date']; @@ -256,7 +241,6 @@ class MasterFunctionsHelper $interval = new \DateInterval('P7D'); } $period = new \DatePeriod($begin, $interval, $end); - $arr_ActualM = []; $tempDate = []; $tempPercentagePlan = []; @@ -264,23 +248,12 @@ class MasterFunctionsHelper $tempPercentageReal = []; $tempTtlPercentPlan = 0; $tempTtlPercentActual = 0; - $currentACWP = 0; $currentBCWP = 0; - foreach ($period as $dt) { $minSevenDays = new \Datetime($dt->format("Y-m-d")); $minSevenDays = $minSevenDays->modify('-7 day')->format("Y-m-d"); $tempDate[] = array($dt->format("Y-m-d")); - // $dataPlanM = DB::table('assign_material_to_activity as ama') - // ->select('ama.activity_id', 'ama.qty_planning', 'ama.plan_date', 'ama.start_activity', 'a.bobot_planning', 'a.biaya_actual', 'a.duration', 'a.persentase_progress') - // ->join('m_activity as a', 'a.id', '=', 'ama.activity_id') - // ->where('ama.proyek_id', '=', $keyGantt['proyek_id']) - // ->where('a.version_gantt_id', '=', $keyGantt['id']) - // ->whereDate('ama.plan_date', '<=',$dt->format("Y-m-d")) - // ->whereDate('ama.plan_date', '>', $minSevenDays) - // ->get(); - $activities = DB::table('m_activity AS a') ->join('assign_material_to_activity AS amta', 'amta.activity_id', '=', 'a.id') ->where('a.type_activity', 'task') @@ -289,7 +262,6 @@ class MasterFunctionsHelper ->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') @@ -300,7 +272,6 @@ class MasterFunctionsHelper ->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') @@ -314,7 +285,6 @@ class MasterFunctionsHelper $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.*') @@ -339,9 +309,20 @@ class MasterFunctionsHelper ->where('activity_id', '=', $keyPlanM->id) ->groupBy('activity_id') ->first(); - $weekCount = $keyPlanM->duration / 7; - $weeklyPlan = $weekCount > 0 ? $sumVolPlan->ttl_qty_plan / $weekCount : 0; - $weeklyProgress = $weeklyPlan / $sumVolPlan->ttl_qty_plan * $keyPlanM->bobot_planning; + 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; @@ -363,7 +344,6 @@ class MasterFunctionsHelper } $x++; } - $w = 0; $dataTempReport = []; $sumPercentageActual = 0; @@ -414,8 +394,6 @@ class MasterFunctionsHelper // $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()]); @@ -423,7 +401,6 @@ class MasterFunctionsHelper $dataTempReport[$w]['totalacwp'] = $totalACWP; $w++; } - $arr_ActualM[] = array( 'date' => $dt->format("Y-m-d"), 'percentPlan' => $sumPercentagePlan, @@ -431,42 +408,30 @@ class MasterFunctionsHelper '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; - - // if($tempTtlPercentPlan >= 100 || $tempTtlPercentActual >= $keyGantt['progress'];){ - // if($tempTtlPercentActual >= 100) - // $tempTtlPercentActual = 100; - // if($tempTtlPercentPlan >= 100) - // $tempTtlPercentPlan = 100; - - // if($tempTtlPercentActual >= $keyGantt['progress']) - // $tempTtlPercentActual = $keyGantt['progress']; - // todo - // if ($tempTtlPercentPlan >= 100) - // $tempTtlPercentPlan = 100; - // $sumPercentageActual > $keyGantt['progress'] ? $keyGantt['progress'] : $sumPercentageActual - - // } - $currentACWP += $totalACWP; $currentBCWP += $totalBCWP; - $tempPercentage[] = array(round($tempTtlPercentPlan, 2), round($tempTtlPercentActual, 2)); $tempPercentagePlan[] = round($tempTtlPercentPlan, 2); $tempPercentagePlanWhr[] = ["weekly period", $tempPercentagePlan]; - $tempPercentageReal[] = round($tempTtlPercentActual, 2); + if ($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); - $tempPercentageReal[] = round($sumPercentageActual, 2); + if ($date < $today) { + $tempPercentageReal[] = round($sumPercentageActual, 2); + } } } - try { if (round($totalACWP, 0) > $totalRencanaBudget) { $estimatedCost = round($totalACWP, 0) + 0; @@ -481,14 +446,12 @@ class MasterFunctionsHelper ]); } $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( @@ -508,12 +471,222 @@ class MasterFunctionsHelper "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; } @@ -830,15 +1003,15 @@ class MasterFunctionsHelper return $dataFinal; } - public function calculateSCurve($projectId) + public function calculateSCurveOld($projectId) { DB::enableQueryLog(); $dataFinal = []; $dataPayload = []; $dataPayload['period'] = 'week'; - $totalACWP = 0; - $totalBCWP = 0; + // $totalACWP = 0; + // $totalBCWP = 0; $tempPercentage = []; $dataProject = Project::find($projectId); @@ -860,14 +1033,14 @@ class MasterFunctionsHelper $minDate = $dataProject->mulai_proyek; - $begin = new \DateTime($minDate . ' Monday'); + $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 + // $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') @@ -890,8 +1063,8 @@ class MasterFunctionsHelper $tempTtlPercentPlan = 0; $tempTtlPercentActual = 0; - $currentACWP = 0; - $currentBCWP = 0; + // $currentACWP = 0; + // $currentBCWP = 0; foreach ($period as $dt) { $minSevenDays = new \Datetime($dt->format("Y-m-d")); @@ -935,8 +1108,8 @@ class MasterFunctionsHelper $dataTempPlan = []; $x = 0; $sumPercentagePlan = 0; - $totalACWP = isset($totalACWP) ? $totalACWP : 0; - $totalBCWP = isset($totalBCWP) ? $totalBCWP : 0; + // $totalACWP = isset($totalACWP) ? $totalACWP : 0; + // $totalBCWP = isset($totalBCWP) ? $totalBCWP : 0; foreach ($dataPlanM as $keyPlanM) { // $sumVolPlan = DB::table(function ($query) use ($projectId) { @@ -962,9 +1135,19 @@ class MasterFunctionsHelper ->groupBy('activity_id') ->first(); - $weekCount = 1; // jadiin perhari (1) - $weeklyPlan = $sumVolPlan->ttl_qty_plan / $weekCount; - $weeklyProgress = $weeklyPlan / $sumVolPlan->ttl_qty_plan * $keyPlanM->bobot_planning; + 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; @@ -977,11 +1160,11 @@ class MasterFunctionsHelper 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; + // 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()]); } @@ -1022,17 +1205,17 @@ class MasterFunctionsHelper ->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; - } + 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){ @@ -1040,7 +1223,7 @@ class MasterFunctionsHelper $sumPercentageActual += $keyActualM->bobot_planning / $reportCount; // $sumPercentageActual = $sumPercentageActual > $keyGantt['progress'] ? $keyGantt['progress'] : $sumPercentageActual; } else { - if ( $actual >= 1 || (int) $sumVolActual->ttl_qty_plan == (int) $sumReportActual) { + 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 { @@ -1057,11 +1240,11 @@ class MasterFunctionsHelper // } - $totalACWP += $keyActualM->duration > 0 ? $keyActualM->biaya_actual / $keyActualM->duration : 0; + // $totalACWP += $keyActualM->duration > 0 ? $keyActualM->biaya_actual / $keyActualM->duration : 0; } catch (\DivisionByZeroError $e) { return response()->json(['message' => $e->getMessage()]); } - $dataTempReport[$w]['totalacwp'] = $totalACWP; + // $dataTempReport[$w]['totalacwp'] = $totalACWP; $w++; } @@ -1072,62 +1255,72 @@ class MasterFunctionsHelper '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 + // todo // if ($tempTtlPercentPlan >= 100) // $tempTtlPercentPlan = 100; - $currentACWP += $totalACWP; - $currentBCWP += $totalBCWP; + // $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 ($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); - $tempPercentageReal[] = round($sumPercentageActual, 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]; - $totalBCWP = $lastReal * $dataProject->rencana_biaya / 100; + // 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" => $begin, + "start" => $minDate, + "begin" => $begin, + // "periode" => $period, "end" => $end, "percentage" => $tempPercentage, "percentagePlan" => $tempPercentagePlan, "percentageReal" => $tempPercentageReal, - "data_details" => $arr_ActualM, + // "data_details" => $arr_ActualM, // "budget_control" => array( // "current_budget" => $totalRencanaBudget, // "acwp" => round($totalACWP, 0), @@ -1148,6 +1341,507 @@ class MasterFunctionsHelper 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(); diff --git a/app/Http/Controllers/ActivityController.php b/app/Http/Controllers/ActivityController.php index 21dc80c..cbb425e 100644 --- a/app/Http/Controllers/ActivityController.php +++ b/app/Http/Controllers/ActivityController.php @@ -37,6 +37,94 @@ class ActivityController extends Controller return response()->json(['status' => 'success', 'data' => $dataGantt, 'code' => 200], 200); } + public function activitySCurve($proyek_id, $gantt_id){ + + // "data": [ + // { + // "id": 1, + // "text": "Office itinerancy", + // "type": "project", + // "order": "10", + // "progress": 0.4, + // "open": true, + // "user":"0", + // "start_date": "02-04-2024 00:00", + // "duration": 17, + // "end_date": "19-04-2024 00:00", + // "parent": 0 + // } + // ], + // "links": [ + // { + // "id": "1", + // "source": "1", + // "target": "2", + // "type": "1" + // } + // ] + // } + + $checkHeader = Activity::where('version_gantt_id', $gantt_id)->where('type_activity', 'header')->count(); + $finalData = []; + if ($checkHeader > 0) { + $dataHeader = Activity::select('id', 'name as text', 'type_activity as type', 'persentase_progress as progress', 'start_date', 'end_date', 'duration', 'parent_id', 'sortorder as order')->where('version_gantt_id', $gantt_id)->where('type_activity', 'header')->first(); + + // $dataHeader->start_date1 = isset($dataHeader->start) ? date_format(date_create($dataHeader->start), "d-m-Y H:i") : NULL; + // $dataHeader->end_date1 = isset($dataHeader->end) ? date_format(date_create($dataHeader->end), "d-m-Y H:i") : NULL; + + $dataHeader->progress = $dataHeader->progress / 100; + + $dataHeader->type = "project"; + $dataHeader->text = $dataHeader->name; + $finalData[] = $dataHeader; + $data = Activity::select('id', 'name as text', 'type_activity as type', 'persentase_progress as progress', 'start_date', 'end_date', 'duration', 'parent_id', 'sortorder as order')->where('version_gantt_id', $gantt_id)->where('parent_id', $dataHeader->id)->orderBy('sortorder', 'asc')->get(); + } else { + $data = Activity::select('id', 'name as text', 'type_activity as type', 'persentase_progress as progress', 'start_date', 'end_date', 'duration', 'parent_id', 'sortorder as order')->where('version_gantt_id', $gantt_id)->whereNull('parent_id')->orderBy('sortorder', 'asc')->get(); + } + + foreach ($data as $objRow) { + $type = "project"; + $dataChildren = $this->getChildrenSCurve($gantt_id, $objRow->id); + + if ($objRow->type_activity == "milestone") + $type = $objRow->type_activity; + if (empty($dataChildren)) + $type = "task"; + + $objRow->parent = $objRow->parent_id ? $objRow->parent_id : null; + // $objRow->start_date = isset($objRow->start) ? date_format(date_create($objRow->start), "d-m-Y H:i") : NULL; + // $objRow->end_date1 = isset($objRow->end) ? date_format(date_create($objRow->end), "d-m-Y H:i") : NULL; + + $objRow->progress = $objRow->persentase_progress / 100; + $objRow->type = $type; + $finalData[] = $objRow; + $finalData = array_merge($finalData, $dataChildren); + } + + $dataLink = Link::where('version_gantt_id', $gantt_id)->get(); + $finalLink = []; + foreach ($dataLink as $objRow) { + $dataRow = array( + 'id' => $objRow->id, + 'source' => $objRow->s_activity_id, + 'target' => $objRow->t_activity_id, + 'type' => $objRow->type_link, + 'code' => $objRow->code_link + ); + if ($objRow->lag) + $dataRow['lag'] = $objRow->lag; + $finalLink[] = $dataRow; + } + + $resultData = array( + "data" => $finalData, + "links" => $finalLink + ); + + return response()->json(['status' => 'success', 'data' => $resultData, 'code' => 200], 200); + + } + private function getDataActivity($id) { $checkHeader = Activity::where('version_gantt_id', $id)->where('type_activity', 'header')->count(); @@ -116,6 +204,43 @@ class ActivityController extends Controller return $resultData; } + private function getChildrenSCurve($gantt_id, $parent_id) + { + $finalData = []; + + $data = Activity::select('id', 'name as text', 'type_activity as type', 'bobot_planning', 'persentase_progress as progress', 'start_date', 'end_date', 'duration', 'parent_id', 'sortorder as order') + ->where('version_gantt_id', $gantt_id)->where('parent_id', $parent_id)->orderBy('sortorder', 'asc')->get(); + foreach ($data as $objRow) { + $objRow->parent = $parent_id; + $objRow->progress = (float) $objRow->bobot_planning /100; + // $objRow->start_date1 = isset($objRow->start) ? date_format(date_create($objRow->start), "d-m-Y H:i") : NULL; + // $objRow->end_date1 = isset($objRow->end) ? date_format(date_create($objRow->end), "d-m-Y H:i") : NULL; + + $dataChildren = $this->getChildrenSCurve($gantt_id, $objRow->id); + if ($objRow->type_activity == "milestone") { + $objRow->type = $objRow->type_activity; + // $objRow->actual_start = isset($objRow->actual_start) ? date_format(date_create($objRow->actual_start), "d-m-Y") : NULL; + } elseif (empty($dataChildren)) { + $objRow->type = "task"; + // $objRow->actual_start = isset($objRow->actual_start) ? date_format(date_create($objRow->actual_start), "d-m-Y") : NULL; + // $objRow->actual_end = isset($objRow->actual_end) ? date_format(date_create($objRow->actual_end), "d-m-Y") : NULL; + // if(isset($objRow->actual_start)){ + // $objRow->auto_scheduling = false; + // } + } else { + $objRow->type = "project"; + // $actualStart = $this->getFirstLastDateActivity($objRow->id, "start"); + // $objRow->actual_start = isset($actualStart) ? date_format(date_create($actualStart), "d-m-Y") : NULL; + + // $actualEnd = $this->getFirstLastDateActivity($objRow->id, "end"); + // $objRow->actual_end = isset($actualEnd) ? date_format(date_create($actualEnd), "d-m-Y") : NULL; + } + $finalData[] = $objRow; + $finalData = array_merge($finalData, $dataChildren); + } + return $finalData; + } + private function getChildren($gantt_id, $parent_id) { $finalData = []; @@ -197,7 +322,7 @@ class ActivityController extends Controller $actualEndValues = array_column(array_filter($dataFinal, function($item) { return isset($item['actual_end']); }), 'actual_end'); - $returnActualStartOrEnd = count($actualEndValues) == count($dataFinal) ? max($actualEndValues) : null; + $returnActualStartOrEnd = count($actualEndValues) == count($dataFinal) && count($actualEndValues) > 0 ? max($actualEndValues) : null; if (isset($parent)) { $parent->actual_end = $returnActualStartOrEnd; $parent->save(); @@ -479,6 +604,7 @@ class ActivityController extends Controller $activityToUpdate = $activity->firstWhere('id', $entity['data']['id']); $entity['data']['name'] = $entity['data']['text']; $entity['data']['persentase_progress'] = $entity['data']['progress'] * 100; + $entity['data']['type_activity'] = $entity['data']['type']; if (isset($entity['data']['rencana_biaya'])) { $entity['data']['rencana_biaya'] = str_replace(",", ".", $entity['data']['rencana_biaya']); } @@ -1030,4 +1156,9 @@ class ActivityController extends Controller } return response()->json(['status' => 'success', 'data' => $request, 'message' => 'Update successful!', 'code' => 200], 200); } + + // public function recalculateProject($by, $id){ + // // query get activity + // $cekActivity = + // } } diff --git a/app/Http/Controllers/DashboardBoDController.php b/app/Http/Controllers/DashboardBoDController.php index deb8065..aca1727 100644 --- a/app/Http/Controllers/DashboardBoDController.php +++ b/app/Http/Controllers/DashboardBoDController.php @@ -41,49 +41,105 @@ class DashboardBoDController extends Controller private function getInvoiceIntegration($search) { - if(empty($search)) - return response()->json(['status'=>'error', 'message'=>'Empty query string!'], 400); + if (empty($search)) + return response()->json(['status' => 'error', 'message' => 'Empty query string!'], 400); - $url = str_replace("SEARCH", $search, config('api.adw').'/project_cost?project_no=SEARCH'); + $url = str_replace("SEARCH", $search, config('api.adw') . '/project_cost?project_no=SEARCH'); $token = config('api.adw_token'); $response = $this->curlReq($url, $token); - if(@$response->data->project_no == "") + if (@$response->data->project_no == "") return null; return $response; } - // to do - public function getCompanyCashFlow($year = '%') + // OLD + // public function getCompanyCashFlow($year = '%') + // { + // $year = $this->interpolateYear($year); + // $totalExpenditure = $totalInvoice = $totalPaidInvoice = 0; + + + // $totalBudgets = Project::select(DB::raw('SUM(CAST("rencana_biaya" AS DOUBLE PRECISION))')) + // ->where('mulai_proyek', 'like', $year) + // /* ->orWhere('akhir_proyek', 'like', $year) */ + // ->pluck('sum') + // ->first(); + + // $projects = Project::where('mulai_proyek', 'like', $year) + // /* ->orWhere('akhir_proyek', 'like', $year) */ + // ->get(); + // foreach ($projects as $project) { + // $project->expenses = 0; + + // $resp = null; + // if ($project->kode_sortname != "") { + // $resp = $this->getInvoiceIntegration($project->kode_sortname); + // /* $resp = $project->kode_sortname; */ + // $cost = $resp->data->total_cost ?? 0; + // $cost = substr($cost, 0, strpos($cost, ".")); + // $totalExpenditure += (int) $cost; + // $totalInvoice += $resp->data->total_invoice_amount ?? 0; + // $totalPaidInvoice += $resp->data->total_invoice_paid_amount ?? 0; + // } + + // } + + // return response()->json([ + // 'data' => [ + // 'total_budget' => (int) $totalBudgets ?? 0, + // 'total_expenditure' => $totalExpenditure, + // 'total_invoice' => $totalInvoice, + // 'total_paid_invoice' => $totalPaidInvoice, + // ] + // ], 200); + // } + + public function getCompanyCashFlow($year = '%', $company_id, $all_project, $hierarchy) { $year = $this->interpolateYear($year); $totalExpenditure = $totalInvoice = $totalPaidInvoice = 0; - // we can't use eloquent's sum() method because someone decided to use varchar as datatype in rencana_biaya field - $totalBudgets = Project::select(DB::raw('SUM(CAST("rencana_biaya" AS DOUBLE PRECISION))')) - ->where('mulai_proyek', 'like', $year) - /* ->orWhere('akhir_proyek', 'like', $year) */ - ->pluck('sum') - ->first(); + $totalBudgets = null; + if ($all_project) { + $totalBudgets = Project::where('mulai_proyek', 'like', $year) + ->where('company_id', $company_id) + ->sum(DB::raw('CAST("rencana_biaya" AS DOUBLE PRECISION)')); + } else { + $totalBudgets = Project::where('mulai_proyek', 'like', $year) + ->where('created_by_id', $hierarchy) + ->sum(DB::raw('CAST("rencana_biaya" AS DOUBLE PRECISION)')); + } + + $projects = null; + if ($all_project) { + $projects = Project::where('mulai_proyek', 'like', $year) + ->where('company_id', $company_id) + ->get(); + } else { + $projects = Project::where('mulai_proyek', 'like', $year) + ->where('created_by_id', $hierarchy) + ->get(); + } - $projects = Project::where('mulai_proyek', 'like', $year) - /* ->orWhere('akhir_proyek', 'like', $year) */ - ->get(); foreach ($projects as $project) { $project->expenses = 0; - $resp = null; if ($project->kode_sortname != "") { + $resp = $this->getInvoiceIntegration($project->kode_sortname); - /* $resp = $project->kode_sortname; */ $cost = $resp->data->total_cost ?? 0; $cost = substr($cost, 0, strpos($cost, ".")); - $totalExpenditure += (int) $cost; - $totalInvoice += $resp->data->total_invoice_amount ?? 0; - $totalPaidInvoice += $resp->data->total_invoice_paid_amount ?? 0; + $cost = 0; + $totalExpenditure = 0; + $totalInvoice = 0; + $totalPaidInvoice = 0; + + // $totalExpenditure += (int) $cost; + // $totalInvoice += $resp->data->total_invoice_amount ?? 0; + // $totalPaidInvoice += $resp->data->total_invoice_paid_amount ?? 0; } - } return response()->json([ @@ -96,6 +152,7 @@ class DashboardBoDController extends Controller ], 200); } + public function getInvoiceOutstanding($year = '%') { $year = $this->interpolateYear($year); @@ -147,15 +204,13 @@ class DashboardBoDController extends Controller } $selisihProgress = $planningProgress - $actualProgress; try { - if ($selisihProgress > 0 && $selisihProgress <= 5){ + if ($selisihProgress > 0 && $selisihProgress <= 5) { $return['warning'] += 1; $projects[$index]->status = 'warning'; - } - elseif ($selisihProgress == 0){ + } elseif ($selisihProgress == 0) { $return['on-schedule'] += 1; $projects[$index]->status = 'on-schedule'; - } - else { + } else { $return['behind-schedule'] += 1; $projects[$index]->status = 'behind-schedule'; } @@ -191,13 +246,11 @@ class DashboardBoDController extends Controller $actualProgress = !empty($actualArray) ? $actualArray[count($actualArray) - 1] : 0; } $selisihProgress = $planningProgress - $actualProgress; - if ($selisihProgress > 0 && $selisihProgress <= 5){ + if ($selisihProgress > 0 && $selisihProgress <= 5) { $warning++; - } - elseif ($selisihProgress == 0){ + } elseif ($selisihProgress == 0) { $onSchedule++; - } - else { + } else { $behindSchedule++; } } @@ -294,7 +347,7 @@ class DashboardBoDController extends Controller { $year = $this->interpolateYear($year); - $divisions = Divisi::select('id', 'name','parent','color') + $divisions = Divisi::select('id', 'name', 'parent', 'color') ->with('children') ->whereNull('parent') ->get(); diff --git a/app/Http/Controllers/HierarchyFtthController.php b/app/Http/Controllers/HierarchyFtthController.php index 3b3f64f..bcf27ad 100644 --- a/app/Http/Controllers/HierarchyFtthController.php +++ b/app/Http/Controllers/HierarchyFtthController.php @@ -6,6 +6,7 @@ use Illuminate\Http\Request; use App\Models\HierarchyFtth; use App\Models\VersionGantt; use Illuminate\Support\Facades\Log; +use Illuminate\Support\Facades\Artisan; class HierarchyFtthController extends Controller { @@ -102,36 +103,41 @@ class HierarchyFtthController extends Controller } } - public function countProgress($project_id) { - $ftthIds = VersionGantt::select('hierarchy_ftth_id') - ->where('proyek_id', $project_id) - ->groupBy('hierarchy_ftth_id') - ->get(); - if($ftthIds){ - foreach ($ftthIds as $ftthId) { - $gantts = VersionGantt::where('hierarchy_ftth_id', $ftthId->hierarchy_ftth_id)->sum('progress'); - $bobot_planning = VersionGantt::where('hierarchy_ftth_id', $ftthId->hierarchy_ftth_id)->sum('bobot'); - $ganttCount = VersionGantt::where('hierarchy_ftth_id', $ftthId->hierarchy_ftth_id)->count(); - - $ftth = HierarchyFtth::find($ftthId->hierarchy_ftth_id); - if($ftth){ - $round = $gantts/$ganttCount; - $round_bobot = $bobot_planning/$ganttCount; - $ftth->progress = round($round, 2); - $ftth->bobot_planning = round($round_bobot, 2); - try { - $ftth->save(); - } catch (\Exception $e) { - // Log the error or handle it in some other way - Log::error($e->getMessage()); - } + public function countProgress($hierarchy_id) { + // $ftthIds = VersionGantt::select('hierarchy_ftth_id') + // ->where('proyek_id', $project_id) + // ->groupBy('hierarchy_ftth_id') + // ->get(); + // if($ftthIds){ + // foreach ($ftthIds as $ftthId) { + // $gantts = VersionGantt::where('hierarchy_ftth_id', $ftthId->hierarchy_ftth_id)->sum('progress'); + // $bobot_planning = VersionGantt::where('hierarchy_ftth_id', $ftthId->hierarchy_ftth_id)->sum('bobot'); + // $ganttCount = VersionGantt::where('hierarchy_ftth_id', $ftthId->hierarchy_ftth_id)->count(); - if($ftth->parent_id){ - $this->countParent($ftth); - } - } - } - } + // $ftth = HierarchyFtth::find($ftthId->hierarchy_ftth_id); + // if($ftth){ + // $round = $gantts/$ganttCount; + // $round_bobot = $bobot_planning/$ganttCount; + // $ftth->progress = round($round, 2); + // $ftth->bobot_planning = round($round_bobot, 2); + // try { + // $ftth->save(); + // } catch (\Exception $e) { + // // Log the error or handle it in some other way + // Log::error($e->getMessage()); + // } + + // if($ftth->parent_id){ + // $this->countParent($ftth); + // } + // } + // } + // } + + // calculate ke curva berdasarkan site + Artisan::call('calculate:progressgantt', [ + 'hierarchy_id' => $hierarchy_id + ]); } public function countParent($ftth){ @@ -179,7 +185,6 @@ class HierarchyFtthController extends Controller public function getTreeByProject($project_id) { - $this->countProgress(intval($project_id)); $data = HierarchyFtth::where('project_id', $project_id)->whereNull('parent_id')->orderByRaw('id ASC')->get(); $finalData = []; foreach($data as $objRow){ @@ -204,7 +209,13 @@ class HierarchyFtthController extends Controller return response()->json(['status'=>'success','data'=>$finalData,'code'=>200], 200); } - + public function countProgressTree($hierarchy_id) + { + Artisan::call('calculate:progressgantt', [ + 'hierarchy_id' => $hierarchy_id + ]); + return response()->json(['status'=>'success','code'=>200], 200); + } private function getChildren($project_id, $parent_id) { $finalData = []; diff --git a/app/Http/Controllers/ProjectController.php b/app/Http/Controllers/ProjectController.php index 3015327..2a4f3dd 100644 --- a/app/Http/Controllers/ProjectController.php +++ b/app/Http/Controllers/ProjectController.php @@ -360,6 +360,13 @@ class ProjectController extends Controller return response()->json(['status' => 'success', 'code' => 200, 'data' => $data], 200); } + // testing + public function calculateSCurvetest(Request $request) + { + $data = MasterFunctionsHelper::calculateSCurve($request->project_id); + return response()->json(['status' => 'success', 'code' => 200, 'data' => $data], 200); + } + public function calculateSCurve(Request $request) { $sCurve = Project::select('scurve')->where('id', $request->project_id)->first(); @@ -542,16 +549,25 @@ class ProjectController extends Controller $result->header = Activity::whereNull('parent_id')->where("proyek_id", $id)->first(); $actualStartExist = Activity::where('proyek_id', $id)->whereNotNull('actual_start')->exists(); if ($result['type_proyek_id'] === 9) { - $actualEndExist = Activity::where('proyek_id', $id)->exists(); - $query = Activity::where('proyek_id', $id); + // $actualEndExist = Activity::where('proyek_id', $id)->exists(); + // $query = Activity::where('proyek_id', $id); + $maxEndDate = Activity::where('proyek_id', $id)->select('end_date') + ->orderBy('end_date', 'desc') + ->first(); } else { - $actualEndExist = Activity::where('version_gantt_id', $ganttId)->exists(); + // $actualEndExist = Activity::where('version_gantt_id', $ganttId)->exists(); + $maxEndDate = Activity::where('version_gantt_id', $ganttId)->select('end_date') + ->orderBy('end_date', 'desc') + ->first(); $query = Activity::where('version_gantt_id', $ganttId); } } else { $result->header = Activity::whereNull('parent_id')->where("proyek_id", $id)->where("version_gantt_id", $ganttId)->first(); $actualStartExist = Activity::where('version_gantt_id', $ganttId)->whereNotNull('actual_start')->exists(); - $actualEndExist = Activity::where('version_gantt_id', $ganttId)->exists(); + // $actualEndExist = Activity::where('version_gantt_id', $ganttId)->exists(); + $maxEndDate = Activity::where('version_gantt_id', $ganttId)->select('end_date') + ->orderBy('end_date', 'desc') + ->first(); $query = Activity::where('version_gantt_id', $ganttId); } @@ -560,10 +576,13 @@ class ProjectController extends Controller } else { $startDate = $query->orderBy('start_date')->value('start_date'); } - if ($actualEndExist) { - $maxEndDate = $query->max('id'); - $endDate = $query->where('id', $maxEndDate)->first()->end_date; - } + // if($actualEndExist) + // { + // // $maxEndDate = $query->max('id'); + // // get last end_date + // // $endDate = $query->where('id',$maxEndDate)->first()->end_date; + + // } $plannedStart = Activity::where('version_gantt_id', $ganttId) ->orderBy('planned_start') @@ -572,7 +591,7 @@ class ProjectController extends Controller ->orderByDesc('planned_end') ->value('planned_end'); $result->header->start_date = $startDate; - $result->header->end_date = $endDate; + $result->header->end_date = $maxEndDate->end_date; $result->header->planned_start = $plannedStart; $result->header->planned_end = $plannedEnd; return response()->json(['status' => 'success', 'code' => 200, 'data' => $result, 'gantt' => $ganttId], 200); diff --git a/app/Models/Project.php b/app/Models/Project.php index 115c9b6..43c0a1e 100644 --- a/app/Models/Project.php +++ b/app/Models/Project.php @@ -48,6 +48,7 @@ class Project extends Model 'created_by', 'updated_at', 'updated_by', - 'created_by_id' + 'created_by_id', + 'company_id' ]; } diff --git a/rest-client.http b/rest-client.http index 772aee0..932e596 100644 --- a/rest-client.http +++ b/rest-client.http @@ -1,4 +1,5 @@ -@token = eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC9sb2NhbGhvc3Q6ODQ0NFwvYXBpXC9sb2dpbiIsImlhdCI6MTY5MTc2MDYyNCwiZXhwIjoxNjkyMzY1NDI0LCJuYmYiOjE2OTE3NjA2MjQsImp0aSI6Ikd2bEFPTE4yZ2FuRFdVbjEiLCJzdWIiOjEsInBydiI6IjIzYmQ1Yzg5NDlmNjAwYWRiMzllNzAxYzQwMDg3MmRiN2E1OTc2ZjcifQ.XNGbsmcgQ-CkV8vLlvnItGKM0R1am5X5b6qUFOR1DRo +@token = eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC9iYWNrZW5kLnRlc3RcL2FwaVwvbG9naW4iLCJpYXQiOjE3MDEzNzMzNzQsImV4cCI6MTcwMTk3ODE3NCwibmJmIjoxNzAxMzczMzc0LCJqdGkiOiJhbkJWOHIwUDZndFRXZk5KIiwic3ViIjoxNzg4LCJwcnYiOiIyM2JkNWM4OTQ5ZjYwMGFkYjM5ZTcwMWM0MDA4NzJkYjdhNTk3NmY3In0.QCiXq-62da7Sdk7sEb_J0apEij_R6IQgZVYG9iL6M8g + @tokenS = eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC9hZHctYXBpLm9zcHJvLmlkXC9hcGlcL2xvZ2luIiwiaWF0IjoxNjkxNTcyMTIwLCJleHAiOjE2OTIxNzY5MjAsIm5iZiI6MTY5MTU3MjEyMCwianRpIjoiVUdqbnhLRVdlZzYyTTBnayIsInN1YiI6MSwicHJ2IjoiMjNiZDVjODk0OWY2MDBhZGIzOWU3MDFjNDAwODcyZGI3YTU5NzZmNyJ9.5QqK0dLW5jzbVOkSCSW0mFo0K7ycGOBW9NCG_2Zldm4 @@ -6,7 +7,7 @@ # @hostname = https://ospro-api.ospro.id/api # @hostname = https://api-iu.ospro.id/api # @hostname = https://api-staging-adw.ospro.id/api -@hostname = http://localhost:8444/api +@hostname = http://backend.test/api # @hostname = http://103.73.125.81:8444/api # @hostname = http://localhost:8444/adw-backend/api @@ -17,8 +18,8 @@ POST {{hostname}}/login content-type: application/json { - "username": "admin", - "password": "1nt3gr4s14" + "username": "testing", + "password": "testing123" } ###### Tools Req @@ -418,7 +419,7 @@ content-type: application/json "operator": "AND" } ], - "select": ["kode_sortname", "nama", "mulai_proyek"], + "select": ["id", "nama", "rencana_biaya", "type_proyek_id", "currency_symbol", "mulai_proyek", "akhir_proyek"], "joins": [ { "name": "m_users", @@ -455,7 +456,43 @@ Authorization: Bearer {{tokenS}} content-type: application/json { - "columns":[{"name":"nama","logic_operator":"ilike","value":"","operator":"AND"}],"joins":[{"name":"m_users","column_join":"pm_id","column_results":["name","username"]},{"name":"m_type_proyek","column_join":"type_proyek_id","column_results":["name","description"]}],"orders":{"columns":["id"],"ascending":false},"paging":{"start":0,"length":10} + "columns": [ + { + "name": "nama", + "logic_operator": "ilike", + "value": "", + "operator": "AND" + } + ], + "select": ["id", "nama", "rencana_biaya", "color_progress", "currency_symbol", "mulai_proyek", "akhir_proyek"], + "joins": [ + { + "name": "m_users", + "column_join": "pm_id", + "column_results": [ + "name", + "username" + ] + }, + { + "name": "m_type_proyek", + "column_join": "type_proyek_id", + "column_results": [ + "name", + "description" + ] + } + ], + "orders": { + "columns": [ + "id" + ], + "ascending": false + }, + "paging": { + "start": 0, + "length": 10 + } } ### add @@ -529,7 +566,7 @@ content-type: application/json ###### Activity ### get data by id version -GET {{hostname}}/activity/33/29/get +GET {{hostname}}/activity/550/137/get Authorization: Bearer {{token}} content-type: application/json @@ -785,24 +822,44 @@ content-type: application/json ### -POST {{hostname}}/activity/get-curva-s +POST {{hostname}}/dashboard/curva-s Authorization: Bearer {{token}} content-type: application/json { - "project_id": [47], - "period": "week" + "project_id": [15] } +### +POST {{hostname}}/project/s-curve-command-test +Authorization: Bearer {{token}} +content-type: application/json + +# {"period":"week","project_id":"137","gantt_id":"916"} +# {"period":"week","project_id":"129","gantt_id":"862"} +{"period":"week","project_id":"140","gantt_id":"1103"} ### -POST {{hostname}}/dashboard/curva-s +POST {{hostname}}/project/calculate-s-curve +Authorization: Bearer {{token}} +content-type: application/json + +{"period":"week","project_id":"129","gantt_id":"862"} +### {"period":"week","project_id":"135","gantt_id":"891"} + +####### +POST {{hostname}}/project/get-s-curve +Authorization: Bearer {{token}} +content-type: application/json + +{"project_id":"164","gantt_id":"973","period":"week"} +### {"period":"week","project_id":"129","gantt_id":"800"} + +####### +GET {{hostname}}/activity/s-curve/137/892 Authorization: Bearer {{token}} content-type: application/json -{ - "project_id": [15] -} ### GET https://adw-api.ospro.id/api/request-material/get-material-integration?name=c @@ -957,6 +1014,27 @@ content-type: application/json "user_id": 1247 } + +# -6.226761,106.809311 jkarta +# -6.465806,106.760559 +# -6.356175,108.336182 indramayu +# -6.266805,106.468048, tigaraksa +# -6.205115,106.918373 jatinegara +###### +POST {{hostname}}/presence/test +Authorization: Bearer {{token}} +content-type: application/json + +{ + "clock_in_out": { + "clock_out_lat": -6.356175, + "clock_out_lng": 108.336182, + "type" : "out" + }, + "time": "2023-08-15T14:48:17+07:00", + "user_id": 1566 +} + ###### POST {{hostname}}/presence/add Authorization: Bearer {{token}} @@ -1016,9 +1094,7 @@ POST {{hostname}}/map-monitoring/search Authorization: Bearer {{token}} content-type: application/json -{ - "project_id" : [75, 76, 78] -} +{"project_id":[140,138,132,130]} ###### POST {{hostname}}/waypoint/add-bulk @@ -1159,13 +1235,3 @@ content-type: application/json } } -####### -POST {{hostname}}/project/get-s-curve -Authorization: Bearer {{token}} -content-type: application/json - -{ - "period":"week", - "project_id":"118", - "gantt_id":"287" -} \ No newline at end of file diff --git a/routes/web.php b/routes/web.php index a629000..f7d3f5f 100644 --- a/routes/web.php +++ b/routes/web.php @@ -23,7 +23,7 @@ $router->group(['prefix' => 'api', 'middleware' => 'cors'], function () use ($ro $router->group(['middleware' => ['auth', 'cors']], function () use ($router) { - $router->get('/dashboard/get-company-cashflow[/{year}]', 'DashboardBoDController@getCompanyCashFlow'); // project expenditure + $router->get('/dashboard/get-company-cashflow/{year}/{company_id}/{all_project}/{hierarchy}', 'DashboardBoDController@getCompanyCashFlow'); // project expenditure $router->get('/dashboard/get-invoice-outstanding[/{year}]', 'DashboardBoDController@getInvoiceOutstanding'); // project invoice vs cash in $router->get('/dashboard/get-total-project-per-schedule-health[/{year}]', 'DashboardBoDController@getTotalProjectPerScheduleHealth'); $router->get('/dashboard/get-total-project-per-budget-health[/{year}]', 'DashboardBoDController@getTotalProjectPerBudgetHealth'); @@ -69,17 +69,19 @@ $router->group(['prefix' => 'api', 'middleware' => 'cors'], function () use ($ro $router->post('/project/get-s-curve', 'ProjectController@getSCurve'); $router->post('/project/calculate-s-curve', 'ProjectController@calculateSCurve'); $router->post('/project/s-curve-command', 'ProjectController@sCurveCommand'); + $router->post('/project/s-curve-command-test', 'ProjectController@calculateSCurvetest'); $router->post('/project/get-linear-s-curve', 'ProjectController@getLinearSCurve'); $router->post('/project/get-overdue-activities', 'ProjectController@getOverdueActivities'); $router->post('/project/get-integration-invoice', 'ProjectController@getInvoiceIntegration'); $router->post('/project/get-report-distribution', 'ProjectController@getReportDistribution'); + /* $router->get('/project/get-expenditure/{id}/{date?}', 'ProjectController@getExpenditure'); */ /* $router->get('/project/get-total-expenditure/{id}', 'ProjectController@getTotalExpenditure'); */ /* $router->get('/project/get-status-health-schedule/{id}', 'ProjectController@getStatusSchedule'); */ /* $router->get('/project/get-status-health-budget/{id}', 'ProjectController@getStatusBudget'); */ - $router->get('/project-carausell','ProjectCarausellController@invoke'); + $router->get('/project-carausell', 'ProjectCarausellController@invoke'); $router->post('/project-charter/search', 'ProjectCharterController@search'); $router->post('/project-charter/add', 'ProjectCharterController@add'); @@ -214,6 +216,8 @@ $router->group(['prefix' => 'api', 'middleware' => 'cors'], function () use ($ro $router->post('/activity/import-old', 'ActivityController@importOld'); $router->post('/activity/batch-update/{ganttId}', 'ActivityController@batchUpdate'); $router->get('/activity/update-schedule/{ganttId}', 'ActivityController@updateSchedule'); + $router->get('/activity/s-curve/{proyek_id}/{gantt_id}', 'ActivityController@activitySCurve'); + $router->post('/task', 'ActivityController@add'); $router->get('/task/edit/{id}', 'ActivityController@edit'); $router->put('/task/{id}', 'ActivityController@update'); @@ -488,6 +492,7 @@ $router->group(['prefix' => 'api', 'middleware' => 'cors'], function () use ($ro $router->put('/hierarchy-ftths/{id}', 'HierarchyFtthController@update'); $router->delete('/hierarchy-ftths/{id}', 'HierarchyFtthController@destroy'); $router->get('/hierarchy-ftths/tree/{project_id}', 'HierarchyFtthController@getTreeByProject'); + $router->get('/hierarchy-ftths/count-tree/{hierarchy_id}', 'HierarchyFtthController@countProgressTree'); $router->get('/hierarchy-ftths/tree-gantt/{gantt_id}', 'HierarchyFtthController@getTreeByGantt'); $router->post('/map-monitoring/search', 'MapMonitoringController@search');