From 3afb8b1c4f2c23bc74acf1b3f6bb6cc68a3191ab Mon Sep 17 00:00:00 2001 From: ibnu Date: Wed, 15 Nov 2023 11:13:35 +0700 Subject: [PATCH 1/4] update curva --- app/Helpers/MasterFunctionsHelper.php | 30 ++++++++++++++------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/app/Helpers/MasterFunctionsHelper.php b/app/Helpers/MasterFunctionsHelper.php index eedd5e6..78f3326 100644 --- a/app/Helpers/MasterFunctionsHelper.php +++ b/app/Helpers/MasterFunctionsHelper.php @@ -932,7 +932,7 @@ class MasterFunctionsHelper ->groupBy('activity_id') ->first(); - $weekCount = $keyPlanM->duration / $keyPlanM->duration; // jadiin perhari (1) + $weekCount = 1; // jadiin perhari (1) $weeklyPlan = $sumVolPlan->ttl_qty_plan / $weekCount; $weeklyProgress = $weeklyPlan / $sumVolPlan->ttl_qty_plan * $keyPlanM->bobot_planning; @@ -1056,9 +1056,9 @@ class MasterFunctionsHelper $tempPercentagePlan[] = round($tempTtlPercentPlan, 2); $tempPercentagePlanWhr[] = ["weekly period", $tempPercentagePlan]; $tempPercentageReal[] = round($tempTtlPercentActual, 2); - if ($tempTtlPercentPlan >= 100 && $tempTtlPercentActual >= 100) { - break; - } + // if ($tempTtlPercentPlan >= 100 && $tempTtlPercentActual >= 100) { + // break; + // } } else { $tempPercentage[] = array(round($sumPercentagePlan, 2), round($sumPercentageActual, 2)); $tempPercentagePlan[] = round($sumPercentagePlan, 2); @@ -1092,20 +1092,22 @@ class MasterFunctionsHelper $totalBCWP = $lastReal * $dataProject->rencana_biaya / 100; $dataResponse = array( "date" => $tempDate, + "start" => $begin, + "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, - ) + // "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( From 884b075291929f00ce3906da1050ce40f1b9ac95 Mon Sep 17 00:00:00 2001 From: ibnu Date: Thu, 23 Nov 2023 15:26:39 +0700 Subject: [PATCH 2/4] update conflict --- app/Http/Controllers/ProjectController.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/Http/Controllers/ProjectController.php b/app/Http/Controllers/ProjectController.php index 42bcb6d..80296af 100644 --- a/app/Http/Controllers/ProjectController.php +++ b/app/Http/Controllers/ProjectController.php @@ -344,6 +344,12 @@ 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(); return response()->json(['status'=>'success','code'=>200, 'data' => json_decode($sCurve->scurve)], 200); From 3ea5783ea6c530a155c9f7512609ffe04afe9a55 Mon Sep 17 00:00:00 2001 From: ibnu Date: Thu, 23 Nov 2023 15:29:22 +0700 Subject: [PATCH 3/4] update curva calculation --- app/Helpers/MasterFunctionsHelper.php | 419 +++++++++++++++++++++++--- rest-client.http | 109 +++++-- routes/web.php | 1 + 3 files changed, 458 insertions(+), 71 deletions(-) diff --git a/app/Helpers/MasterFunctionsHelper.php b/app/Helpers/MasterFunctionsHelper.php index 78f3326..bf2ee73 100644 --- a/app/Helpers/MasterFunctionsHelper.php +++ b/app/Helpers/MasterFunctionsHelper.php @@ -162,7 +162,7 @@ class MasterFunctionsHelper return $dataFinal; } - public function calculateProgressBasedOnReportMaterial($keyGantt) + public function calculateProgressBasedOnReportMaterialOld($keyGantt) { DB::enableQueryLog(); @@ -488,6 +488,325 @@ class MasterFunctionsHelper return $dataFinal; } + public function calculateProgressBasedOnReportMaterial($keyGantt) + { + DB::enableQueryLog(); + + $dataFinal = []; + $dataPayload = []; + $dataPayload['period'] = 'week'; + $totalACWP = 0; + $totalBCWP = 0; + $tempPercentage = []; + + $dataProject = Project::find($keyGantt['proyek_id']); + $dataHeader = Activity::where('type_activity', 'header')->where("proyek_id", $keyGantt['proyek_id'])->where("version_gantt_id", $keyGantt['id'])->first(); + if (isset($dataPayload['end_date']) && $dataPayload['end_date'] > $dataProject->akhir_proyek) { + $dataPayload['end_date'] = $dataProject->akhir_proyek; + } + + if ($dataHeader) { + $totalRencanaBudget = Activity::where('parent_id', $dataHeader->id)->where("proyek_id", $keyGantt['proyek_id'])->where("version_gantt_id", $keyGantt['id'])->sum("rencana_biaya"); + } else { + $totalRencanaBudget = Activity::whereNull('parent_id')->where("proyek_id", $keyGantt['proyek_id'])->where("version_gantt_id", $keyGantt['id'])->sum("rencana_biaya"); + } + + if (!Activity::where("version_gantt_id", $keyGantt['id'])->first()) + return $dataFinal; + + // $alreadyHasReport = DB::table('report_activity_material as a') + // ->select('a.id') + // ->join('m_activity as b', 'b.id', '=', 'a.activity_id') + // ->where('b.version_gantt_id', '=', $keyGantt['id']) + // ->exists(); + // note : delete this + // if(!$alreadyHasReport) + // return $dataFinal; + + $minDate = Activity::where('version_gantt_id', $keyGantt['id'])->whereNull('parent_id')->pluck('start_date')->first(); + + $begin = new \DateTime($minDate); + $begin->modify('last Monday'); + if (isset($dataPayload['end_date'])) { + $maxDate = $dataPayload['end_date']; + $end = new \DateTime($maxDate . ' Friday'); + $end->modify('next Friday'); + $end->modify('next Friday'); + /* $interval = \DateInterval::createFromDateString('1 day'); */// should be using this but its bugged + $interval = new \DateInterval('P7D'); + } else { + $actualMaxDate = DB::table('assign_material_to_activity as ama') + ->where("ama.proyek_id", $keyGantt['proyek_id']) + ->join('m_activity as a', 'a.id', '=', 'ama.activity_id') + ->where('a.version_gantt_id', '=', $keyGantt['id']) + ->max("a.end_date"); // plan date overlapped with assign_material_to_activity's, it should be m_activity's + $plannedMaxDate = DB::table('assign_material_to_activity as ama') + ->where("ama.proyek_id", $keyGantt['proyek_id']) + ->join('m_activity as a', 'a.id', '=', 'ama.activity_id') + ->where('a.version_gantt_id', '=', $keyGantt['id']) + ->max("a.planned_end"); // plan date overlapped with assign_material_to_activity's, it should be m_activity' + $maxDate = max(new \DateTime($plannedMaxDate), new \DateTime($actualMaxDate)); + $end = new \DateTime($maxDate->format('Y-m-d') . ' Friday'); + $end->modify('next Friday'); + $end->modify('next Friday'); + $interval = new \DateInterval('P7D'); + } + $period = new \DatePeriod($begin, $interval, $end); + + $arr_ActualM = []; + $tempDate = []; + $tempPercentagePlan = []; + $tempPercentagePlanWhr = []; + $tempPercentageReal = []; + $tempTtlPercentPlan = 0; + $tempTtlPercentActual = 0; + + $currentACWP = 0; + $currentBCWP = 0; + + foreach ($period as $dt) { + $minSevenDays = new \Datetime($dt->format("Y-m-d")); + $minSevenDays = $minSevenDays->modify('-7 day')->format("Y-m-d"); + $tempDate[] = array($dt->format("Y-m-d")); + // $dataPlanM = DB::table('assign_material_to_activity as ama') + // ->select('ama.activity_id', 'ama.qty_planning', 'ama.plan_date', 'ama.start_activity', 'a.bobot_planning', 'a.biaya_actual', 'a.duration', 'a.persentase_progress') + // ->join('m_activity as a', 'a.id', '=', 'ama.activity_id') + // ->where('ama.proyek_id', '=', $keyGantt['proyek_id']) + // ->where('a.version_gantt_id', '=', $keyGantt['id']) + // ->whereDate('ama.plan_date', '<=',$dt->format("Y-m-d")) + // ->whereDate('ama.plan_date', '>', $minSevenDays) + // ->get(); + + $activities = DB::table('m_activity AS a') + ->join('assign_material_to_activity AS amta', 'amta.activity_id', '=', 'a.id') + ->where('a.type_activity', 'task') + ->where('a.bobot_planning', '>', 0) + ->where('a.version_gantt_id', $keyGantt['id']) + ->whereDate('amta.plan_date', '<=', $dt->format("Y-m-d")) + ->whereDate('amta.plan_date', '>', $minSevenDays) + ->select('a.bobot_planning', 'a.biaya_actual', 'a.duration', 'a.persentase_progress', 'a.id'); + + $dataPlanM = DB::table('m_activity AS a') + ->join('assign_hr_to_activity AS ahta', 'ahta.activity_id', '=', 'a.id') + ->where('a.type_activity', 'task') + ->where('a.bobot_planning', '>', 0) + ->where('a.version_gantt_id', $keyGantt['id']) + ->whereDate('a.start_date', '<=', $dt->format("Y-m-d")) + ->whereDate('a.start_date', '>', $minSevenDays) + ->select('a.bobot_planning', 'a.biaya_actual', 'a.duration', 'a.persentase_progress', 'a.id') + ->union($activities) + ->get(); + + $dataActualM = DB::table('report_activity_material as ram') + ->select('ram.activity_id', 'ram.qty', 'ram.report_date', 'a.bobot_planning', 'a.biaya_actual', 'a.duration', 'a.persentase_progress') + ->join('m_activity as a', 'a.id', '=', 'ram.activity_id') + ->where('a.version_gantt_id', '=', $keyGantt['id']) + ->where('a.proyek_id', '=', $keyGantt['proyek_id']) + ->whereDate('ram.report_date', '<=', $dt->format("Y-m-d")) + ->whereDate('ram.report_date', '>', $minSevenDays) + ->get(); + $dataTempPlan = []; + $x = 0; + $sumPercentagePlan = 0; + $totalACWP = isset($totalACWP) ? $totalACWP : 0; + $totalBCWP = isset($totalBCWP) ? $totalBCWP : 0; + + foreach ($dataPlanM as $keyPlanM) { + // $sumVolPlan = DB::table(function ($query) use ($keyGantt) { + // $query->select('a.*') + // ->from('m_activity AS a') + // ->join('assign_material_to_activity as amta', 'amta.activity_id', '=', 'a.id') + // ->where('a.type_activity', 'task') + // ->where('a.bobot_planning', '>', 0) + // ->where('a.version_gantt_id', $keyGantt['id']) + // ->unionAll(function ($query) use ($keyGantt) { + // $query->select('a.*') + // ->from('m_activity AS a') + // ->join('assign_hr_to_activity as ahta', 'ahta.activity_id', '=', 'a.id') + // ->where('a.type_activity', 'task') + // ->where('a.bobot_planning', '>', 0) + // ->where('a.version_gantt_id', $keyGantt['id']); + // }) + // ->orderBy('id', 'asc'); + // }, 'subquery') + // ->sum('bobot_planning'); + $sumVolPlan = DB::table('assign_material_to_activity') + ->select('activity_id', DB::raw('SUM(qty_planning) as ttl_qty_plan')) + ->where('activity_id', '=', $keyPlanM->id) + ->groupBy('activity_id') + ->first(); + 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; + + } + + // $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, + ); + 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]; + $tempPercentageReal[] = round($tempTtlPercentActual, 2); + if ($tempTtlPercentPlan >= 100 && $tempTtlPercentActual >= 100) { + break; + } + } else { + $tempPercentage[] = array(round($sumPercentagePlan, 2), round($sumPercentageActual, 2)); + $tempPercentagePlan[] = round($sumPercentagePlan, 2); + $tempPercentageReal[] = round($sumPercentageActual, 2); + } + } + + try { + if (round($totalACWP, 0) > $totalRencanaBudget) { + $estimatedCost = round($totalACWP, 0) + 0; + } else { + $estimatedCost = ($totalRencanaBudget + 0); + } + } catch (\DivisionByZeroError $e) { + return response()->json([ + 'message' => $e->getMessage(), + "line" => 566, + 'gantt' => $keyGantt, + ]); + } + $estimatedCost = $totalACWP > $totalRencanaBudget ? $totalACWP : $totalRencanaBudget; + + $costDeviation = $totalRencanaBudget - $estimatedCost; + if ($costDeviation > 0) { + $potential = "SAVING"; + } else { + $potential = $costDeviation == 0 ? "ON BUDGET" : "OVERRUN"; + } + + $lastReal = $tempPercentageReal[count($tempPercentageReal) - 1]; + $totalBCWP = $lastReal * $dataProject->rencana_biaya / 100; + $dataResponse = array( + "date" => $tempDate, + "percentage" => $tempPercentage, + "percentagePlan" => $tempPercentagePlan, + "percentageReal" => $tempPercentageReal, + "data_details" => $arr_ActualM, + "budget_control" => array( + "current_budget" => $totalRencanaBudget, + "acwp" => round($totalACWP, 0), + "bcwp" => round($totalBCWP, 0), + "rem_to_complete" => ($totalRencanaBudget - round($totalACWP, 0)), + "add_cost_to_complete" => 0, + "estimated_at_completion" => $estimatedCost, + "cost_deviation" => $costDeviation, + "potential" => $potential, + ) + ); + + $dataFinal[] = array( + "proyek_name" => $dataProject->nama, + "data" => $dataResponse, + "gantt" => $keyGantt + ); + + return $dataFinal; + } + public function calculateSCurveVWahyu($projectId) { DB::enableQueryLog(); @@ -807,8 +1126,8 @@ class MasterFunctionsHelper $dataFinal = []; $dataPayload = []; $dataPayload['period'] = 'week'; - $totalACWP = 0; - $totalBCWP = 0; + // $totalACWP = 0; + // $totalBCWP = 0; $tempPercentage = []; $dataProject = Project::find($projectId); @@ -830,13 +1149,13 @@ 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'); + // $end->modify('next Friday'); /* $interval = \DateInterval::createFromDateString('1 day'); */// should be using this but its bugged $interval = new \DateInterval('P7D'); } else { @@ -860,8 +1179,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")); @@ -905,8 +1224,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) { @@ -932,9 +1251,14 @@ 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; + $weeklyPlan = $weekCount > 0 ? $sumVolPlan->ttl_qty_plan / $weekCount : 0; + $weeklyProgress = $weeklyPlan / $sumVolPlan->ttl_qty_plan * $keyPlanM->bobot_planning; + }else{ + $weeklyProgress = 0; + } // $weeklyPlan = $sumVolPlan->ttl_qty_plan / $weekCount; // $weeklyProgress = 80; @@ -947,11 +1271,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()]); } @@ -1027,11 +1351,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++; } @@ -1049,8 +1373,8 @@ class MasterFunctionsHelper // 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); @@ -1067,37 +1391,40 @@ class MasterFunctionsHelper $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), diff --git a/rest-client.http b/rest-client.http index 772aee0..6abe9ab 100644 --- a/rest-client.http +++ b/rest-client.http @@ -1,4 +1,5 @@ -@token = eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC9sb2NhbGhvc3Q6ODQ0NFwvYXBpXC9sb2dpbiIsImlhdCI6MTY5MTc2MDYyNCwiZXhwIjoxNjkyMzY1NDI0LCJuYmYiOjE2OTE3NjA2MjQsImp0aSI6Ikd2bEFPTE4yZ2FuRFdVbjEiLCJzdWIiOjEsInBydiI6IjIzYmQ1Yzg5NDlmNjAwYWRiMzllNzAxYzQwMDg3MmRiN2E1OTc2ZjcifQ.XNGbsmcgQ-CkV8vLlvnItGKM0R1am5X5b6qUFOR1DRo +@token = eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC9iYWNrZW5kLnRlc3RcL2FwaVwvbG9naW4iLCJpYXQiOjE3MDA0NTA1ODYsImV4cCI6MTcwMTA1NTM4NiwibmJmIjoxNzAwNDUwNTg2LCJqdGkiOiJack9MMU04UGdKWGkwTUU1Iiwic3ViIjoxLCJwcnYiOiIyM2JkNWM4OTQ5ZjYwMGFkYjM5ZTcwMWM0MDA4NzJkYjdhNTk3NmY3In0.fyg6CyiCAcX3GD4iSy8urkHpZEJ4mnXSXQc4NKC8U9A + @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 @@ -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,37 @@ 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":"129","gantt_id":"862"} +### {"period":"week","project_id":"129","gantt_id":"862"} ### -POST {{hostname}}/dashboard/curva-s +POST {{hostname}}/project/calculate-s-curve Authorization: Bearer {{token}} content-type: application/json -{ - "project_id": [15] -} +{"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 + +{"period":"week","project_id":"129","gantt_id":"800"} +### {"period":"week","project_id":"135","gantt_id":"891"} ### GET https://adw-api.ospro.id/api/request-material/get-material-integration?name=c @@ -957,6 +1007,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 +1087,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 +1228,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 f9e79b4..5d9bcfa 100644 --- a/routes/web.php +++ b/routes/web.php @@ -69,6 +69,7 @@ $router->group(['prefix'=>'api', 'middleware' => 'cors'], function () use ($rout $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'); From fa54ad6227ac49fa5993bc4ae8993451573d2c8d Mon Sep 17 00:00:00 2001 From: ibnu Date: Mon, 27 Nov 2023 16:04:21 +0700 Subject: [PATCH 4/4] update scurve --- app/Helpers/MasterFunctionsHelper.php | 23 +++- app/Http/Controllers/ActivityController.php | 125 ++++++++++++++++++++ routes/web.php | 3 + 3 files changed, 145 insertions(+), 6 deletions(-) diff --git a/app/Helpers/MasterFunctionsHelper.php b/app/Helpers/MasterFunctionsHelper.php index bf2ee73..9baaa80 100644 --- a/app/Helpers/MasterFunctionsHelper.php +++ b/app/Helpers/MasterFunctionsHelper.php @@ -642,7 +642,11 @@ class MasterFunctionsHelper $weeklyProgress = $weeklyPlan / $sumVolPlan->ttl_qty_plan * $keyPlanM->bobot_planning; // $bobotHari = $keyPlanM->bobot_planning / $keyPlanM->duration; }else{ - $weeklyProgress = 0; + // $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; } @@ -776,10 +780,11 @@ class MasterFunctionsHelper $potential = "SAVING"; } else { $potential = $costDeviation == 0 ? "ON BUDGET" : "OVERRUN"; - } - + } $lastReal = $tempPercentageReal[count($tempPercentageReal) - 1]; $totalBCWP = $lastReal * $dataProject->rencana_biaya / 100; + array_pop($tempPercentageReal); + array_pop($tempPercentageReal); $dataResponse = array( "date" => $tempDate, "percentage" => $tempPercentage, @@ -1253,11 +1258,17 @@ class MasterFunctionsHelper if($keyPlanM->duration){ $weekCount = $keyPlanM->duration / 7; - // $weeklyPlan = $weekCount >= 1 ? $sumVolPlan->ttl_qty_plan / $weekCount : $sumVolPlan->ttl_qty_plan / $weekCount / 7; - $weeklyPlan = $weekCount > 0 ? $sumVolPlan->ttl_qty_plan / $weekCount : 0; + $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; + // $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; diff --git a/app/Http/Controllers/ActivityController.php b/app/Http/Controllers/ActivityController.php index 21dc80c..eabfcc6 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 = []; diff --git a/routes/web.php b/routes/web.php index 5d9bcfa..14e1d08 100644 --- a/routes/web.php +++ b/routes/web.php @@ -75,6 +75,7 @@ $router->group(['prefix'=>'api', 'middleware' => 'cors'], function () use ($rout $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'); */ @@ -214,6 +215,8 @@ $router->group(['prefix'=>'api', 'middleware' => 'cors'], function () use ($rout $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');