diff --git a/Dockerfile b/Dockerfile
index 4edd5c1..f9925d2 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -29,6 +29,9 @@ RUN docker-php-ext-install \
pgsql \
tokenizer
+# Copy php.ini to the container
+COPY /docker/php/php.ini /usr/local/etc/php/
+
#Install Extensions
RUN docker-php-ext-configure pgsql -with-pgsql=/usr/local/pgsql
diff --git a/app/Console/Commands/CalculateSCurve.php b/app/Console/Commands/CalculateSCurve.php
new file mode 100644
index 0000000..2d005d7
--- /dev/null
+++ b/app/Console/Commands/CalculateSCurve.php
@@ -0,0 +1,29 @@
+argument('project_id');
+ $project = Project::find($project_id);
+
+ $project->calculation_status = true;
+ $project->save();
+
+ $data = MasterFunctionsHelper::CalculateSCurve($project_id);
+
+ $project->scurve = json_encode($data);
+ $project->calculation_status = true;
+ $project->save();
+ }
+}
diff --git a/app/Console/Commands/syncHumanResourceIntegration.php b/app/Console/Commands/syncHumanResourceIntegration.php
index 6120999..7b4ef5f 100644
--- a/app/Console/Commands/syncHumanResourceIntegration.php
+++ b/app/Console/Commands/syncHumanResourceIntegration.php
@@ -39,9 +39,9 @@ class syncHumanResourceIntegration extends Command
*/
public function handle()
{
- // $url = config('api.adw').'/employees?page=1';
- // echo "Requesting to " . $url;
- $response = null;
+ $url = config('api.adw').'/employees?page=1';
+ echo "Requesting to " . $url;
+ $response = MasterFunctionsHelper::curlReq($url);
if(!$response)
return;
diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php
index a379d80..a7fceee 100644
--- a/app/Console/Kernel.php
+++ b/app/Console/Kernel.php
@@ -13,7 +13,8 @@ class Kernel extends ConsoleKernel
* @var array
*/
protected $commands = [
- Commands\syncHumanResourceIntegration::class
+ Commands\syncHumanResourceIntegration::class,
+ Commands\CalculateSCurve::class
];
/**
diff --git a/app/Helpers/MasterFunctionsHelper.php b/app/Helpers/MasterFunctionsHelper.php
index ebd59b3..ae74952 100644
--- a/app/Helpers/MasterFunctionsHelper.php
+++ b/app/Helpers/MasterFunctionsHelper.php
@@ -1,528 +1,1001 @@
-max("id");
- if(!$maxGanttId){
- $data = array(
- "proyek_id" => $id
- );
- } else {
- $data = array(
- "last_gantt_id" => $maxGanttId,
- "proyek_id" => $id
- );
- }
- return $data;
- }
-
- // dipake di dashboard project & bod
- public function getSCurve($request){
- $allGantt = [];
- if(!is_int($request)){
- $dataPayload = $request->all();
- if(isset($dataPayload['gantt_id'])){
- $allGantt = $dataPayload['gantt_id'];
- }else{
- $allGantt[] = MasterFunctionsHelper::getLatestGantt($dataPayload['project_id']);
- }
- } else {
- $allGantt[] = MasterFunctionsHelper::getLatestGantt($request);
- }
- foreach($allGantt as $gantt){
- $gantt = VersionGantt::where('id', $gantt['last_gantt_id'])->first()->toArray();
- if($gantt['calculation_type'] == 'simple') {
- // to do
- return MasterFunctionsHelper::calculateProgressBasedOnSimple($gantt);
- } else {
- return MasterFunctionsHelper::calculateProgressBasedOnReportMaterial($gantt);
- }
- }
- }
-
- public function calculateProgressBasedOnReportMaterial($keyGantt)
- {
- DB::enableQueryLog();
-
- $dataFinal=[];
- $dataPayload = [];
- $dataPayload['period'] = 'week';
-
- $dataProject = Project::find($keyGantt['proyek_id']);
- $dataHeader = Activity::where('type_activity', 'header')->where("proyek_id", $keyGantt['proyek_id'])->where("version_gantt_id", $keyGantt['id'])->first();
- if(isset($dataPayload['end_date']) && $dataPayload['end_date'] > $dataProject->akhir_proyek){
- $dataPayload['end_date'] = $dataProject->akhir_proyek;
- }
-
- if($dataHeader){
- $totalRencanaBudget = Activity::where('parent_id', $dataHeader->id)->where("proyek_id", $keyGantt['proyek_id'])->where("version_gantt_id", $keyGantt['id'])->sum("rencana_biaya");
- }else{
- $totalRencanaBudget = Activity::whereNull('parent_id')->where("proyek_id", $keyGantt['proyek_id'])->where("version_gantt_id", $keyGantt['id'])->sum("rencana_biaya");
- }
-
- if(!Activity::where("version_gantt_id", $keyGantt['id'])->first())
- return $dataFinal;
-
- $alreadyHasReport = DB::table('report_activity_material as a')
- ->select('a.id')
- ->join('m_activity as b', 'b.id', '=', 'a.activity_id')
- ->where('b.version_gantt_id', '=', $keyGantt['id'])
- ->exists();
-
- if(!$alreadyHasReport)
- return $dataFinal;
-
- $minDate = Activity::where('version_gantt_id', $keyGantt['id'])->whereNull('parent_id')->pluck('start_date')->first();
-
- $begin = new \DateTime($minDate.' Monday');
- if(isset($dataPayload['end_date'])){
- $maxDate = $dataPayload['end_date'];
- $end = new \DateTime($maxDate. ' Friday');
- $end->modify('next Friday');
- /* $interval = \DateInterval::createFromDateString('1 day'); */ // should be using this but its bugged
- $interval = new \DateInterval('P7D');
- } else {
- $maxDate = DB::table('assign_material_to_activity as ama')
- ->where("ama.proyek_id", $keyGantt['proyek_id'])
- ->join('m_activity as a', 'a.id', '=', 'ama.activity_id')
- ->where('a.version_gantt_id', '=', $keyGantt['id'])
- ->max("plan_date"); // plan date overlapped with assign_material_to_activity's, it should be m_activity's
- $end = new \DateTime($maxDate. ' Friday');
- $end->modify('next Friday');
- $interval = new \DateInterval('P7D');
- }
- $period = new \DatePeriod($begin, $interval, $end);
-
- $arr_ActualM = [];
- $tempDate = [];
- $tempPercentagePlan = [];
- $tempPercentagePlanWhr = [];
- $tempPercentageReal = [];
- $tempTtlPercentPlan=0;
- $tempTtlPercentActual=0;
-
- $currentACWP = 0;
- $currentBCWP = 0;
-
- foreach ($period as $dt) {
- $minSevenDays = new \Datetime($dt->format("Y-m-d"));
- $minSevenDays = $minSevenDays->modify('-7 day')->format("Y-m-d");
- $dataPlanM = DB::table('assign_material_to_activity as ama')
- ->select('ama.activity_id', 'ama.qty_planning', 'ama.plan_date', 'ama.start_activity', 'a.bobot_planning', 'a.biaya_actual', 'a.duration', 'a.persentase_progress')
- ->join('m_activity as a', 'a.id', '=', 'ama.activity_id')
- ->where('ama.proyek_id', '=', $keyGantt['proyek_id'])
- ->where('a.version_gantt_id', '=', $keyGantt['id'])
- ->whereDate('ama.plan_date', '<=',$dt->format("Y-m-d"))
- ->whereDate('ama.plan_date', '>', $minSevenDays)
- ->get();
- $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('assign_material_to_activity')
- ->select('activity_id', DB::raw('SUM(qty_planning) as ttl_qty_plan'))
- ->where('activity_id', '=', $keyPlanM->activity_id)
- ->groupBy('activity_id')
- ->first();
- $dataTempPlan [$x]['activity_id'] = $keyPlanM->activity_id;
- $dataTempPlan [$x]['qty_plan'] = $keyPlanM->qty_planning;
- $dataTempPlan [$x]['plan_date'] = $keyPlanM->plan_date;
- $dataTempPlan [$x]['start_activity'] = $keyPlanM->start_activity;
- $dataTempPlan [$x]['bobot_planning'] = $keyPlanM->bobot_planning;
- $dataTempPlan [$x]['ttl_plan'] = $sumVolPlan->ttl_qty_plan;
- $dataTempPlan [$x]['biaya_actual'] = $keyPlanM->biaya_actual;
- $dataTempPlan [$x]['duration'] = $keyPlanM->duration;
- $dataTempPlan [$x]['persentase_progress'] = $keyPlanM->persentase_progress;
- try {
- $dataTempPlan [$x]['percentage'] = ($keyPlanM->qty_planning/$sumVolPlan->ttl_qty_plan)*$keyPlanM->bobot_planning;
- $sumPercentagePlan+=($keyPlanM->qty_planning/$sumVolPlan->ttl_qty_plan)*$keyPlanM->bobot_planning;
- $totalBCWP += (((($keyPlanM->persentase_progress*$keyPlanM->bobot_planning)/100)/$keyPlanM->duration)* $totalRencanaBudget)/100;
- $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();
- $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 {
- $dataTempReport [$w]['percentage'] = ($keyActualM->qty/$sumVolActual->ttl_qty_plan)*$keyActualM->bobot_planning;
- $sumPercentageActual+=($keyActualM->qty/$sumVolActual->ttl_qty_plan)*$keyActualM->bobot_planning;
- $totalACWP += $keyActualM->biaya_actual/$keyActualM->duration;
- } catch (\DivisionByZeroError $e) {
- return response()->json(['message' => $e->getMessage()]);
- }
- $dataTempReport [$w]['totalacwp'] = $totalACWP;
- $w++;
- }
-
- $arr_ActualM[] = array(
- 'date'=>$dt->format("Y-m-d"),
- 'percentPlan'=>$sumPercentagePlan,
- 'percentActual'=>$sumPercentageActual,
- 'plan'=>$dataTempPlan,
- 'actual'=>$dataTempReport,
- );
- if(isset($dataPayload['period']) && $dataPayload['period'] == 'week'){
- $tempTtlPercentPlan+= $sumPercentagePlan;
- $tempTtlPercentActual+= $sumPercentageActual;
-
- if($tempTtlPercentPlan >= 100 || $tempTtlPercentActual >= 100){
- if($tempTtlPercentActual >= 100)
- $tempTtlPercentActual = 100;
- if($tempTtlPercentPlan >= 100)
- $tempTtlPercentPlan = 100;
- }
-
- $currentACWP += $totalACWP;
- $currentBCWP += $totalBCWP;
-
- $tempPercentage[] = array(round($tempTtlPercentPlan,2), round($tempTtlPercentActual,2));
- $tempPercentagePlan[] = round($tempTtlPercentPlan, 2);
- $tempPercentagePlanWhr[] = ["weekly period", $tempPercentagePlan];
- $tempPercentageReal[] = round($tempTtlPercentActual, 2);
- if($tempTtlPercentPlan >= 100 && $tempTtlPercentActual >= 100){
- break;
- }
- }else{
- $tempPercentage[] = array(round($sumPercentagePlan,2), round($sumPercentageActual,2));
- $tempPercentagePlan[] = round($sumPercentagePlan, 2);
- $tempPercentageReal[] = round($sumPercentageActual, 2);
- }
- $tempDate[] = array($dt->format("Y-m-d"));
- }
-
- try {
- if(round($totalACWP,0) > $totalRencanaBudget){
- $estimatedCost = round($totalACWP,0)+0;
- }else{
- $estimatedCost = ($totalRencanaBudget+0);
- }
- } catch (\DivisionByZeroError $e) {
- return response()->json([
- 'message' => $e->getMessage(),
- "line" => 566,
- 'gantt' => $keyGantt,
- ]);
- }
- $estimatedCost = $totalACWP > $totalRencanaBudget ? $totalACWP : $totalRencanaBudget;
-
- $costDeviation = $totalRencanaBudget - $estimatedCost;
- if($costDeviation > 0){
- $potential = "SAVING";
- } else {
- $potential = $costDeviation == 0 ? "ON BUDGET" : "OVERRUN";
- }
-
- $dataResponse = array(
- "date" =>$tempDate,
- "percentage" =>$tempPercentage,
- "percentagePlan" => $tempPercentagePlan,
- "percentageReal" => $tempPercentageReal,
- "data_details" =>$arr_ActualM,
- "budget_control" =>array("current_budget"=> $totalRencanaBudget,
- "acwp" => round($totalACWP,0),
- "bcwp" => round($totalBCWP,0),
- "rem_to_complete" => ($totalRencanaBudget - round($totalACWP,0)),
- "add_cost_to_complete" => 0,
- "estimated_at_completion" => $estimatedCost,
- "cost_deviation" => $costDeviation,
- "potential" => $potential,
- )
- );
-
- $dataFinal[] = array(
- "proyek_name"=> $dataProject->nama,
- "data"=>$dataResponse,
- "gantt"=>$keyGantt
- );
-
- return $dataFinal;
- }
-
- public function calculateProgressBasedOnSimple($keyGantt){
- DB::enableQueryLog();
-
- $dataFinal=[];
- $dataPayload = [];
- $dataPayload['period'] = 'week';
-
- $dataProject = Project::find($keyGantt['proyek_id']);
- $dataHeader = Activity::where('type_activity', 'header')->where("proyek_id", $keyGantt['proyek_id'])->where("version_gantt_id", $keyGantt['id'])->first();
- if(isset($dataPayload['end_date']) && $dataPayload['end_date'] > $dataProject->akhir_proyek){
- $dataPayload['end_date'] = $dataProject->akhir_proyek;
- }
-
- if($dataHeader){
- $totalRencanaBudget = Activity::where('parent_id', $dataHeader->id)->where("proyek_id", $keyGantt['proyek_id'])->where("version_gantt_id", $keyGantt['id'])->sum("rencana_biaya");
- }else{
- $totalRencanaBudget = Activity::whereNull('parent_id')->where("proyek_id", $keyGantt['proyek_id'])->where("version_gantt_id", $keyGantt['id'])->sum("rencana_biaya");
- }
-
- if(!Activity::where("version_gantt_id", $keyGantt['id'])->first())
- return $dataFinal;
-
- // $alreadyHasReport = DB::table('report_activity_material as a')
- // ->select('a.id')
- // ->join('m_activity as b', 'b.id', '=', 'a.activity_id')
- // ->where('b.version_gantt_id', '=', $keyGantt['id'])
- // ->exists();
-
- // if(!$alreadyHasReport)
- // return $dataFinal;
-
- $minDate = Activity::where('version_gantt_id', $keyGantt['id'])->whereNull('parent_id')->pluck('start_date')->first();
-
- $begin = new \DateTime($minDate.' Monday');
- if(isset($dataPayload['end_date'])){
- $maxDate = $dataPayload['end_date'];
- $end = new \DateTime($maxDate);
- /* $interval = \DateInterval::createFromDateString('1 day'); */ // should be using this but its bugged
- $interval = new \DateInterval('P7D');
- } else {
- // $maxDate = DB::table('assign_material_to_activity as ama')
- // ->where("ama.proyek_id", $keyGantt['proyek_id'])
- // ->join('m_activity as a', 'a.id', '=', 'ama.activity_id')
- // ->where('a.version_gantt_id', '=', $keyGantt['id'])
- // ->max("plan_date"); // plan date overlapped with assign_material_to_activity's, it should be m_activity's
- $maxDate = Activity::where('version_gantt_id', $keyGantt['id'])->whereNull('parent_id')->pluck('end_date')->first();
- $end = new \DateTime($maxDate. ' Friday');
- $interval = new \DateInterval('P7D');
- }
- $period = new \DatePeriod($begin, $interval, $end);
-
- $arr_ActualM = [];
- $tempDate = [];
- $tempPercentagePlan = [];
- $tempPercentagePlanWhr = [];
- $tempPercentageReal = [];
- $tempTtlPercentPlan=0;
- $tempTtlPercentActual=0;
-
- $currentACWP = 0;
- $currentBCWP = 0;
-
- foreach ($period as $dt) {
- $minSevenDays = new \Datetime($dt->format("Y-m-d"));
- $minSevenDays = $minSevenDays->modify('-7 day')->format("Y-m-d");
-
- $dataPlanM = DB::table('m_activity')
- ->select('id as activity_id', 'bobot_planning', 'start_date', 'biaya_actual', 'duration', 'persentase_progress')
- // ->join('m_activity as a', 'a.id', '=', 'activity_id')
- ->where('proyek_id', '=', $keyGantt['proyek_id'])
- ->where('type_activity', '=', 'task')
- ->where('version_gantt_id', '=', $keyGantt['id'])
- ->whereDate('start_date', '<=',$dt->format("Y-m-d"))
- ->whereDate('start_date', '>', $minSevenDays)
- ->get();
-
- $dataActualM = DB::table('m_activity as a')
- ->select('mapl.id as id_progress_log', 'mapl.activity_id', 'mapl.variance', 'mapl.created_at', 'a.bobot_planning', 'a.biaya_actual', 'a.duration', 'a.persentase_progress')
- ->join('m_activity_progress_log as mapl', 'a.id', '=', 'mapl.activity_id')
- ->where('a.version_gantt_id', '=', $keyGantt['id'])
- ->where('a.type_activity', '=', 'task')
- ->where('mapl.variance', '>', 0)
- ->where('a.proyek_id', '=', $keyGantt['proyek_id'])
- ->whereDate('mapl.created_at', '<=',$dt->format("Y-m-d"))
- ->whereDate('mapl.created_at', '>',$minSevenDays)
- ->get();
- $dataTempPlan = [];
- $x = 0;
- $sumPercentagePlan=0;
- $totalACWP = isset($totalACWP) ? $totalACWP : 0;
- $totalBCWP = isset($totalBCWP) ? $totalBCWP : 0;
-
- foreach ($dataPlanM as $keyPlanM) {
-
- $dataTempPlan [$x]['activity_id'] = $keyPlanM->activity_id;
- $dataTempPlan [$x]['qty_plan'] = $keyPlanM->bobot_planning;
- $dataTempPlan [$x]['plan_date'] = $keyPlanM->start_date;
- $dataTempPlan [$x]['start_activity'] = $keyPlanM->start_date;
- $dataTempPlan [$x]['bobot_planning'] = $keyPlanM->bobot_planning;
- $dataTempPlan [$x]['ttl_plan'] = $keyPlanM->bobot_planning;
- $dataTempPlan [$x]['biaya_actual'] = $keyPlanM->biaya_actual;
- $dataTempPlan [$x]['duration'] = $keyPlanM->duration;
- $dataTempPlan [$x]['persentase_progress'] = $keyPlanM->persentase_progress;
- try {
- $dataTempPlan [$x]['percentage'] = $keyPlanM->bobot_planning;
- $sumPercentagePlan+=$keyPlanM->bobot_planning;
- $totalBCWP += 0;
- $dataTempPlan [$x]['totalBCWP'] = $totalBCWP;
- } catch (\DivisionByZeroError $e) {
- return response()->json(['message' => $e->getMessage()]);
- }
- $x++;
- }
-
- $w = 0;
- $dataTempReport = [];
- $sumPercentageActual=0;
- foreach ($dataActualM as $keyActualM) {
- $sumVolActual = DB::table('m_activity_progress_log')
- ->select('id', DB::raw('SUM(variance) as ttl_percen_act'))
- ->where('id', '=', $keyActualM->id_progress_log)
- ->groupBy('id')
- ->first();
- $dataTempReport [$w]['id_progress_log'] = $keyActualM->id_progress_log;
- // $dataTempReport [$w]['qty'] = $keyActualM->qty;
- $dataTempReport [$w]['report_date'] = $keyActualM->created_at;
- $dataTempReport [$w]['bobot_planning'] = $keyActualM->bobot_planning;
- // $dataTempReport [$w]['ttl_plan'] = $sumVolActual->ttl_percen_act ? $sumVolActual->ttl_percen_act : 0;
- $dataTempReport [$w]['biaya_actual'] = $keyActualM->biaya_actual;
- $dataTempReport [$w]['duration'] = $keyActualM->duration;
- $dataTempReport [$w]['persentase_progress'] = $keyActualM->persentase_progress;
- try {
- $dataTempReport [$w]['percentage'] = $sumVolActual->ttl_percen_act ? ($sumVolActual->ttl_percen_act/100)*$keyActualM->bobot_planning : 0;
- $sumPercentageActual+=$sumVolActual->ttl_percen_act ? ($sumVolActual->ttl_percen_act/100)*$keyActualM->bobot_planning : 0;
- $totalACWP += $keyActualM->biaya_actual/$keyActualM->duration;
- } catch (\DivisionByZeroError $e) {
- return response()->json(['message' => $e->getMessage()]);
- }
- $dataTempReport [$w]['totalacwp'] = $totalACWP;
- $w++;
- }
-
- $arr_ActualM[] = array(
- 'date'=>$dt->format("Y-m-d"),
- 'percentPlan'=>$sumPercentagePlan,
- 'percentActual'=>$sumPercentageActual,
- 'plan'=>$dataTempPlan,
- 'actual'=>$dataTempReport,
- );
- if(isset($dataPayload['period']) && $dataPayload['period'] == 'week'){
- $tempTtlPercentPlan+= $sumPercentagePlan;
- $tempTtlPercentActual+= $sumPercentageActual;
-
- if($tempTtlPercentPlan >= 100 || $tempTtlPercentActual >= 100){
- if($tempTtlPercentActual >= 100)
- $tempTtlPercentActual = 100;
- if($tempTtlPercentPlan >= 100)
- $tempTtlPercentPlan = 100;
- }
-
- $currentACWP += $totalACWP;
- $currentBCWP += $totalBCWP;
-
- $tempPercentage[] = array(round($tempTtlPercentPlan,2), round($tempTtlPercentActual,2));
- $tempPercentagePlan[] = round($tempTtlPercentPlan, 2);
- $tempPercentagePlanWhr[] = ["weekly period", $tempPercentagePlan];
- $tempPercentageReal[] = round($tempTtlPercentActual, 2);
- if($tempTtlPercentPlan >= 100 && $tempTtlPercentActual >= 100){
- break;
- }
- }else{
- $tempPercentage[] = array(round($sumPercentagePlan,2), round($sumPercentageActual,2));
- $tempPercentagePlan[] = round($sumPercentagePlan, 2);
- $tempPercentageReal[] = round($sumPercentageActual, 2);
- }
- $tempDate[] = array($dt->format("Y-m-d"));
- }
-
- try {
- if(round($totalACWP,0) > $totalRencanaBudget){
- $estimatedCost = round($totalACWP,0)+0;
- }else{
- $estimatedCost = ($totalRencanaBudget+0);
- }
- } catch (\DivisionByZeroError $e) {
- return response()->json([
- 'message' => $e->getMessage(),
- "line" => 566,
- 'gantt' => $keyGantt,
- ]);
- }
- $estimatedCost = $totalACWP > $totalRencanaBudget ? $totalACWP : $totalRencanaBudget;
-
- $costDeviation = $totalRencanaBudget - $estimatedCost;
- if($costDeviation > 0){
- $potential = "SAVING";
- } else {
- $potential = $costDeviation == 0 ? "ON BUDGET" : "OVERRUN";
- }
-
- $dataResponse = array(
- "date" =>$tempDate,
- "percentage" =>$tempPercentage,
- "percentagePlan" => $tempPercentagePlan,
- "percentageReal" => $tempPercentageReal,
- "data_details" =>$arr_ActualM,
- "budget_control" =>array("current_budget"=> $totalRencanaBudget,
- "acwp" => round($totalACWP,0),
- "bcwp" => round($totalBCWP,0),
- "rem_to_complete" => ($totalRencanaBudget - round($totalACWP,0)),
- "add_cost_to_complete" => 0,
- "estimated_at_completion" => $estimatedCost,
- "cost_deviation" => $costDeviation,
- "potential" => $potential,
- )
- );
-
- $dataFinal[] = array(
- "proyek_name"=> $dataProject->nama,
- "data"=>$dataResponse,
- "gantt"=>$keyGantt,
- );
-
- return $dataFinal;
- }
-
-}
+first()->config_dayoff;
+ $diff = date_diff($start, $end);
+ $endCount = clone $end;
+ $duration = $diff->days + 1;
+ $daysRemaining = $duration;
+ // Loop until the remaining days become zero
+ while ($daysRemaining > 0) {
+ $endCount->modify('-1 day');
+ // Check if the current day is a day off (Sunday or Saturday)
+ $currentDayOfWeek = (int) $endCount->format('w');
+ if (strpos($dayOffs, (string) $currentDayOfWeek) !== false) {
+ // continue; // Skip the day off and continue to the next day
+ $duration--;
+ }
+ $daysRemaining--; // Decrease the remaining days by one
+ }
+ return $duration;
+ }
+
+ public function getLatestGantt($id)
+ {
+ $maxGanttId = VersionGantt::where("proyek_id", $id)->max("id");
+ if (!$maxGanttId) {
+ $data = array(
+ "proyek_id" => $id
+ );
+ } else {
+ $data = array(
+ "last_gantt_id" => $maxGanttId,
+ "proyek_id" => $id
+ );
+ }
+ return $data;
+ }
+
+ // dipake di dashboard project & bod
+ public function getSCurve($request)
+ {
+ $allGantt = [];
+ if (!is_int($request)) {
+ $dataPayload = $request->all();
+ if (isset($dataPayload['gantt_id'])) {
+ $allGantt[] = $dataPayload['gantt_id'];
+ } else {
+ $allGantt[] = MasterFunctionsHelper::getLatestGantt($dataPayload['project_id']);
+ }
+ } else {
+ $allGantt[] = MasterFunctionsHelper::getLatestGantt($request);
+ }
+ foreach ($allGantt as $gantt) {
+ if (!isset($gantt['last_gantt_id'])) {
+ $ganttId = $gantt;
+ } else {
+ $ganttId = $gantt['last_gantt_id'];
+ }
+ $gantt = VersionGantt::find($ganttId)->toArray();
+ // foreach ($gantt as $key => $value) {
+ // Log::info('gantt '.$value.' index '.$key);
+ // }
+ if (isset($gantt['calculation_type'])) {
+ if ($gantt['calculation_type'] == 'simple') {
+ // to do
+ return MasterFunctionsHelper::calculateProgressBasedOnSimple($gantt);
+ } else {
+ return MasterFunctionsHelper::calculateProgressBasedOnReportMaterial($gantt);
+ }
+ }
+ }
+ }
+
+ public function getLinearSCurve($request)
+ {
+ $ftths = HierarchyFtth::where('project_id', $request->project_id)->get();
+ $ttlProgress = 0;
+ $ttlPlanning = 0;
+
+ foreach ($ftths as $ftth) {
+ $progress = VersionGantt::where('hierarchy_ftth_id', $ftth->id)->sum('progress');
+ $planning = VersionGantt::where('hierarchy_ftth_id', $ftth->id)->sum('bobot');
+ $ttlProgress += $progress;
+ $ttlPlanning += $planning;
+ }
+
+ $minDate = Project::select('mulai_proyek')->where('id', $request->project_id)->first();
+ $maxDate = Project::select('akhir_proyek')->where('id', $request->project_id)->first();
+
+ $begin = new \DateTime($minDate->mulai_proyek . ' Monday');
+
+ $end = new \DateTime($maxDate->akhir_proyek . ' Friday');
+
+ $interval = new \DateInterval('P7D');
+
+ $period = new \DatePeriod($begin, $interval, $end);
+ $dates = iterator_to_array($period);
+ $count = count($dates);
+
+ $avgProgress = $ttlProgress / $ttlPlanning / $count * 100;
+ $avgPlanning = $ttlPlanning / $ttlPlanning / $count * 100;
+ $progressData = [];
+ $planningData = [];
+ $dates = [];
+ $tempProgress = 0;
+ $tempPlanning = 0;
+ array_push($progressData, round($tempProgress, 2));
+ array_push($planningData, round($tempPlanning, 2));
+ foreach ($period as $p) {
+ $tempProgress += $avgProgress;
+ $tempPlanning += $avgPlanning;
+ array_push($progressData, round($tempProgress, 2));
+ array_push($planningData, round($tempPlanning, 2));
+ array_push($dates, $p->format("Y-m-d"));
+ }
+
+ $dataResponse = array(
+ "percentagePlan" => $planningData,
+ "percentageReal" => $progressData,
+ "date" => $dates,
+ );
+
+ $dataFinal[] = array(
+ "data" => $dataResponse,
+ );
+ return $dataFinal;
+ }
+
+ public function calculateProgressBasedOnReportMaterial($keyGantt)
+ {
+ DB::enableQueryLog();
+
+ $dataFinal = [];
+ $dataPayload = [];
+ $dataPayload['period'] = 'week';
+ $totalACWP = 0;
+ $totalBCWP = 0;
+ $tempPercentage = [];
+
+ $dataProject = Project::find($keyGantt['proyek_id']);
+ $dataHeader = Activity::where('type_activity', 'header')->where("proyek_id", $keyGantt['proyek_id'])->where("version_gantt_id", $keyGantt['id'])->first();
+ if (isset($dataPayload['end_date']) && $dataPayload['end_date'] > $dataProject->akhir_proyek) {
+ $dataPayload['end_date'] = $dataProject->akhir_proyek;
+ }
+
+ if ($dataHeader) {
+ $totalRencanaBudget = Activity::where('parent_id', $dataHeader->id)->where("proyek_id", $keyGantt['proyek_id'])->where("version_gantt_id", $keyGantt['id'])->sum("rencana_biaya");
+ } else {
+ $totalRencanaBudget = Activity::whereNull('parent_id')->where("proyek_id", $keyGantt['proyek_id'])->where("version_gantt_id", $keyGantt['id'])->sum("rencana_biaya");
+ }
+
+ if (!Activity::where("version_gantt_id", $keyGantt['id'])->first())
+ return $dataFinal;
+
+ $alreadyHasReport = DB::table('report_activity_material as a')
+ ->select('a.id')
+ ->join('m_activity as b', 'b.id', '=', 'a.activity_id')
+ ->where('b.version_gantt_id', '=', $keyGantt['id'])
+ ->exists();
+ // note : delete this
+ // if(!$alreadyHasReport)
+ // return $dataFinal;
+
+ $minDate = Activity::where('version_gantt_id', $keyGantt['id'])->whereNull('parent_id')->pluck('start_date')->first();
+
+ $begin = new \DateTime($minDate . ' Monday');
+ $begin->modify('last Monday');
+ if (isset($dataPayload['end_date'])) {
+ $maxDate = $dataPayload['end_date'];
+ $end = new \DateTime($maxDate . ' Friday');
+ $end->modify('next Friday');
+ $end->modify('next Friday');
+ /* $interval = \DateInterval::createFromDateString('1 day'); */// should be using this but its bugged
+ $interval = new \DateInterval('P7D');
+ } else {
+ $actualMaxDate = DB::table('assign_material_to_activity as ama')
+ ->where("ama.proyek_id", $keyGantt['proyek_id'])
+ ->join('m_activity as a', 'a.id', '=', 'ama.activity_id')
+ ->where('a.version_gantt_id', '=', $keyGantt['id'])
+ ->max("a.end_date"); // plan date overlapped with assign_material_to_activity's, it should be m_activity's
+ $plannedMaxDate = DB::table('assign_material_to_activity as ama')
+ ->where("ama.proyek_id", $keyGantt['proyek_id'])
+ ->join('m_activity as a', 'a.id', '=', 'ama.activity_id')
+ ->where('a.version_gantt_id', '=', $keyGantt['id'])
+ ->max("a.planned_end"); // plan date overlapped with assign_material_to_activity's, it should be m_activity'
+ $maxDate = max(new \DateTime($plannedMaxDate), new \DateTime($actualMaxDate));
+ $end = new \DateTime($maxDate->format('Y-m-d') . ' Friday');
+ $end->modify('next Friday');
+ $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');
+ $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 += $keyPlanM->bobot_planning;
+ 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->biaya_actual / $keyActualM->duration;
+ } catch (\DivisionByZeroError $e) {
+ return response()->json(['message' => $e->getMessage()]);
+ }
+ $dataTempReport[$w]['totalacwp'] = $totalACWP;
+ $w++;
+ }
+
+ $arr_ActualM[] = array(
+ 'date' => $dt->format("Y-m-d"),
+ 'percentPlan' => $sumPercentagePlan,
+ 'percentActual' => $sumPercentageActual,
+ 'plan' => $dataTempPlan,
+ 'actual' => $dataTempReport,
+ );
+ if (isset($dataPayload['period']) && $dataPayload['period'] == 'week') {
+ $tempTtlPercentPlan += $sumPercentagePlan;
+ $tempTtlPercentActual += $sumPercentageActual;
+
+ // if($tempTtlPercentPlan >= 100 || $tempTtlPercentActual >= $keyGantt['progress'];){
+ // if($tempTtlPercentActual >= 100)
+ // $tempTtlPercentActual = 100;
+ // if($tempTtlPercentPlan >= 100)
+ // $tempTtlPercentPlan = 100;
+
+ // if($tempTtlPercentActual >= $keyGantt['progress'])
+ // $tempTtlPercentActual = $keyGantt['progress'];
+ if ($tempTtlPercentPlan >= 100)
+ $tempTtlPercentPlan = 100;
+ // $sumPercentageActual > $keyGantt['progress'] ? $keyGantt['progress'] : $sumPercentageActual
+
+ // }
+
+ $currentACWP += $totalACWP;
+ $currentBCWP += $totalBCWP;
+
+ $tempPercentage[] = array(round($tempTtlPercentPlan, 2), round($tempTtlPercentActual, 2));
+ $tempPercentagePlan[] = round($tempTtlPercentPlan, 2);
+ $tempPercentagePlanWhr[] = ["weekly period", $tempPercentagePlan];
+ $tempPercentageReal[] = round($tempTtlPercentActual, 2);
+ if ($tempTtlPercentPlan >= 100 && $tempTtlPercentActual >= 100) {
+ break;
+ }
+ } else {
+ $tempPercentage[] = array(round($sumPercentagePlan, 2), round($sumPercentageActual, 2));
+ $tempPercentagePlan[] = round($sumPercentagePlan, 2);
+ $tempPercentageReal[] = round($sumPercentageActual, 2);
+ }
+ }
+
+ try {
+ if (round($totalACWP, 0) > $totalRencanaBudget) {
+ $estimatedCost = round($totalACWP, 0) + 0;
+ } else {
+ $estimatedCost = ($totalRencanaBudget + 0);
+ }
+ } catch (\DivisionByZeroError $e) {
+ return response()->json([
+ 'message' => $e->getMessage(),
+ "line" => 566,
+ 'gantt' => $keyGantt,
+ ]);
+ }
+ $estimatedCost = $totalACWP > $totalRencanaBudget ? $totalACWP : $totalRencanaBudget;
+
+ $costDeviation = $totalRencanaBudget - $estimatedCost;
+ if ($costDeviation > 0) {
+ $potential = "SAVING";
+ } else {
+ $potential = $costDeviation == 0 ? "ON BUDGET" : "OVERRUN";
+ }
+
+ $lastReal = $tempPercentageReal[count($tempPercentageReal) - 1];
+ $totalBCWP = $lastReal * $dataProject->rencana_biaya / 100;
+ $dataResponse = array(
+ "date" => $tempDate,
+ "percentage" => $tempPercentage,
+ "percentagePlan" => $tempPercentagePlan,
+ "percentageReal" => $tempPercentageReal,
+ "data_details" => $arr_ActualM,
+ "budget_control" => array(
+ "current_budget" => $totalRencanaBudget,
+ "acwp" => round($totalACWP, 0),
+ "bcwp" => round($totalBCWP, 0),
+ "rem_to_complete" => ($totalRencanaBudget - round($totalACWP, 0)),
+ "add_cost_to_complete" => 0,
+ "estimated_at_completion" => $estimatedCost,
+ "cost_deviation" => $costDeviation,
+ "potential" => $potential,
+ )
+ );
+
+ $dataFinal[] = array(
+ "proyek_name" => $dataProject->nama,
+ "data" => $dataResponse,
+ "gantt" => $keyGantt
+ );
+
+ return $dataFinal;
+ }
+
+ public function calculateSCurve($projectId)
+ {
+ DB::enableQueryLog();
+
+ $dataFinal = [];
+ $dataPayload = [];
+ $dataPayload['period'] = 'week';
+ $totalACWP = 0;
+ $totalBCWP = 0;
+ $tempPercentage = [];
+
+ $dataProject = Project::find($projectId);
+ $dataHeader = Activity::where('type_activity', 'header')->where("proyek_id", $projectId)->first();
+ if (isset($dataPayload['end_date']) && $dataPayload['end_date'] > $dataProject->akhir_proyek) {
+ $dataPayload['end_date'] = $dataProject->akhir_proyek;
+ }
+
+ if ($dataHeader) {
+ $totalRencanaBudget = Activity::where('parent_id', $dataHeader->id)->where("proyek_id", $projectId)->sum("rencana_biaya");
+ } else {
+ $totalRencanaBudget = Activity::whereNull('parent_id')->where("proyek_id", $projectId)->sum("rencana_biaya");
+ }
+
+ $alreadyHasReport = DB::table('report_activity_material as a')
+ ->select('a.id')
+ ->join('m_activity as b', 'b.id', '=', 'a.activity_id')
+ ->exists();
+
+ $minDate = $dataProject->mulai_proyek;
+
+ $begin = new \DateTime($minDate);
+ $begin->modify('last Monday');
+ if (isset($dataPayload['end_date'])) {
+ $maxDate = $dataPayload['end_date'];
+ $end = new \DateTime($maxDate);
+ $end->modify('next Friday');
+ $end->modify('next Friday');
+ /* $interval = \DateInterval::createFromDateString('1 day'); */// should be using this but its bugged
+ $interval = new \DateInterval('P7D');
+ } else {
+ // $maxDate = DB::table('assign_material_to_activity as ama')
+ // ->where("ama.proyek_id", $projectId)
+ // ->join('m_activity as a', 'a.id', '=', 'ama.activity_id')
+ // ->max("plan_date"); // plan date overlapped with assign_material_to_activity's, it should be m_activity's
+ $maxDate = $dataProject->akhir_proyek;
+ $end = new \DateTime($maxDate);
+ $end->modify('next Friday');
+ $end->modify('next Friday');
+ $interval = new \DateInterval('P7D');
+ }
+ $period = new \DatePeriod($begin, $interval, $end);
+
+ $arr_ActualM = [];
+ $tempDate = [];
+ $tempPercentagePlan = [];
+ $tempPercentagePlanWhr = [];
+ $tempPercentageReal = [];
+ $tempTtlPercentPlan = 0;
+ $tempTtlPercentActual = 0;
+
+ $currentACWP = 0;
+ $currentBCWP = 0;
+
+ foreach ($period as $dt) {
+ $minSevenDays = new \Datetime($dt->format("Y-m-d"));
+ $minSevenDays = $minSevenDays->modify('-7 day')->format("Y-m-d");
+ // $dataPlanM = DB::table('assign_material_to_activity as ama')
+ // ->select('ama.activity_id', 'ama.qty_planning', 'ama.plan_date', 'ama.start_activity', 'a.bobot_planning', 'a.biaya_actual', 'a.duration', 'a.persentase_progress')
+ // ->join('m_activity as a', 'a.id', '=', 'ama.activity_id')
+ // ->where('ama.proyek_id', '=', $keyGantt['proyek_id'])
+ // ->where('a.version_gantt_id', '=', $keyGantt['id'])
+ // ->whereDate('ama.plan_date', '<=',$dt->format("Y-m-d"))
+ // ->whereDate('ama.plan_date', '>', $minSevenDays)
+ // ->get();
+
+ $activities = DB::table('m_activity AS a')
+ ->join('assign_material_to_activity AS amta', 'amta.activity_id', '=', 'a.id')
+ ->where('a.type_activity', 'task')
+ ->where('a.bobot_planning', '>', 0)
+ ->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)
+ ->whereDate('a.start_date', '<=', $dt->format("Y-m-d"))
+ ->whereDate('a.start_date', '>', $minSevenDays)
+ ->select('a.bobot_planning', 'a.biaya_actual', 'a.duration', 'a.persentase_progress', 'a.id')
+ ->union($activities)
+ ->get();
+
+ $dataActualM = DB::table('report_activity_material as ram')
+ ->select('ram.activity_id', 'ram.qty', 'ram.report_date', 'a.bobot_planning', 'a.biaya_actual', 'a.duration', 'a.persentase_progress')
+ ->join('m_activity as a', 'a.id', '=', 'ram.activity_id')
+ ->where('a.proyek_id', '=', $projectId)
+ ->whereDate('ram.report_date', '<=', $dt->format("Y-m-d"))
+ ->whereDate('ram.report_date', '>', $minSevenDays)
+ ->get();
+ $dataTempPlan = [];
+ $x = 0;
+ $sumPercentagePlan = 0;
+ $totalACWP = isset($totalACWP) ? $totalACWP : 0;
+ $totalBCWP = isset($totalBCWP) ? $totalBCWP : 0;
+
+ foreach ($dataPlanM as $keyPlanM) {
+ $sumVolPlan = DB::table(function ($query) {
+ $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)
+ ->unionAll(function ($query) {
+ $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);
+ })->orderBy('id', 'asc');
+ }, 'subquery')
+ ->sum('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 += $keyPlanM->bobot_planning;
+ if (isset($keyPlanM->duration) && $keyPlanM->duration > 0)
+ $totalBCWP += (((($keyPlanM->persentase_progress * $keyPlanM->bobot_planning) / 100) / $keyPlanM->duration) * $totalRencanaBudget) / 100;
+ else
+ $totalBCWP = 0;
+ $dataTempPlan[$x]['totalBCWP'] = $totalBCWP;
+ } catch (\DivisionByZeroError $e) {
+ return response()->json(['message' => $e->getMessage()]);
+ }
+ $x++;
+ }
+
+ $w = 0;
+ $dataTempReport = [];
+ $sumPercentageActual = 0;
+ foreach ($dataActualM as $keyActualM) {
+ $sumVolActual = DB::table('assign_material_to_activity')
+ ->select('activity_id', DB::raw('SUM(qty_planning) as ttl_qty_plan'))
+ ->where('activity_id', '=', $keyActualM->activity_id)
+ ->groupBy('activity_id')
+ ->first();
+ if (!isset($sumVolActual)) {
+ $sumVolActual = (object) [
+ 'activity_id' => $keyActualM->activity_id,
+ 'ttl_qty_plan' => "0"
+ ];
+ }
+ $sumReportActual = DB::table('report_activity_material')
+ ->where('activity_id', $keyActualM->activity_id)
+ ->sum('qty');
+ $reportCount = DB::table('report_activity_material')->where('activity_id', '=', $keyActualM->activity_id)->count();
+ $dataTempReport[$w]['activity_id'] = $keyActualM->activity_id;
+ $dataTempReport[$w]['qty'] = $keyActualM->qty;
+ $dataTempReport[$w]['report_date'] = $keyActualM->report_date;
+ $dataTempReport[$w]['bobot_planning'] = $keyActualM->bobot_planning;
+ $dataTempReport[$w]['ttl_plan'] = $sumVolActual->ttl_qty_plan;
+ $dataTempReport[$w]['biaya_actual'] = $keyActualM->biaya_actual;
+ $dataTempReport[$w]['duration'] = $keyActualM->duration;
+ $dataTempReport[$w]['persentase_progress'] = $keyActualM->persentase_progress;
+ try {
+ // assign_material_to_activity
+ $checkStatusActivity = DB::table('assign_material_to_activity')
+ ->select('activity_id', 'status_activity')
+ ->where('activity_id', '=', $keyActualM->activity_id)
+ ->orderBy('status_activity', 'ASC')
+ ->first();
+ if (!isset($checkStatusActivity)) {
+ $checkStatusActivity = (object) [
+ 'activity_id' => $keyActualM->activity_id,
+ 'status_activity' => 'open'
+ ];
+ }
+ if ($sumVolActual->ttl_qty_plan == "0") {
+ $actual = 0;
+ } else {
+ $actual = $keyActualM->qty / $sumVolActual->ttl_qty_plan;
+ }
+ $dataTempReport[$w]['percentage'] = $actual * $keyActualM->bobot_planning;
+ // $sumPercentageActual+=($keyActualM->qty/$sumVolActual->ttl_qty_plan)*$keyActualM->bobot_planning;
+ // if($keyActualM->qty/$sumVolActual->ttl_qty_plan >= 1){
+ if ($checkStatusActivity->status_activity == 'done') {
+ $sumPercentageActual += $keyActualM->bobot_planning / $reportCount;
+ // $sumPercentageActual = $sumPercentageActual > $keyGantt['progress'] ? $keyGantt['progress'] : $sumPercentageActual;
+ } else {
+ if ( $actual >= 1 || (int) $sumVolActual->ttl_qty_plan == (int) $sumReportActual) {
+ $sumPercentageActual += ($actual * $keyActualM->bobot_planning) * (95 / 100);
+ // $sumPercentageActual = $sumPercentageActual > $keyGantt['progress'] ? $keyGantt['progress'] : $sumPercentageActual;
+ } else {
+ $sumPercentageActual += $actual * $keyActualM->bobot_planning;
+ // $sumPercentageActual = $sumPercentageActual > $keyGantt['progress'] ? $keyGantt['progress'] : $sumPercentageActual;
+ }
+ }
+ // }else {
+ // if($checkStatusActivity->status_activity == 'done'){
+ // $sumPercentageActual+=($keyActualM->qty/$keyActualM->qty)*$keyActualM->bobot_planning;
+ // }else{
+ // $sumPercentageActual+=($keyActualM->qty/$sumVolActual->ttl_qty_plan)*$keyActualM->bobot_planning;
+ // }
+ // }
+
+
+ $totalACWP += $keyActualM->duration > 0 ? $keyActualM->biaya_actual / $keyActualM->duration : 0;
+ } catch (\DivisionByZeroError $e) {
+ return response()->json(['message' => $e->getMessage()]);
+ }
+ $dataTempReport[$w]['totalacwp'] = $totalACWP;
+ $w++;
+ }
+
+ $arr_ActualM[] = array(
+ 'date' => $dt->format("Y-m-d"),
+ 'percentPlan' => $sumPercentagePlan,
+ 'percentActual' => $sumPercentageActual,
+ 'plan' => $dataTempPlan,
+ 'actual' => $dataTempReport,
+ );
+ if (isset($dataPayload['period']) && $dataPayload['period'] == 'week') {
+ $tempTtlPercentPlan += $sumPercentagePlan;
+ $tempTtlPercentActual += $sumPercentageActual;
+
+ $currentACWP += $totalACWP;
+ $currentBCWP += $totalBCWP;
+
+ $tempPercentage[] = array(round($tempTtlPercentPlan, 2), round($tempTtlPercentActual, 2));
+ $tempPercentagePlan[] = round($tempTtlPercentPlan, 2);
+ $tempPercentagePlanWhr[] = ["weekly period", $tempPercentagePlan];
+ $tempPercentageReal[] = round($tempTtlPercentActual, 2);
+ } else {
+ $tempPercentage[] = array(round($sumPercentagePlan, 2), round($sumPercentageActual, 2));
+ $tempPercentagePlan[] = round($sumPercentagePlan, 2);
+ $tempPercentageReal[] = round($sumPercentageActual, 2);
+ }
+ $tempDate[] = array($dt->format("Y-m-d"));
+ }
+
+ try {
+ if (round($totalACWP, 0) > $totalRencanaBudget) {
+ $estimatedCost = round($totalACWP, 0) + 0;
+ } else {
+ $estimatedCost = ($totalRencanaBudget + 0);
+ }
+ } catch (\DivisionByZeroError $e) {
+ return response()->json([
+ 'message' => $e->getMessage(),
+ "line" => 566,
+ ]);
+ }
+ $estimatedCost = $totalACWP > $totalRencanaBudget ? $totalACWP : $totalRencanaBudget;
+
+ $costDeviation = $totalRencanaBudget - $estimatedCost;
+ if ($costDeviation > 0) {
+ $potential = "SAVING";
+ } else {
+ $potential = $costDeviation == 0 ? "ON BUDGET" : "OVERRUN";
+ }
+
+ $lastReal = $tempPercentageReal[count($tempPercentageReal) - 1];
+ $totalBCWP = $lastReal * $dataProject->rencana_biaya / 100;
+ $dataResponse = array(
+ "date" => $tempDate,
+ "percentage" => $tempPercentage,
+ "percentagePlan" => $tempPercentagePlan,
+ "percentageReal" => $tempPercentageReal,
+ "data_details" => $arr_ActualM,
+ "budget_control" => array(
+ "current_budget" => $totalRencanaBudget,
+ "acwp" => round($totalACWP, 0),
+ "bcwp" => round($totalBCWP, 0),
+ "rem_to_complete" => ($totalRencanaBudget - round($totalACWP, 0)),
+ "add_cost_to_complete" => 0,
+ "estimated_at_completion" => $estimatedCost,
+ "cost_deviation" => $costDeviation,
+ "potential" => $potential,
+ )
+ );
+
+ $dataFinal[] = array(
+ "proyek_name" => $dataProject->nama,
+ "data" => $dataResponse,
+ );
+
+ return $dataFinal;
+ }
+
+ public function calculateProgressBasedOnSimple($keyGantt)
+ {
+ DB::enableQueryLog();
+
+ $dataFinal = [];
+ $dataPayload = [];
+ $dataPayload['period'] = 'week';
+
+ $dataProject = Project::find($keyGantt['proyek_id']);
+ $dataHeader = Activity::where('type_activity', 'header')->where("proyek_id", $keyGantt['proyek_id'])->where("version_gantt_id", $keyGantt['id'])->first();
+ if (isset($dataPayload['end_date']) && $dataPayload['end_date'] > $dataProject->akhir_proyek) {
+ $dataPayload['end_date'] = $dataProject->akhir_proyek;
+ }
+
+ if ($dataHeader) {
+ $totalRencanaBudget = Activity::where('parent_id', $dataHeader->id)->where("proyek_id", $keyGantt['proyek_id'])->where("version_gantt_id", $keyGantt['id'])->sum("rencana_biaya");
+ } else {
+ $totalRencanaBudget = Activity::whereNull('parent_id')->where("proyek_id", $keyGantt['proyek_id'])->where("version_gantt_id", $keyGantt['id'])->sum("rencana_biaya");
+ }
+
+ if (!Activity::where("version_gantt_id", $keyGantt['id'])->first())
+ return $dataFinal;
+
+ // $alreadyHasReport = DB::table('report_activity_material as a')
+ // ->select('a.id')
+ // ->join('m_activity as b', 'b.id', '=', 'a.activity_id')
+ // ->where('b.version_gantt_id', '=', $keyGantt['id'])
+ // ->exists();
+
+ // if(!$alreadyHasReport)
+ // return $dataFinal;
+
+ $minDate = Activity::where('version_gantt_id', $keyGantt['id'])->whereNull('parent_id')->pluck('start_date')->first();
+
+ $begin = new \DateTime($minDate . ' Monday');
+ if (isset($dataPayload['end_date'])) {
+ $maxDate = $dataPayload['end_date'];
+ $end = new \DateTime($maxDate);
+ /* $interval = \DateInterval::createFromDateString('1 day'); */// should be using this but its bugged
+ $interval = new \DateInterval('P7D');
+ } else {
+ // $maxDate = DB::table('assign_material_to_activity as ama')
+ // ->where("ama.proyek_id", $keyGantt['proyek_id'])
+ // ->join('m_activity as a', 'a.id', '=', 'ama.activity_id')
+ // ->where('a.version_gantt_id', '=', $keyGantt['id'])
+ // ->max("plan_date"); // plan date overlapped with assign_material_to_activity's, it should be m_activity's
+ $maxDate = Activity::where('version_gantt_id', $keyGantt['id'])->whereNull('parent_id')->pluck('end_date')->first();
+ $end = new \DateTime($maxDate . ' Friday');
+ $interval = new \DateInterval('P7D');
+ }
+ $period = new \DatePeriod($begin, $interval, $end);
+
+ $arr_ActualM = [];
+ $tempDate = [];
+ $tempPercentagePlan = [];
+ $tempPercentagePlanWhr = [];
+ $tempPercentageReal = [];
+ $tempTtlPercentPlan = 0;
+ $tempTtlPercentActual = 0;
+
+ $currentACWP = 0;
+ $currentBCWP = 0;
+
+ foreach ($period as $dt) {
+ $minSevenDays = new \Datetime($dt->format("Y-m-d"));
+ $minSevenDays = $minSevenDays->modify('-7 day')->format("Y-m-d");
+
+ $dataPlanM = DB::table('m_activity')
+ ->select('id as activity_id', 'bobot_planning', 'start_date', 'biaya_actual', 'duration', 'persentase_progress')
+ // ->join('m_activity as a', 'a.id', '=', 'activity_id')
+ ->where('proyek_id', '=', $keyGantt['proyek_id'])
+ ->where('type_activity', '=', 'task')
+ ->where('version_gantt_id', '=', $keyGantt['id'])
+ ->whereDate('start_date', '<=', $dt->format("Y-m-d"))
+ ->whereDate('start_date', '>', $minSevenDays)
+ ->get();
+
+ $dataActualM = DB::table('m_activity as a')
+ ->select('mapl.id as id_progress_log', 'mapl.activity_id', 'mapl.variance', 'mapl.created_at', 'a.bobot_planning', 'a.biaya_actual', 'a.duration', 'a.persentase_progress')
+ ->join('m_activity_progress_log as mapl', 'a.id', '=', 'mapl.activity_id')
+ ->where('a.version_gantt_id', '=', $keyGantt['id'])
+ ->where('a.type_activity', '=', 'task')
+ ->where('mapl.variance', '>', 0)
+ ->where('a.proyek_id', '=', $keyGantt['proyek_id'])
+ ->whereDate('mapl.created_at', '<=', $dt->format("Y-m-d"))
+ ->whereDate('mapl.created_at', '>', $minSevenDays)
+ ->get();
+ $dataTempPlan = [];
+ $x = 0;
+ $sumPercentagePlan = 0;
+ $totalACWP = isset($totalACWP) ? $totalACWP : 0;
+ $totalBCWP = isset($totalBCWP) ? $totalBCWP : 0;
+
+ foreach ($dataPlanM as $keyPlanM) {
+
+ $dataTempPlan[$x]['activity_id'] = $keyPlanM->activity_id;
+ $dataTempPlan[$x]['qty_plan'] = $keyPlanM->bobot_planning;
+ $dataTempPlan[$x]['plan_date'] = $keyPlanM->start_date;
+ $dataTempPlan[$x]['start_activity'] = $keyPlanM->start_date;
+ $dataTempPlan[$x]['bobot_planning'] = $keyPlanM->bobot_planning;
+ $dataTempPlan[$x]['ttl_plan'] = $keyPlanM->bobot_planning;
+ $dataTempPlan[$x]['biaya_actual'] = $keyPlanM->biaya_actual;
+ $dataTempPlan[$x]['duration'] = $keyPlanM->duration;
+ $dataTempPlan[$x]['persentase_progress'] = $keyPlanM->persentase_progress;
+ try {
+ $dataTempPlan[$x]['percentage'] = $keyPlanM->bobot_planning;
+ $sumPercentagePlan += $keyPlanM->bobot_planning;
+ $totalBCWP += 0;
+ $dataTempPlan[$x]['totalBCWP'] = $totalBCWP;
+ } catch (\DivisionByZeroError $e) {
+ return response()->json(['message' => $e->getMessage()]);
+ }
+ $x++;
+ }
+
+ $w = 0;
+ $dataTempReport = [];
+ $sumPercentageActual = 0;
+ foreach ($dataActualM as $keyActualM) {
+ $sumVolActual = DB::table('m_activity_progress_log')
+ ->select('id', DB::raw('SUM(variance) as ttl_percen_act'))
+ ->where('id', '=', $keyActualM->id_progress_log)
+ ->groupBy('id')
+ ->first();
+ $dataTempReport[$w]['id_progress_log'] = $keyActualM->id_progress_log;
+ // $dataTempReport [$w]['qty'] = $keyActualM->qty;
+ $dataTempReport[$w]['report_date'] = $keyActualM->created_at;
+ $dataTempReport[$w]['bobot_planning'] = $keyActualM->bobot_planning;
+ // $dataTempReport [$w]['ttl_plan'] = $sumVolActual->ttl_percen_act ? $sumVolActual->ttl_percen_act : 0;
+ $dataTempReport[$w]['biaya_actual'] = $keyActualM->biaya_actual;
+ $dataTempReport[$w]['duration'] = $keyActualM->duration;
+ $dataTempReport[$w]['persentase_progress'] = $keyActualM->persentase_progress;
+ try {
+ $dataTempReport[$w]['percentage'] = $sumVolActual->ttl_percen_act ? ($sumVolActual->ttl_percen_act / 100) * $keyActualM->bobot_planning : 0;
+ $sumPercentageActual += $sumVolActual->ttl_percen_act ? ($sumVolActual->ttl_percen_act / 100) * $keyActualM->bobot_planning : 0;
+ $totalACWP += $keyActualM->biaya_actual / $keyActualM->duration;
+ } catch (\DivisionByZeroError $e) {
+ return response()->json(['message' => $e->getMessage()]);
+ }
+ $dataTempReport[$w]['totalacwp'] = $totalACWP;
+ $w++;
+ }
+
+ $arr_ActualM[] = array(
+ 'date' => $dt->format("Y-m-d"),
+ 'percentPlan' => $sumPercentagePlan,
+ 'percentActual' => $sumPercentageActual,
+ 'plan' => $dataTempPlan,
+ 'actual' => $dataTempReport,
+ );
+ if (isset($dataPayload['period']) && $dataPayload['period'] == 'week') {
+ $tempTtlPercentPlan += $sumPercentagePlan;
+ $tempTtlPercentActual += $sumPercentageActual;
+
+ if ($tempTtlPercentPlan >= 100 || $tempTtlPercentActual >= 100) {
+ if ($tempTtlPercentActual >= 100)
+ $tempTtlPercentActual = 100;
+ if ($tempTtlPercentPlan >= 100)
+ $tempTtlPercentPlan = 100;
+ }
+
+ $currentACWP += $totalACWP;
+ $currentBCWP += $totalBCWP;
+
+ $tempPercentage[] = array(round($tempTtlPercentPlan, 2), round($tempTtlPercentActual, 2));
+ $tempPercentagePlan[] = round($tempTtlPercentPlan, 2);
+ $tempPercentagePlanWhr[] = ["weekly period", $tempPercentagePlan];
+ $tempPercentageReal[] = round($tempTtlPercentActual, 2);
+ if ($tempTtlPercentPlan >= 100 && $tempTtlPercentActual >= 100) {
+ break;
+ }
+ } else {
+ $tempPercentage[] = array(round($sumPercentagePlan, 2), round($sumPercentageActual, 2));
+ $tempPercentagePlan[] = round($sumPercentagePlan, 2);
+ $tempPercentageReal[] = round($sumPercentageActual, 2);
+ }
+ $tempDate[] = array($dt->format("Y-m-d"));
+ }
+
+ try {
+ if (round($totalACWP, 0) > $totalRencanaBudget) {
+ $estimatedCost = round($totalACWP, 0) + 0;
+ } else {
+ $estimatedCost = ($totalRencanaBudget + 0);
+ }
+ } catch (\DivisionByZeroError $e) {
+ return response()->json([
+ 'message' => $e->getMessage(),
+ "line" => 566,
+ 'gantt' => $keyGantt,
+ ]);
+ }
+ $estimatedCost = $totalACWP > $totalRencanaBudget ? $totalACWP : $totalRencanaBudget;
+
+ $costDeviation = $totalRencanaBudget - $estimatedCost;
+ if ($costDeviation > 0) {
+ $potential = "SAVING";
+ } else {
+ $potential = $costDeviation == 0 ? "ON BUDGET" : "OVERRUN";
+ }
+
+ $dataResponse = array(
+ "date" => $tempDate,
+ "percentage" => $tempPercentage,
+ "percentagePlan" => $tempPercentagePlan,
+ "percentageReal" => $tempPercentageReal,
+ "data_details" => $arr_ActualM,
+ "budget_control" => array(
+ "current_budget" => $totalRencanaBudget,
+ "acwp" => round($totalACWP, 0),
+ "bcwp" => round($totalBCWP, 0),
+ "rem_to_complete" => ($totalRencanaBudget - round($totalACWP, 0)),
+ "add_cost_to_complete" => 0,
+ "estimated_at_completion" => $estimatedCost,
+ "cost_deviation" => $costDeviation,
+ "potential" => $potential,
+ )
+ );
+
+ $dataFinal[] = array(
+ "proyek_name" => $dataProject->nama,
+ "data" => $dataResponse,
+ "gantt" => $keyGantt,
+ );
+
+ return $dataFinal;
+ }
+
+}
diff --git a/app/Http/Controllers/ActivityController.php b/app/Http/Controllers/ActivityController.php
index 361826d..acd94b0 100644
--- a/app/Http/Controllers/ActivityController.php
+++ b/app/Http/Controllers/ActivityController.php
@@ -1,720 +1,966 @@
-where("version_gantt_id", $id)->count() == 0) {
- if(!$gantt->hierarchy_ftth_id) {
- $this->cloneTemplate($id, $proyek_id);
- } else {
- $this->cloneTemplate($id, $proyek_id, $gantt->hierarchy_ftth_id);
- }
- }
-
- $dataGantt = $this->getDataActivity($id);
-
- return response()->json(['status'=>'success','data'=> $dataGantt,'code'=>200], 200);
- }
-
- private function getDataActivity($id)
- {
- $checkHeader = Activity::where('version_gantt_id', $id)->where('type_activity', 'header')->count(); $finalData = [];
- if($checkHeader > 0){
- $dataHeader = Activity::where('version_gantt_id', $id)->where('type_activity', 'header')->first();
- $startDate = date_create($dataHeader->start_date);
- $endDate = date_create($dataHeader->end_date);
- $dataHeader->start_date = date_format($startDate,"Y-m-d H:i:s");
- $dataHeader->end_date = date_format($endDate,"Y-m-d H:i:s");
- $dataHeader->progress = $dataHeader->persentase_progress / 100;
- $dataHeader->planned_start = isset($dataHeader->planned_start) ? date_format(date_create($dataHeader->planned_start),"Y-m-d H:i:s") : NULL;
- $dataHeader->planned_end = isset($dataHeader->planned_end) ? date_format(date_create($dataHeader->planned_end),"Y-m-d H:i:s") : NULL;
- $dataHeader->type = "header";
- $dataHeader->text = $dataHeader->name;
- $finalData[] = $dataHeader;
- $data = Activity::where('version_gantt_id', $id)->where('parent_id', $dataHeader->id)->orderBy('sortorder', 'asc')->get();
- }else{
- $data = Activity::where('version_gantt_id', $id)->whereNull('parent_id')->orderBy('sortorder', 'asc')->get();
- }
-
- foreach($data as $objRow){
- $type = "project";
- $dataChildren = $this->getChildren($id, $objRow->id);
- $startDate = date_create($objRow->start_date);
- $endDate = date_create($objRow->end_date);
-
- if($objRow->type_activity=="milestone")
- $type = $objRow->type_activity;
- if(empty($dataChildren))
- $type = "task";
-
- $objRow->text = $objRow->name;
- $objRow->parent = $objRow->parent_id ? $objRow->parent_id : null;
- $objRow->start_date = date_format($startDate,"Y-m-d H:i:s");
- $objRow->end_date = date_format($endDate,"Y-m-d H:i:s");
- $objRow->planned_start = isset($objRow->planned_start) ? date_format(date_create($objRow->planned_start),"Y-m-d H:i:s") : NULL;
- $objRow->planned_end = isset($objRow->planned_end) ? date_format(date_create($objRow->planned_end),"Y-m-d H:i:s") : NULL;
- $objRow->progress = $objRow->persentase_progress / 100;
- $objRow->type = $type;
- $finalData[] = $objRow;
- $finalData = array_merge($finalData, $dataChildren);
- }
-
- $dataLink = Link::where('version_gantt_id', $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 $resultData;
- }
-
- private function getChildren($gantt_id, $parent_id)
- {
- $finalData = [];
- $data = Activity::where('version_gantt_id', $gantt_id)->where('parent_id', $parent_id)->orderBy('sortorder', 'asc')->get();
- foreach($data as $objRow){
- $objRow->parent = $parent_id;
- $objRow->text = $objRow->name;
- $objRow->progress = (int)$objRow->persentase_progress/100;
- $startDate = date_create($objRow->start_date);
- $endDate = date_create($objRow->end_date);
- $objRow->start_date = date_format($startDate,"Y-m-d H:i:s");
- $objRow->end_date = date_format($endDate,"Y-m-d H:i:s");
- $objRow->planned_start = isset($objRow->planned_start) ? date_format(date_create($objRow->planned_start),"Y-m-d H:i:s") : NULL;
- $objRow->planned_end = isset($objRow->planned_end) ? date_format(date_create($objRow->planned_end),"Y-m-d H:i:s") : NULL;
- $dataChildren = $this->getChildren($gantt_id, $objRow->id);
- if($objRow->type_activity=="milestone"){
- $objRow->type = $objRow->type_activity;
- }elseif(empty($dataChildren)){
- $objRow->type = "task";
- }else{
- $objRow->type = "project";
- }
- $finalData[] = $objRow;
- $finalData = array_merge($finalData, $dataChildren);
- }
- return $finalData;
- }
-
- private function cloneTemplate($id, $proyek_id, $hierarchy_ftth_id = null) {
- $project = Project::find($proyek_id);
- if($hierarchy_ftth_id){
- $gantt = VersionGantt::find($id);
- $rootActivity = Activity::create([
- 'version_gantt_id'=>$id,
- 'proyek_id'=>$proyek_id,
- 'name'=> $gantt->name_version,
- 'start_date'=> $project->mulai_proyek,
- 'end_date'=> $project->akhir_proyek,
- 'rencana_biaya'=> $project->rencana_biaya,
- 'type_activity'=> 'project',
- 'created_by'=>$this->currentName,
- 'sortorder'=>1
- ]);
- } else {
- $rootActivity = Activity::create([
- 'version_gantt_id'=>$id,
- 'proyek_id'=>$proyek_id,
- 'name'=> $project->nama,
- 'kode_sortname'=>$project->kode_sortname,
- 'start_date'=> $project->mulai_proyek,
- 'end_date'=> $project->akhir_proyek,
- 'rencana_biaya'=> $project->rencana_biaya,
- 'type_activity'=> 'project',
- 'created_by'=>$this->currentName,
- 'sortorder'=>1
- ]);
- }
-
- $resultTypeProject = TemplateGantt::where('proyek_type_id', $project->type_proyek_id)
- ->whereNull('parent_id')
- ->orderByRaw('id ASC')
- ->get();
-
- foreach($resultTypeProject as $objRow){
- $childActivities = TemplateGantt::where("parent_id", $objRow->id)->count();
- $max = Activity::where('version_gantt_id', $id)->max('sortorder');
- $resultNew = Activity::create([
- 'type_activity'=> $childActivities > 0 ? "project" : "task",
- 'version_gantt_id'=>$id,
- 'parent_id'=>$rootActivity->id,
- 'proyek_id'=>$proyek_id,
- 'name'=> $objRow->name_activity,
- 'start_date'=>date("Y-m-d H:i:s"),
- 'end_date'=>date("Y-m-d H:i:s"),
- 'created_by'=>$this->currentName,
- 'sortorder'=>$max+1
- ]);
- $this->getChildrenTemplate($id, $objRow->id, $project->type_project_id, $proyek_id, $resultNew->id, $project->mulai_proyek);
- }
- }
-
- private function getChildrenTemplate($id, $parent_id, $type_proyek_id, $proyek_id, $parent_new, $firstDay)
- {
- $data = TemplateGantt::where('parent_id', $parent_id)->orderByRaw('id ASC')->get();
- foreach($data as $objRow){
- $childActivities = TemplateGantt::where("parent_id", $objRow->id)->count();
- $max = Activity::where('version_gantt_id', $id)->max('sortorder');
- $resultNew = Activity::create([
- 'type_activity'=> $childActivities > 0 ? "project" : "task",
- 'version_gantt_id'=>$id,
- 'parent_id'=>$parent_new,
- 'proyek_id'=>$proyek_id,
- 'name'=> $objRow->name_activity,
- 'start_date'=>$firstDay,
- 'end_date'=>$firstDay,
- 'created_by'=>$this->currentName,
- 'sortorder'=>$max+1
- ]);
- $this->getChildrenTemplate($id, $objRow->id, $type_proyek_id, $proyek_id, $resultNew->id, $firstDay);
- }
- }
-
- public function add(Request $request)
- {
- $this->validate($request, [
- 'version_gantt_id'=>'required'
- ]);
-
- $data = $request->all();
- $data['name'] = $request->text;
- $data['persentase_progress'] = $request->progress;
- $data['created_by'] = $this->currentName;
- $max = Activity::where('version_gantt_id', $request->version_gantt_id)->max('sortorder');
- $data['sortorder'] = $max + 1;
- $data['type_activity'] = "task";
-
- $parent = $data['parent_id'] ?? null;
- if($parent){
- $parentData = Activity::find($parent);
- if($parentData->parent_id) {
- $parentData->update(["type_activity" => "project"]);
- }
- CommentActivity::where('activity_id', $parent)->delete();
- UserToActivity::where('activity_id', $parent)->delete();
- }
-
- if(!$result = Activity::create($data))
- return response()->json(['status'=>'failed','action'=>'error','code'=> 500], 500);
-
- return response()->json(['status'=>'success','action'=>'inserted', 'tid'=>$result->id,'code'=>200], 200);
- }
-
- public function edit($id){
- if(empty($id) || !is_int((int)$id))
- return response()->json(['status'=>'failed','message'=>'id is required!','code'=>400], 400);
-
- if(!$result = Activity::find($id))
- return response()->json(['status'=>'failed','message'=>'Data not found!','code'=> 404], 404);
-
- return response()->json(['status'=>'success','code'=>200,'data'=> $result], 200);
- }
-
- public function update(Request $request, $id)
- {
- if(empty($id) || !is_int((int)$id))
- return response()->json(['status'=>'failed', 'action'=>'error','message'=>'id is required!','code'=>400], 400);
-
- $updateBobot = true;
- if(!$data = Activity::find($id))
- return response()->json(['status'=>'failed', 'action'=>'error','message'=>'Data not found!','code'=> 404], 404);
- $dataUpdate = $request->all();
-
- $dataUpdate['name'] = $request->text;
- $dataUpdate['persentase_progress'] = $request->progress*100;
- $dataUpdate['updated_by'] = $this->currentName;
- unset($dataUpdate['sortorder']);
- if($data->type_activity!='header')
- $dataUpdate['type_activity'] = $request->type;
-
- if($request->has("target")){
- $this->updateOrder($id, $request->target);
- }
-
- if(!$data->update($dataUpdate))
- return response()->json(['status'=>'failed', 'action'=>'error','message'=>'data activity failed updated!','code'=>400], 400);
-
- return response()->json(['status'=>'success','update_bobot'=> $updateBobot, 'data'=>$dataUpdate, 'action'=>'updated','message'=>'Activity updated!','code'=>200], 200);
- }
-
- private function updateOrder($taskId, $target){
- $nextTask = false;
- $targetId = $target;
-
- if(strpos($target, "next:") === 0){
- $targetId = substr($target, strlen("next:"));
- $nextTask = true;
- }
-
- if($targetId == "null")
- return;
-
- $targetOrder = Activity::find($targetId)->sortorder;
- if($nextTask)
- $targetOrder++;
-
- Activity::where("sortorder", ">=", $targetOrder)->increment("sortorder");
-
- $updatedTask = Activity::find($taskId);
- $updatedTask->sortorder = $targetOrder;
- $updatedTask->save();
- }
-
- public function updateRegular(Request $request, $id){
- if(empty($id) || !is_int((int)$id))
- return response()->json(['status'=>'failed','message'=>'id is required!','code'=>400], 400);
-
- $data = Activity::find($id);
-
- if(!$data = Activity::find($id))
- return response()->json(['status'=>'failed','message'=>'Data not found!','code'=> 404], 404);
-
- if(!$data->update($request->all()))
- return response()->json(['status'=>'failed','message'=>'Failed to update!','code'=> 500], 500);
-
- return response()->json(['status'=>'success','message'=>'Activity Updated!','code'=> 200], 200);
- }
-
- public function delete($id)
- {
- if(!$data = Activity::find($id))
- return response()->json(['status'=>'failed', 'action'=>'error','message'=> 'Data not found!','code'=> 404], 404);
-
- if(!$data->delete())
- return response()->json(['status'=>'failed', 'action'=>'error','message'=>'data activity failed deleted!','code'=> 500], 500);
-
- return response()->json(['status'=>'success', "action"=>"deleted",'message'=>'data activity successfully deleted!','code'=>200], 200);
- }
-
- public function getUpdate($id)
- {
- if(!$data = Activity::find($id))
- return response()->json(['status'=>'failed', 'action'=>'error','message'=> 'Data not found!','code'=>400], 400);
-
- $data->progress = (int) $data->persentase_progress / 100;
- $data->rencana_biaya = str_replace(".", ",", $data->rencana_biaya);
- return response()->json(['status'=>'success', "data"=> $data,'code'=>200], 200);
- }
-
- public function search(Request $request)
- {
- $dataBuilder = $this->setUpPayload($request->all(), 'm_activity');
- $builder = $dataBuilder['builder'];
- $countBuilder = $dataBuilder['count'];
- $dataGet = $builder->get();
- $totalRecord = $countBuilder->count();
- return response()->json(['status'=>'success','code'=>200,'data'=>$dataGet, 'totalRecord'=>$totalRecord], 200);
- }
-
- // before upload file
- public function importOld(Request $request)
- {
- $data = $request->all();
-
- $data['created_by'] = $this->currentName;
-
- Activity::where('version_gantt_id', $data['ganttId'])->delete();
-
- $projectId = VersionGantt::where('id', $data['ganttId'])->first()->proyek_id;
-
- $activityStack = [];
-
- $hasWeight = false;
-
- foreach ($data['activities'] as $key => $value) {
- if(isset($value['weight']) && $value['weight'] != null && $value['weight'] != 0){
- $hasWeight = true;
- break;
- }
- }
-
- if(!$hasWeight){
- foreach ($data['activities'] as $key => $value) {
- if($key == 0){
- $data['activities'][$key]['weight'] = 100;
- } else {
- $parentWeight = 0;
- $siblingsCount = 1;
-
- $i = $key;
- while($i > 0){
- if ($data['activities'][$i - 1]['level'] == $data['activities'][$key]['level']-1){
- $parentWeight = $data['activities'][$i - 1]['weight'];
- break;
- }
- if ($data['activities'][$key]['level'] == $data['activities'][$i]['level']){
- $siblingsCount++;
- }
- $i--;
- }
-
- $i = $key+1;
- while($i < count($data['activities'])){
- if ($data['activities'][$i]['level'] == $data['activities'][$key]['level']-1){
- break;
- }
- // Log::info('level '.$data['activities'][$key]['level'].' i level '.$data['activities'][$i]['level']);
- if ($data['activities'][$key]['level'] == $data['activities'][$i]['level']){
- $siblingsCount++;
- }
- $i++;
- }
-
- $data['activities'][$key]['weight'] = $parentWeight / $siblingsCount;
- }
- };
- }
- foreach ($data['activities'] as $i => $activity_row) {
- $startDate = \DateTime::createFromFormat('d-m-y', $activity_row['start_date']);
- $endDate = \DateTime::createFromFormat('d-m-y H:i:sO', $activity_row['end_date']);
- $input['name'] = $activity_row['name'];
- $input['proyek_id'] = $projectId;
- $input['version_gantt_id'] = $data['ganttId'];
- $input['parent_id'] = null;
- $input['start_date'] = $startDate->format('Y-m-d');
- $input['end_date'] = $endDate->format('Y-m-d H:i:sO');
- $input['duration'] = $activity_row['duration'];
- $input['bobot_planning'] = $activity_row['weight'];
- $input['persentase_progress'] = 0;
- $input['type_activity'] = $i == 0 ? "header" : "task";
- $input['created_by'] = $this->currentName;
- $input['sortorder'] = $activity_row['no'];
-
- if (!$activity = Activity::create($input)) {
- Activity::where('version_gantt_id', $data['ganttId'])->delete();
- return response()->json(['status' => 'error', 'message' => 'Input failed on ' . $activity['name'], 'code' => 500], 500);
- }
-
- $data['activities'][$i]['activity_id'] = $activity->id;
-
- if ($i == 0) {
- $activity->type_activity = "project";
- $activity->save();
- $activity->level = $activity_row['level'];
- array_push($activityStack, $activity);
- continue;
- }
-
- $activity->level = $activity_row['level'];
-
- if ($lastStack = end($activityStack)) {
- $levelLowerThanLastStack = $activity->level < $lastStack->level;
- $levelEqualWithLastStack = $activity->level == $lastStack->level;
-
- if ($levelLowerThanLastStack) {
- $lastStackIsNotRight = $levelLowerThanLastStack;
- do {
- array_pop($activityStack);
- $lastStack = end($activityStack);
- if ($activity->level > $lastStack->level)
- $lastStackIsNotRight = false;
- } while ($lastStackIsNotRight);
- }
-
- if ($levelEqualWithLastStack) {
- array_pop($activityStack);
- }
- }
-
- $activity->parent_id = $activityStack[count($activityStack) - 1]->id ?? null;
- // there should be better way to except / filter attribute level before save because it's cause error
- // cant use except() / filter() on $activity collection somehow
- unset($activity->level);
- $activity->save();
- $activity->level = $activity_row['level'];
-
- if (@$activityStack[count($activityStack) - 1]->level != $activity->level && $activity->level != $data['activities'][$i - 1]['level']) {
- array_push($activityStack, $activity);
- }
-
- if ($activity->level < @$data['activities'][$i + 1]['level']) {
- unset($activity->level);
- $activity->type_activity = "project";
- $activity->save();
- $activity->level = $activity_row['level'];
- }
-
- if (!empty($activity_row['predecessor'])) {
- $key = array_search($activity_row['predecessor'], array_column($data['activities'], 'no'));
-
- if (!$predecessorActivity = Activity::find($data['activities'][$key]['activity_id']))
- continue;
-
- $predecessorFinishDate = new \DateTime($predecessorActivity->end_date);
- $interval = $predecessorFinishDate->diff(new \DateTime($activity->start_date));
- $diff = $interval->days;
-
- Link::create([
- 'created_by' => $this->currentName,
- 's_activity_id' => $predecessorActivity->id,
- 't_activity_id' => $activity->id,
- 'type_link' => 0,
- 'code_link' => 'FS',
- 'version_gantt_id' => $data['ganttId'],
- 'lag' => $diff > 1 ? $diff : null,
- ]);
- }
- }
-
- return response()->json(['stack' => $activityStack, 'status' => 'success', 'message' => 'Data imported!', 'projectId' => $projectId, 'code' => 200], 200);
- }
-
- private function getLatestGantt($id){
- $maxGanttId = VersionGantt::where("proyek_id", $id)->max("id");
- $data = array(
- "last_gantt_id" => $maxGanttId,
- "proyek_id" => $id
- );
- return $data;
- }
-
- public function getCalculateCurvaS(Request $request) // for adw (plan & actual == date)
- {
- $dataPayload = $request->all();
- $allGantt = [];
- if(isset($dataPayload['gannt_id'])){
- $allGantt = $dataPayload['gannt_id'];
- }else{
- foreach ($dataPayload['project_id'] as $val) {
- $allGantt[] = $this->getLatestGantt($val);
- }
- }
- $dataFinal=[];
- foreach ($allGantt as $keyGantt) {
- $dataProject = Project::find($keyGantt['proyek_id']);
- $dataHeader = Activity::where('type_activity', 'header')->where("proyek_id", $keyGantt['proyek_id'])->where("version_gantt_id", $keyGantt['last_gantt_id'])->first();
- if($dataHeader){
- $totalRencanaBudget = Activity::where('parent_id', $dataHeader->id)->where("proyek_id", $keyGantt['proyek_id'])->where("version_gantt_id", $keyGantt['last_gantt_id'])->sum("rencana_biaya");
- }else{
- $totalRencanaBudget = Activity::whereNull('parent_id')->where("proyek_id", $keyGantt['proyek_id'])->where("version_gantt_id", $keyGantt['last_gantt_id'])->sum("rencana_biaya");
- }
- $minDate = 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['last_gantt_id'])
- ->min("plan_date");
- $maxDate = DB::table('assign_material_to_activity as ama')
- ->where("ama.proyek_id", $keyGantt['proyek_id'])
- ->join('m_activity as a', 'a.id', '=', 'ama.activity_id')
- ->where('a.version_gantt_id', '=', $keyGantt['last_gantt_id'])
- ->max("plan_date");
- $begin = new \DateTime($minDate);
- $end = new \DateTime($maxDate);
- $end2 = new \DateTime($maxDate);
- $interval = \DateInterval::createFromDateString('1 day');
- $period = new \DatePeriod($begin, $interval, $end);
- $arr_ActualM = [];
- $tempDate = [];
- $tempPercentage = [];
- $tempTtlPercentPlan=0;
- $tempTtlPercentActual=0;
- $currentACWP = 0;
- $budgetControlACWP = 0;
- $currentProgressActivity = 0;
- $currentBCWP = 0;
- $budgetControlBCWP = 0;
- foreach ($period as $dt) {
- $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['last_gantt_id'])
- ->whereDate('ama.plan_date', $dt->format("Y-m-d"))
- ->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['last_gantt_id'])
- ->where('a.proyek_id', '=', $keyGantt['proyek_id'])
- ->whereDate('ram.report_date', $dt->format("Y-m-d"))
- ->get();
- $dataTempPlan = [];
- $x = 0;
- $sumPercentagePlan=0;
- $totalACWP = isset($totalACWP) ? $totalACWP : 0;
- $totalBCWP = isset($totalBCWP) ? $totalBCWP : 0;
- foreach ($dataPlanM as $keyPlanM) {
- $sumVolPlan = DB::table('assign_material_to_activity')
- ->select('activity_id', DB::raw('SUM(qty_planning) as ttl_qty_plan'))
- ->where('activity_id', '=', $keyPlanM->activity_id)
- ->groupBy('activity_id')
- ->first();
- $dataTempPlan [$x]['activity_id'] = $keyPlanM->activity_id;
- $dataTempPlan [$x]['qty_plan'] = $keyPlanM->qty_planning;
- $dataTempPlan [$x]['plan_date'] = $keyPlanM->plan_date;
- $dataTempPlan [$x]['start_activity'] = $keyPlanM->start_activity;
- $dataTempPlan [$x]['bobot_planning'] = $keyPlanM->bobot_planning;
- $dataTempPlan [$x]['ttl_plan'] = $sumVolPlan->ttl_qty_plan;
- $dataTempPlan [$x]['biaya_actual'] = $keyPlanM->biaya_actual;
- $dataTempPlan [$x]['duration'] = $keyPlanM->duration;
- $dataTempPlan [$x]['persentase_progress'] = $keyPlanM->persentase_progress;
- $dataTempPlan [$x]['percentage'] = ($keyPlanM->qty_planning/$sumVolPlan->ttl_qty_plan)*$keyPlanM->bobot_planning;
- $sumPercentagePlan+=($keyPlanM->qty_planning/$sumVolPlan->ttl_qty_plan)*$keyPlanM->bobot_planning;
- $totalBCWP += (((($keyPlanM->persentase_progress*$keyPlanM->bobot_planning)/100)/$keyPlanM->duration)* $totalRencanaBudget)/100;
- $dataTempPlan [$x]['totalBCWP'] = $totalBCWP;
- $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();
- $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;
- $dataTempReport [$w]['percentage'] = ($keyActualM->qty/$sumVolActual->ttl_qty_plan)*$keyActualM->bobot_planning;
- $sumPercentageActual+=($keyActualM->qty/$sumVolActual->ttl_qty_plan)*$keyActualM->bobot_planning;
- $totalACWP += $keyActualM->biaya_actual/$keyActualM->duration;
- $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'){
- if($dt->format("w")==1){
- if($totalACWP > 0 ){
- $budgetControlACWP = $currentACWP + $totalACWP;
- }
- if($totalBCWP > 0 ){
- $budgetControlBCWP = $currentBCWP + $totalBCWP;
- }
- $tempTtlPercentPlan+= $sumPercentagePlan;
- $tempTtlPercentActual+= $sumPercentageActual;
- $currentACWP += $totalACWP;
- $currentBCWP += $totalBCWP;
- $tempPercentage[] = array(round($tempTtlPercentPlan,2), round($tempTtlPercentActual,2));
- $tempDate[] = array($dt->format("Y-m-d"), 0, 0);
- }else if($dt->format("Y-m-d") == $end2->format("Y-m-d")) {
- $tempTtlPercentPlan+= $sumPercentagePlan;
- $tempTtlPercentActual+= $sumPercentageActual;
- $currentACWP += $totalACWP;
- $currentBCWP += $totalBCWP;
- $tempPercentage[] = array(round($tempTtlPercentPlan,2), round($tempTtlPercentActual,2));
- $tempDate[] = array($dt->format("Y-m-d"), 0, 0);
- $tempTtlPercentPlan = 0;
- $tempTtlPercentActual = 0;
- }
- }else{
- $tempPercentage[] = array(round($sumPercentagePlan,2), round($sumPercentageActual,2));
- $tempDate[] = array($dt->format("Y-m-d"), 0, 0);
- }
- }
- if(round($totalACWP,0) > $totalRencanaBudget){
- $estimatedCost = round($totalACWP,0)+0;
- }else{
- $estimatedCost = ($totalRencanaBudget+0);
- }
- $costDeviation = $totalRencanaBudget - $estimatedCost;
- if($costDeviation > 0){
- $potential = "SAVING";
- } else {
- $potential = $costDeviation == 0 ? "ON BUDGET" : "OVERRUN";
- }
- $dataResponse = array(
- "date" =>$tempDate,
- "percentage" =>$tempPercentage,
- "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,
- "allGant"=>$allGantt
- );
- }
- return response()->json(['status'=>'success','code'=>200, 'data' => $dataFinal], 200);
- }
-
- public function import(Request $request)
- {
- $data = $request->all();
- $data['created_by'] = $this->currentName;
- Activity::where('version_gantt_id', $data['gantt_id'])->delete();
- $projectId = VersionGantt::where('id', $data['gantt_id'])->first()->proyek_id;
- // get data excel
- $excel = TmpImport::latest('id')->first();
-
- return response()->json(['stack' => $excel, 'status' => 'success', 'message' => 'Data imported!', 'data' => $data, 'code' => 200], 200);
- }
-
- public function uploadTmpImport(Request $request)
- {
- if($request->hasFile('dokumen')){
- $document = $request->file('dokumen');
- $gantt_id = $request->gantt_id;
- $name = $document->getClientOriginalName();
-
- $result = $document->move($this->pathTmpImport, $name);
- if($result){
- $data = [
- 'gantt_id' => (int)$gantt_id,
- 'file' => $name,
- 'type_dokumen' => $request->type_dokumen
- ];
-
- $result = TmpImport::create($data);
-
- if(!$result){
- unlink($this->pathTmpImport.$name);
- return response()->json(['status'=>'failed','message'=>'Upload failed!','code'=> 500], 500);
- }
- return response()->json(['status'=>'success','message'=>'Upload successful!','code'=>200], 200);
-
- }
- return response()->json(['status'=>'failed','message'=>'Upload failed!','code'=> 500], 500);
- }
- return response()->json(['status'=>'failed','message'=>'File is required!','code'=>400], 400);
- }
-}
+where("version_gantt_id", $id)->count() == 0) {
+ if (!$gantt->hierarchy_ftth_id) {
+ $this->cloneTemplate($id, $proyek_id);
+ } else {
+ $this->cloneTemplate($id, $proyek_id, $gantt->hierarchy_ftth_id);
+ }
+ }
+
+ $dataGantt = $this->getDataActivity($id);
+
+ return response()->json(['status' => 'success', 'data' => $dataGantt, 'code' => 200], 200);
+ }
+
+ private function getDataActivity($id)
+ {
+ $checkHeader = Activity::where('version_gantt_id', $id)->where('type_activity', 'header')->count();
+ $finalData = [];
+ if ($checkHeader > 0) {
+ $dataHeader = Activity::where('version_gantt_id', $id)->where('type_activity', 'header')->first();
+ $startDate = date_create($dataHeader->start_date);
+ $endDate = date_create($dataHeader->end_date);
+ $dataHeader->start_date = date_format($startDate, "Y-m-d H:i:s");
+ $dataHeader->end_date = date_format($endDate, "Y-m-d H:i:s");
+ $dataHeader->progress = $dataHeader->persentase_progress / 100;
+ $dataHeader->planned_start = isset($dataHeader->planned_start) ? date_format(date_create($dataHeader->planned_start), "Y-m-d H:i:s") : NULL;
+ $dataHeader->planned_end = isset($dataHeader->planned_end) ? date_format(date_create($dataHeader->planned_end), "Y-m-d H:i:s") : NULL;
+
+ $actualStart = $this->getFirstLastDateActivity($dataHeader->id, "start");
+ $dataHeader->actual_start = date_format(date_create($actualStart), "Y-m-d");
+ $actualEnd = $this->getFirstLastDateActivity($dataHeader->id, "end");
+ $dataHeader->actual_end = isset($actualEnd) ? date_format(date_create($actualEnd), "Y-m-d") : NULL;
+
+ $dataHeader->type = "header";
+ $dataHeader->text = $dataHeader->name;
+ $finalData[] = $dataHeader;
+ $data = Activity::where('version_gantt_id', $id)->where('parent_id', $dataHeader->id)->orderBy('sortorder', 'asc')->get();
+ } else {
+ $data = Activity::where('version_gantt_id', $id)->whereNull('parent_id')->orderBy('sortorder', 'asc')->get();
+ }
+
+ foreach ($data as $objRow) {
+ $type = "project";
+ $dataChildren = $this->getChildren($id, $objRow->id);
+ $startDate = date_create($objRow->start_date);
+ $endDate = date_create($objRow->end_date);
+
+ if ($objRow->type_activity == "milestone")
+ $type = $objRow->type_activity;
+ if (empty($dataChildren))
+ $type = "task";
+
+ $objRow->text = $objRow->name;
+ $objRow->parent = $objRow->parent_id ? $objRow->parent_id : null;
+ $objRow->start_date = date_format($startDate, "Y-m-d H:i:s");
+ $objRow->end_date = date_format($endDate, "Y-m-d H:i:s");
+ $objRow->planned_start = isset($objRow->planned_start) ? date_format(date_create($objRow->planned_start), "Y-m-d H:i:s") : NULL;
+ $objRow->planned_end = isset($objRow->planned_end) ? date_format(date_create($objRow->planned_end), "Y-m-d H:i:s") : NULL;
+
+ $actualStart = $this->getFirstLastDateActivity($objRow->id, "start");
+ $objRow->actual_start = isset($actualStart) ? date_format(date_create($actualStart), "Y-m-d") : NULL;
+ $actualEnd = $this->getFirstLastDateActivity($objRow->id, "end");
+ $objRow->actual_end = isset($actualEnd) ? date_format(date_create($actualEnd), "Y-m-d") : NULL;
+
+ $objRow->progress = $objRow->persentase_progress / 100;
+ $objRow->type = $type;
+ $finalData[] = $objRow;
+ $finalData = array_merge($finalData, $dataChildren);
+ }
+
+ $dataLink = Link::where('version_gantt_id', $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 $resultData;
+ }
+
+ private function getChildren($gantt_id, $parent_id)
+ {
+ $finalData = [];
+ $data = Activity::where('version_gantt_id', $gantt_id)->where('parent_id', $parent_id)->orderBy('sortorder', 'asc')->get();
+ foreach ($data as $objRow) {
+ $objRow->parent = $parent_id;
+ $objRow->text = $objRow->name;
+ $objRow->progress = (float) $objRow->persentase_progress / 100;
+ $startDate = date_create($objRow->start_date);
+ $endDate = date_create($objRow->end_date);
+ $objRow->start_date = date_format($startDate, "Y-m-d H:i:s");
+ $objRow->end_date = date_format($endDate, "Y-m-d H:i:s");
+ $objRow->planned_start = isset($objRow->planned_start) ? date_format(date_create($objRow->planned_start), "Y-m-d H:i:s") : NULL;
+ $objRow->planned_end = isset($objRow->planned_end) ? date_format(date_create($objRow->planned_end), "Y-m-d H:i:s") : NULL;
+
+ $dataChildren = $this->getChildren($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), "Y-m-d") : NULL;
+ } elseif (empty($dataChildren)) {
+ $objRow->type = "task";
+ $objRow->actual_start = isset($objRow->actual_start) ? date_format(date_create($objRow->actual_start), "Y-m-d") : NULL;
+ $objRow->actual_end = isset($objRow->actual_end) ? date_format(date_create($objRow->actual_end), "Y-m-d") : 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), "Y-m-d") : NULL;
+
+ $actualEnd = $this->getFirstLastDateActivity($objRow->id, "end");
+ $objRow->actual_end = isset($actualEnd) ? date_format(date_create($actualEnd), "Y-m-d") : NULL;
+ }
+ $finalData[] = $objRow;
+ $finalData = array_merge($finalData, $dataChildren);
+ }
+ return $finalData;
+ }
+
+ public function getActivityFirst($parentId){
+ $activity = Activity::where('parent_id', $parentId)->orderByRaw('actual_start ASC')->first();
+ if (!isset($activity)) {
+ return null;
+ }
+ if($activity->type_activity == "task"){
+ // Log::info("activity ", [$activity]);
+ return $activity->actual_start;
+ }else{
+ return $this->getActivityFirst($activity->id);
+ }
+
+ }
+
+ public function getFirstLastDateActivity($id, $params){
+ if($params == "start"){
+ $data = Activity::select('id', 'parent_id', 'name', 'actual_start')->where('parent_id', $id)->get();
+ }else{
+ $data = Activity::select('id', 'parent_id', 'name', 'actual_end')->where('parent_id', $id)->get();
+ }
+ $parent = Activity::findOrFail($id);
+ $dataFinal=[];
+ foreach ($data as $val) {
+ $activity = $this->getchildActivityForActual($val->id, $params);
+ $dataFinal[] = $val;
+ $dataFinal = array_merge($dataFinal, $activity);
+
+ }
+ if($params == "start"){
+ $actualStartValues = array_column(array_filter($dataFinal, function($item) {
+ return isset($item['actual_start']);
+ }), 'actual_start');
+ $returnActualStartOrEnd = count($actualStartValues) == count($dataFinal) ? min($actualStartValues) : null;
+ if (isset($parent)) {
+ $parent->actual_start = $returnActualStartOrEnd;
+ $parent->save();
+ }
+ }else{
+ $actualEndValues = array_column(array_filter($dataFinal, function($item) {
+ return isset($item['actual_end']);
+ }), 'actual_end');
+ $returnActualStartOrEnd = count($actualEndValues) == count($dataFinal) ? max($actualEndValues) : null;
+ if (isset($parent)) {
+ $parent->actual_end = $returnActualStartOrEnd;
+ $parent->save();
+ }
+ }
+
+ // return json_encode(["min"=>$minActualStart, "max"=>$maxActualStart]);
+ return $returnActualStartOrEnd;
+ }
+
+ public function getchildActivityForActual($parent, $params){
+ if($params == "start"){
+ $activity = Activity::select('id', 'actual_start')->where('parent_id', $parent)->get();
+ }else{
+ $activity = Activity::select('id', 'actual_end')->where('parent_id', $parent)->get();
+ }
+ $temp = [];
+ foreach($activity as $val1){
+ $getChild = $this->getchildActivityForActual($val1->id, $params);
+ $temp[] = $val1;
+ $temp = array_merge($temp, $getChild);
+ }
+ return $temp;
+ }
+
+ public function getActivityLast($parentId){
+ $activity = Activity::where('parent_id', $parentId)->orderByRaw('actual_end DESC')->first();
+ if (!isset($activity)) {
+ return null;
+ }
+ if($activity->type_activity == "task"){
+ // Log::info("activity ", [$activity]);
+ return $activity->actual_end;
+ }else{
+ return $this->getActivityLast($activity->id);
+ }
+
+ }
+
+ private function cloneTemplate($id, $proyek_id, $hierarchy_ftth_id = null)
+ {
+ $project = Project::find($proyek_id);
+ if ($hierarchy_ftth_id) {
+ $gantt = VersionGantt::find($id);
+ $rootActivity = Activity::create([
+ 'version_gantt_id' => $id,
+ 'proyek_id' => $proyek_id,
+ 'name' => $gantt->name_version,
+ 'start_date' => $project->mulai_proyek,
+ 'end_date' => $project->akhir_proyek,
+ 'rencana_biaya' => $project->rencana_biaya,
+ 'type_activity' => 'project',
+ 'created_by' => $this->currentName,
+ 'sortorder' => 1
+ ]);
+ } else {
+ $rootActivity = Activity::create([
+ 'version_gantt_id' => $id,
+ 'proyek_id' => $proyek_id,
+ 'name' => $project->nama,
+ 'kode_sortname' => $project->kode_sortname,
+ 'start_date' => $project->mulai_proyek,
+ 'end_date' => $project->akhir_proyek,
+ 'rencana_biaya' => $project->rencana_biaya,
+ 'type_activity' => 'project',
+ 'created_by' => $this->currentName,
+ 'sortorder' => 1
+ ]);
+ }
+
+ $resultTypeProject = TemplateGantt::where('proyek_type_id', $project->type_proyek_id)
+ ->whereNull('parent_id')
+ ->orderByRaw('id ASC')
+ ->get();
+
+ foreach ($resultTypeProject as $objRow) {
+ $childActivities = TemplateGantt::where("parent_id", $objRow->id)->count();
+ $max = Activity::where('version_gantt_id', $id)->max('sortorder');
+ $resultNew = Activity::create([
+ 'type_activity' => $childActivities > 0 ? "project" : "task",
+ 'version_gantt_id' => $id,
+ 'parent_id' => $rootActivity->id,
+ 'proyek_id' => $proyek_id,
+ 'name' => $objRow->name_activity,
+ 'start_date' => date("Y-m-d H:i:s"),
+ 'end_date' => date("Y-m-d H:i:s"),
+ 'created_by' => $this->currentName,
+ 'sortorder' => $max + 1
+ ]);
+ $this->getChildrenTemplate($id, $objRow->id, $project->type_project_id, $proyek_id, $resultNew->id, $project->mulai_proyek);
+ }
+ }
+
+ private function getChildrenTemplate($id, $parent_id, $type_proyek_id, $proyek_id, $parent_new, $firstDay)
+ {
+ $data = TemplateGantt::where('parent_id', $parent_id)->orderByRaw('id ASC')->get();
+ foreach ($data as $objRow) {
+ $childActivities = TemplateGantt::where("parent_id", $objRow->id)->count();
+ $max = Activity::where('version_gantt_id', $id)->max('sortorder');
+ $resultNew = Activity::create([
+ 'type_activity' => $childActivities > 0 ? "project" : "task",
+ 'version_gantt_id' => $id,
+ 'parent_id' => $parent_new,
+ 'proyek_id' => $proyek_id,
+ 'name' => $objRow->name_activity,
+ 'start_date' => $firstDay,
+ 'end_date' => $firstDay,
+ 'created_by' => $this->currentName,
+ 'sortorder' => $max + 1
+ ]);
+ $this->getChildrenTemplate($id, $objRow->id, $type_proyek_id, $proyek_id, $resultNew->id, $firstDay);
+ }
+ }
+
+ public function add(Request $request)
+ {
+ $this->validate($request, [
+ 'version_gantt_id' => 'required'
+ ]);
+
+ $data = $request->all();
+ $data['name'] = $request->text;
+ $data['persentase_progress'] = $request->progress;
+ $data['created_by'] = $this->currentName;
+ $max = Activity::where('version_gantt_id', $request->version_gantt_id)->max('sortorder');
+ $data['sortorder'] = $max + 1;
+ if (!isset($data['type_activity'])) {
+ $data['type_activity'] = "task";
+ }
+
+ $parent = $data['parent_id'] ?? null;
+ if ($parent) {
+ $parentData = Activity::find($parent);
+ if ($parentData->parent_id) {
+ $parentData->update(["type_activity" => "project"]);
+ }
+ CommentActivity::where('activity_id', $parent)->delete();
+ UserToActivity::where('activity_id', $parent)->delete();
+ }
+
+ if (!$result = Activity::create($data))
+ return response()->json(['status' => 'failed', 'action' => 'error', 'code' => 500], 500);
+
+ return response()->json(['status' => 'success', 'action' => 'inserted', 'tid' => $result->id, 'code' => 200], 200);
+ }
+
+ public function edit($id)
+ {
+ if (empty($id) || !is_int((int) $id))
+ return response()->json(['status' => 'failed', 'message' => 'id is required!', 'code' => 400], 400);
+
+ if (!$result = Activity::find($id))
+ return response()->json(['status' => 'failed', 'message' => 'Data not found!', 'code' => 404], 404);
+
+ return response()->json(['status' => 'success', 'code' => 200, 'data' => $result], 200);
+ }
+
+ public function update(Request $request, $id)
+ {
+ if (empty($id) || !is_int((int) $id))
+ return response()->json(['status' => 'failed', 'action' => 'error', 'message' => 'id is required!', 'code' => 400], 400);
+
+ $updateBobot = true;
+ if (!$data = Activity::find($id))
+ return response()->json(['status' => 'failed', 'action' => 'error', 'message' => 'Data not found!', 'code' => 404], 404);
+ $dataUpdate = $request->all();
+
+ $dataUpdate['name'] = $request->text;
+ $dataUpdate['persentase_progress'] = $request->progress * 100;
+ $dataUpdate['updated_by'] = $this->currentName;
+ unset($dataUpdate['sortorder']);
+ if ($data->type_activity != 'header')
+ $dataUpdate['type_activity'] = $request->type;
+
+ if ($request->has("target")) {
+ $this->updateOrder($id, $request->target);
+ }
+
+ if (!$data->update($dataUpdate))
+ return response()->json(['status' => 'failed', 'action' => 'error', 'message' => 'data activity failed updated!', 'code' => 400], 400);
+
+ return response()->json(['status' => 'success', 'update_bobot' => $updateBobot, 'data' => $dataUpdate, 'action' => 'updated', 'message' => 'Activity updated!', 'code' => 200], 200);
+ }
+
+ private function updateOrder($taskId, $target)
+ {
+ $nextTask = false;
+ $targetId = $target;
+
+ if (strpos($target, "next:") === 0) {
+ $targetId = substr($target, strlen("next:"));
+ $nextTask = true;
+ }
+
+ if ($targetId == "null")
+ return;
+
+ $targetOrder = Activity::find($targetId)->sortorder;
+ if ($nextTask)
+ $targetOrder++;
+
+ Activity::where("sortorder", ">=", $targetOrder)->increment("sortorder");
+
+ $updatedTask = Activity::find($taskId);
+ $updatedTask->sortorder = $targetOrder;
+ $updatedTask->save();
+ }
+
+ public function updateRegular(Request $request, $id)
+ {
+ if (empty($id) || !is_int((int) $id))
+ return response()->json(['status' => 'failed', 'message' => 'id is required!', 'code' => 400], 400);
+
+ $data = Activity::find($id);
+
+ if (!$data = Activity::find($id))
+ return response()->json(['status' => 'failed', 'message' => 'Data not found!', 'code' => 404], 404);
+
+ if (!$data->update($request->all()))
+ return response()->json(['status' => 'failed', 'message' => 'Failed to update!', 'code' => 500], 500);
+
+ return response()->json(['status' => 'success', 'message' => 'Activity Updated!', 'code' => 200], 200);
+ }
+
+ public function updateSchedule($ganttId){
+ if (empty($ganttId) || !is_int((int) $ganttId))
+ return response()->json(['status' => 'failed', 'message' => 'id is required!', 'code' => 400], 400);
+
+ $activities = Activity::where('version_gantt_id', $ganttId)->get();
+ if (!$activities)
+ return response()->json(['status' => 'failed', 'message' => 'Activities not found!', 'code' => 404], 404);
+ $duration = 0;
+ foreach ($activities as $key => $activity) {
+ $assignMaterial = AssignMaterial::where('activity_id', $activity->id)->first();
+ if (isset($assignMaterial)) {
+ $statusActivity = $assignMaterial->status_activity;
+ } else {
+ $statusActivity = '';
+ }
+ if (isset($activity->planned_start) && isset($activity->planned_end) && $statusActivity != "done") {
+ // todo check report for no report / progress == 0
+ $today = new DateTime();
+ $endDate = new DateTime($activity->end_date);
+ $startDate = new DateTime($activity->start_date);
+ $plannedStart = new DateTime($activity->planned_start);
+ $plannedEnd = new DateTime($activity->planned_end);
+ $duration = MasterFunctionsHelper::countDays($ganttId, $plannedStart, $plannedEnd);
+ if ($today >= $endDate) {
+ $endDate = $today;
+ $bobotPlanning = (int) $activity->bobot_planning;
+ $rerataBobot = $duration > 0 ? $bobotPlanning / $duration : 0;
+ $bobotActual = (int) $activity->persentase_progress/100 * $bobotPlanning;
+ $sisaBobot = $bobotPlanning - $bobotActual;
+ $sisaHari = $rerataBobot > 0 ? $sisaBobot / $rerataBobot : 0;
+ $endDate->modify("+".ceil($sisaHari)." Days");
+ $actualDuration = MasterFunctionsHelper::countDays($ganttId, $startDate, $endDate);
+ $activity->duration = $actualDuration;
+ $activity->end_date = $endDate;
+ $activity->save();
+ }
+ }
+ }
+ return response()->json(['status' => 'success', 'message' => 'Activities Updated!', 'code' => 200], 200);
+ }
+
+ public function batchUpdate(Request $request, $ganttId)
+ {
+ $entities = $request->all();
+ if (empty($ganttId) || !is_int((int) $ganttId))
+ return response()->json(['status' => 'failed', 'message' => 'id is required!', 'code' => 400], 400);
+ $activity = Activity::where('version_gantt_id',$ganttId)->get();
+ $link = Link::where('version_gantt_id', $ganttId)->get();
+ if (!$activity)
+ return response()->json(['status' => 'failed', 'message' => 'Activity not found!', 'code' => 404], 404);
+ if (!$link)
+ return response()->json(['status' => 'failed', 'message' => 'Link not found!', 'code' => 404], 404);
+ foreach ($entities as $entity) {
+ if ($entity['entity'] == "task") {
+ $activityToUpdate = $activity->firstWhere('id', $entity['data']['id']);
+ $entity['data']['name'] = $entity['data']['text'];
+ $entity['data']['persentase_progress'] = $entity['data']['progress'] * 100;
+ if (isset($entity['data']['rencana_biaya'])) {
+ $entity['data']['rencana_biaya'] = str_replace(",", ".", $entity['data']['rencana_biaya']);
+ }
+ if (isset($entity['data']['target'])) {
+ $this->updateOrder($entity['data']['id'], $entity['data']['target']);
+ }
+ if (!$activityToUpdate->update($entity['data']))
+ return response()->json(['status' => 'failed', 'message' => 'Failed to update activity !', 'code' => 500], 500);
+ $updatedJobsDone = $activityToUpdate->jobs_done;
+ } else if ($entity['entity'] == "link") {
+ $linkToUpdate = $link->firstWhere('id', $entity['data']['id']);
+ if (!$linkToUpdate->update($entity['data']))
+ return response()->json(['status' => 'failed', 'message' => 'Failed to update link !', 'code' => 500], 500);
+ }
+ }
+ return response()->json(['status' => 'success', 'message' => 'Activity Updated!', 'code' => 200], 200);
+ }
+
+ public function delete($id)
+ {
+ if (!$data = Activity::find($id))
+ return response()->json(['status' => 'failed', 'action' => 'error', 'message' => 'Data not found!', 'code' => 404], 404);
+
+ if (!$data->delete())
+ return response()->json(['status' => 'failed', 'action' => 'error', 'message' => 'data activity failed deleted!', 'code' => 500], 500);
+
+ return response()->json(['status' => 'success', "action" => "deleted", 'message' => 'data activity successfully deleted!', 'code' => 200], 200);
+ }
+
+ public function getUpdate($id)
+ {
+ if (!$data = Activity::find($id))
+ return response()->json(['status' => 'failed', 'action' => 'error', 'message' => 'Data not found!', 'code' => 400], 400);
+
+ $data->progress = (float) $data->persentase_progress / 100;
+ $data->rencana_biaya = str_replace(".", ",", $data->rencana_biaya);
+ return response()->json(['status' => 'success', "data" => $data, 'code' => 200], 200);
+ }
+
+ public function search(Request $request)
+ {
+ $dataBuilder = $this->setUpPayload($request->all(), 'm_activity');
+ $builder = $dataBuilder['builder'];
+ $countBuilder = $dataBuilder['count'];
+ $dataGet = $builder->get();
+ $totalRecord = $countBuilder->count();
+ return response()->json(['status' => 'success', 'code' => 200, 'data' => $dataGet, 'totalRecord' => $totalRecord], 200);
+ }
+
+ // before upload file
+ public function importOld(Request $request)
+ {
+ $data = $request->all();
+
+ $data['created_by'] = $this->currentName;
+
+ Activity::where('version_gantt_id', $data['ganttId'])->delete();
+
+ $projectId = VersionGantt::where('id', $data['ganttId'])->first()->proyek_id;
+ $dayOffs = VersionGantt::where('id', $data['ganttId'])->first()->config_dayoff;
+
+ $activityStack = [];
+
+ $hasWeight = false;
+
+ foreach ($data['activities'] as $key => $value) {
+ if (isset($value['weight']) && $value['weight'] != null && $value['weight'] != 0) {
+ $hasWeight = true;
+ break;
+ }
+ }
+
+ if (!$hasWeight) {
+ foreach ($data['activities'] as $key => $value) {
+ if ($key == 0) {
+ $data['activities'][$key]['weight'] = 100;
+ } else {
+ $parentWeight = 0;
+ $siblingsCount = 1;
+
+ $i = $key;
+ while ($i > 0) {
+ if ($data['activities'][$i - 1]['level'] == $data['activities'][$key]['level'] - 1) {
+ $parentWeight = $data['activities'][$i - 1]['weight'];
+ break;
+ }
+ if ($data['activities'][$key]['level'] == $data['activities'][$i]['level']) {
+ $siblingsCount++;
+ }
+ $i--;
+ }
+
+ $i = $key + 1;
+ while ($i < count($data['activities'])) {
+ if ($data['activities'][$i]['level'] == $data['activities'][$key]['level'] - 1) {
+ break;
+ }
+ // Log::info('level '.$data['activities'][$key]['level'].' i level '.$data['activities'][$i]['level']);
+ if ($data['activities'][$key]['level'] == $data['activities'][$i]['level']) {
+ $siblingsCount++;
+ }
+ $i++;
+ }
+
+ $data['activities'][$key]['weight'] = $parentWeight / $siblingsCount;
+ }
+ }
+ ;
+ }
+ $projectStart = Project::select('mulai_proyek')->where('id', $projectId)->first();
+ foreach ($data['activities'] as $i => $activity_row) {
+ $startDate = new \DateTime($projectStart->mulai_proyek);
+ $endDate = clone $startDate;
+ $endDate->modify('-1 day');
+ $daysRemaining = $activity_row['duration'];
+
+ // Loop until the remaining days become zero
+ while ($daysRemaining > 0) {
+ $endDate->modify('+1 day');
+
+ // Check if the current day is a day off (Sunday or Saturday)
+ $currentDayOfWeek = (int) $endDate->format('w');
+ if (strpos($dayOffs, (string) $currentDayOfWeek) !== false) {
+ continue; // Skip the day off and continue to the next day
+ }
+
+ $daysRemaining--; // Decrease the remaining days by one
+ }
+ $endDate->setTime(23, 59, 59);
+ $input['name'] = $activity_row['name'];
+ $input['proyek_id'] = $projectId;
+ $input['version_gantt_id'] = $data['ganttId'];
+ $input['parent_id'] = null;
+ $input['start_date'] = $startDate->format('Y-m-d');
+ $input['end_date'] = $endDate->format('Y-m-d H:i:sO');
+ $input['duration'] = $activity_row['duration'];
+ $input['bobot_planning'] = $activity_row['weight'];
+ $input['persentase_progress'] = 0;
+ $input['type_activity'] = $i == 0 ? "header" : "task";
+ $input['created_by'] = $this->currentName;
+ $input['sortorder'] = $activity_row['no'];
+
+ if (!$activity = Activity::create($input)) {
+ Activity::where('version_gantt_id', $data['ganttId'])->delete();
+ return response()->json(['status' => 'error', 'message' => 'Input failed on ' . $activity['name'], 'code' => 500], 500);
+ }
+
+ $data['activities'][$i]['activity_id'] = $activity->id;
+
+ if ($i == 0) {
+ $activity->type_activity = "project";
+ $activity->save();
+ $activity->level = $activity_row['level'];
+ array_push($activityStack, $activity);
+ continue;
+ }
+
+ $activity->level = $activity_row['level'];
+
+ if ($lastStack = end($activityStack)) {
+ $levelLowerThanLastStack = $activity->level < $lastStack->level;
+ $levelEqualWithLastStack = $activity->level == $lastStack->level;
+
+ if ($levelLowerThanLastStack) {
+ $lastStackIsNotRight = $levelLowerThanLastStack;
+ do {
+ array_pop($activityStack);
+ $lastStack = end($activityStack);
+ if ($lastStack) {
+ if ($activity->level > $lastStack->level)
+ $lastStackIsNotRight = false;
+ } else {
+ $lastStackIsNotRight = false;
+ }
+ } while ($lastStackIsNotRight);
+ }
+
+ if ($levelEqualWithLastStack) {
+ array_pop($activityStack);
+ }
+ }
+
+ $activity->parent_id = $activityStack[count($activityStack) - 1]->id ?? null;
+ array_push($activityStack, $activity);
+ // there should be better way to except / filter attribute level before save because it's cause error
+ // cant use except() / filter() on $activity collection somehow
+ unset($activity->level);
+ $activity->save();
+ $activity->level = $activity_row['level'];
+
+ if (@$activityStack[count($activityStack) - 1]->level != $activity->level && $activity->level != $data['activities'][$i - 1]['level']) {
+ array_push($activityStack, $activity);
+ }
+
+ if ($activity->level < @$data['activities'][$i + 1]['level']) {
+ unset($activity->level);
+ $activity->type_activity = "project";
+ $activity->save();
+ $activity->level = $activity_row['level'];
+ }
+ if (isset($data['activities'][$i]['nik']) && $data['activities'][$i]['nik'] != '') {
+ $user = User::where("ktp_number", $data['activities'][$i]['nik'])->first();
+ $userProyek = UserToProyek::where("user_id", $user->id)
+ ->where("proyek_id", $projectId)
+ ->first();
+
+ $dataInsert = array(
+ "user_id" => $user->id,
+ "activity_id" => $activity->id,
+ "role_proyek_id" => $userProyek->project_role,
+ "proyek_id" => $projectId,
+ "created_by" => $this->currentName,
+ "version_gantt_id" => $data['ganttId']
+ );
+ UserToActivity::create($dataInsert);
+ }
+
+ if (!empty($activity_row['predecessor'])) {
+ $key = array_search($activity_row['predecessor'], array_column($data['activities'], 'no'));
+
+ if (!isset($data['activities'][$key]['activity_id']) || !$predecessorActivity = Activity::find($data['activities'][$key]['activity_id']))
+ continue;
+
+ $predecessorFinishDate = new \DateTime($predecessorActivity->end_date);
+ $interval = $predecessorFinishDate->diff(new \DateTime($activity->start_date));
+ $diff = $interval->days;
+
+ Link::create([
+ 'created_by' => $this->currentName,
+ 's_activity_id' => $predecessorActivity->id,
+ 't_activity_id' => $activity->id,
+ 'type_link' => 0,
+ 'code_link' => 'FS',
+ 'version_gantt_id' => $data['ganttId'],
+ 'lag' => null,
+ ]);
+ }
+ }
+
+ return response()->json(['stack' => $activityStack, 'status' => 'success', 'message' => 'Data imported!', 'projectId' => $projectId, 'code' => 200], 200);
+ }
+
+ private function getLatestGantt($id)
+ {
+ $maxGanttId = VersionGantt::where("proyek_id", $id)->max("id");
+ $data = array(
+ "last_gantt_id" => $maxGanttId,
+ "proyek_id" => $id
+ );
+ return $data;
+ }
+
+ public function getCalculateCurvaS(Request $request) // for adw (plan & actual == date)
+ {
+ $dataPayload = $request->all();
+ $allGantt = [];
+ if (isset($dataPayload['gannt_id'])) {
+ $allGantt = $dataPayload['gannt_id'];
+ } else {
+ foreach ($dataPayload['project_id'] as $val) {
+ $allGantt[] = $this->getLatestGantt($val);
+ }
+ }
+ $dataFinal = [];
+ foreach ($allGantt as $keyGantt) {
+ $dataProject = Project::find($keyGantt['proyek_id']);
+ $dataHeader = Activity::where('type_activity', 'header')->where("proyek_id", $keyGantt['proyek_id'])->where("version_gantt_id", $keyGantt['last_gantt_id'])->first();
+ if ($dataHeader) {
+ $totalRencanaBudget = Activity::where('parent_id', $dataHeader->id)->where("proyek_id", $keyGantt['proyek_id'])->where("version_gantt_id", $keyGantt['last_gantt_id'])->sum("rencana_biaya");
+ } else {
+ $totalRencanaBudget = Activity::whereNull('parent_id')->where("proyek_id", $keyGantt['proyek_id'])->where("version_gantt_id", $keyGantt['last_gantt_id'])->sum("rencana_biaya");
+ }
+ $minDate = 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['last_gantt_id'])
+ ->min("plan_date");
+ $maxDate = DB::table('assign_material_to_activity as ama')
+ ->where("ama.proyek_id", $keyGantt['proyek_id'])
+ ->join('m_activity as a', 'a.id', '=', 'ama.activity_id')
+ ->where('a.version_gantt_id', '=', $keyGantt['last_gantt_id'])
+ ->max("plan_date");
+ $begin = new \DateTime($minDate);
+ $end = new \DateTime($maxDate);
+ $end2 = new \DateTime($maxDate);
+ $interval = \DateInterval::createFromDateString('1 day');
+ $period = new \DatePeriod($begin, $interval, $end);
+ $arr_ActualM = [];
+ $tempDate = [];
+ $tempPercentage = [];
+ $tempTtlPercentPlan = 0;
+ $tempTtlPercentActual = 0;
+ $currentACWP = 0;
+ $budgetControlACWP = 0;
+ $currentProgressActivity = 0;
+ $currentBCWP = 0;
+ $budgetControlBCWP = 0;
+ foreach ($period as $dt) {
+ $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['last_gantt_id'])
+ ->whereDate('ama.plan_date', $dt->format("Y-m-d"))
+ ->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['last_gantt_id'])
+ ->where('a.proyek_id', '=', $keyGantt['proyek_id'])
+ ->whereDate('ram.report_date', $dt->format("Y-m-d"))
+ ->get();
+ $dataTempPlan = [];
+ $x = 0;
+ $sumPercentagePlan = 0;
+ $totalACWP = isset($totalACWP) ? $totalACWP : 0;
+ $totalBCWP = isset($totalBCWP) ? $totalBCWP : 0;
+ foreach ($dataPlanM as $keyPlanM) {
+ $sumVolPlan = DB::table('assign_material_to_activity')
+ ->select('activity_id', DB::raw('SUM(qty_planning) as ttl_qty_plan'))
+ ->where('activity_id', '=', $keyPlanM->activity_id)
+ ->groupBy('activity_id')
+ ->first();
+ $dataTempPlan[$x]['activity_id'] = $keyPlanM->activity_id;
+ $dataTempPlan[$x]['qty_plan'] = $keyPlanM->qty_planning;
+ $dataTempPlan[$x]['plan_date'] = $keyPlanM->plan_date;
+ $dataTempPlan[$x]['start_activity'] = $keyPlanM->start_activity;
+ $dataTempPlan[$x]['bobot_planning'] = $keyPlanM->bobot_planning;
+ $dataTempPlan[$x]['ttl_plan'] = $sumVolPlan->ttl_qty_plan;
+ $dataTempPlan[$x]['biaya_actual'] = $keyPlanM->biaya_actual;
+ $dataTempPlan[$x]['duration'] = $keyPlanM->duration;
+ $dataTempPlan[$x]['persentase_progress'] = $keyPlanM->persentase_progress;
+ $dataTempPlan[$x]['percentage'] = ($keyPlanM->qty_planning / $sumVolPlan->ttl_qty_plan) * $keyPlanM->bobot_planning;
+ $sumPercentagePlan += ($keyPlanM->qty_planning / $sumVolPlan->ttl_qty_plan) * $keyPlanM->bobot_planning;
+ $totalBCWP += (((($keyPlanM->persentase_progress * $keyPlanM->bobot_planning) / 100) / $keyPlanM->duration) * $totalRencanaBudget) / 100;
+ $dataTempPlan[$x]['totalBCWP'] = $totalBCWP;
+ $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();
+ $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;
+ $dataTempReport[$w]['percentage'] = ($keyActualM->qty / $sumVolActual->ttl_qty_plan) * $keyActualM->bobot_planning;
+ $sumPercentageActual += ($keyActualM->qty / $sumVolActual->ttl_qty_plan) * $keyActualM->bobot_planning;
+ $totalACWP += $keyActualM->biaya_actual / $keyActualM->duration;
+ $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') {
+ if ($dt->format("w") == 1) {
+ if ($totalACWP > 0) {
+ $budgetControlACWP = $currentACWP + $totalACWP;
+ }
+ if ($totalBCWP > 0) {
+ $budgetControlBCWP = $currentBCWP + $totalBCWP;
+ }
+ $tempTtlPercentPlan += $sumPercentagePlan;
+ $tempTtlPercentActual += $sumPercentageActual;
+ $currentACWP += $totalACWP;
+ $currentBCWP += $totalBCWP;
+ $tempPercentage[] = array(round($tempTtlPercentPlan, 2), round($tempTtlPercentActual, 2));
+ $tempDate[] = array($dt->format("Y-m-d"), 0, 0);
+ } else if ($dt->format("Y-m-d") == $end2->format("Y-m-d")) {
+ $tempTtlPercentPlan += $sumPercentagePlan;
+ $tempTtlPercentActual += $sumPercentageActual;
+ $currentACWP += $totalACWP;
+ $currentBCWP += $totalBCWP;
+ $tempPercentage[] = array(round($tempTtlPercentPlan, 2), round($tempTtlPercentActual, 2));
+ $tempDate[] = array($dt->format("Y-m-d"), 0, 0);
+ $tempTtlPercentPlan = 0;
+ $tempTtlPercentActual = 0;
+ }
+ } else {
+ $tempPercentage[] = array(round($sumPercentagePlan, 2), round($sumPercentageActual, 2));
+ $tempDate[] = array($dt->format("Y-m-d"), 0, 0);
+ }
+ }
+ if (round($totalACWP, 0) > $totalRencanaBudget) {
+ $estimatedCost = round($totalACWP, 0) + 0;
+ } else {
+ $estimatedCost = ($totalRencanaBudget + 0);
+ }
+ $costDeviation = $totalRencanaBudget - $estimatedCost;
+ if ($costDeviation > 0) {
+ $potential = "SAVING";
+ } else {
+ $potential = $costDeviation == 0 ? "ON BUDGET" : "OVERRUN";
+ }
+ $dataResponse = array(
+ "date" => $tempDate,
+ "percentage" => $tempPercentage,
+ "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,
+ "allGant" => $allGantt
+ );
+ }
+ return response()->json(['status' => 'success', 'code' => 200, 'data' => $dataFinal], 200);
+ }
+
+ public function import(Request $request)
+ {
+ $data = $request->all();
+ $data['created_by'] = $this->currentName;
+ Activity::where('version_gantt_id', $data['gantt_id'])->delete();
+ $projectId = VersionGantt::where('id', $data['gantt_id'])->first()->proyek_id;
+ // get data excel
+ $excel = TmpImport::latest('id')->first();
+
+ return response()->json(['stack' => $excel, 'status' => 'success', 'message' => 'Data imported!', 'data' => $data, 'code' => 200], 200);
+ }
+
+ public function uploadTmpImport(Request $request)
+ {
+ if ($request->hasFile('dokumen')) {
+ $document = $request->file('dokumen');
+ $gantt_id = $request->gantt_id;
+ $name = $document->getClientOriginalName();
+
+ $result = $document->move($this->pathTmpImport, $name);
+ if ($result) {
+ $data = [
+ 'gantt_id' => (int) $gantt_id,
+ 'file' => $name,
+ 'type_dokumen' => $request->type_dokumen
+ ];
+
+ $result = TmpImport::create($data);
+
+ if (!$result) {
+ unlink($this->pathTmpImport . $name);
+ return response()->json(['status' => 'failed', 'message' => 'Upload failed!', 'code' => 500], 500);
+ }
+ return response()->json(['status' => 'success', 'message' => 'Upload successful!', 'code' => 200], 200);
+
+ }
+ return response()->json(['status' => 'failed', 'message' => 'Upload failed!', 'code' => 500], 500);
+ }
+ return response()->json(['status' => 'failed', 'message' => 'File is required!', 'code' => 400], 400);
+ }
+
+ public function importUpdate(Request $request)
+ {
+ $data = $request->all();
+ foreach ($data as $value) {
+ $activity = Activity::find($value['id']);
+ $activity->duration = $value['duration'];
+ $activity->start_date = $value['start_date'];
+ $activity->end_date = $value['end_date'];
+ $activity->save();
+ }
+ return response()->json(['status' => 'success', 'data' => $request, 'message' => 'Update successful!', 'code' => 200], 200);
+ }
+}
diff --git a/app/Http/Controllers/AssignMaterialController.php b/app/Http/Controllers/AssignMaterialController.php
index 5a89147..3d78384 100644
--- a/app/Http/Controllers/AssignMaterialController.php
+++ b/app/Http/Controllers/AssignMaterialController.php
@@ -1,215 +1,221 @@
-validate($request, [
- 'activity_id' => 'required',
- 'material_id' => 'required',
- 'qty_planning' => 'required'
- ]);
-
- $activity = Activity::where('id', $request->activity_id)->first();
-
- $checkStock = RequestMaterial::where("id", $request->material_id)->first();
- $currentStock = $checkStock->qty;
- if((int)$currentStock < (int)$request->qty_planning){
- return response()->json(['status'=>'failed','message'=>'Stock is not enough!','code'=> 500]);
- }
-
- $start_date = $activity->start_date;
- $start_date = substr($start_date, 0, 19); // remove the timezone offset
- $startDate = new \DateTime(date("Y-m-d", strtotime($start_date)));
- $planDate = new \DateTime(date("Y-m-d", strtotime($request->plan_date)));
-
- $data = $request->all();
- $data['created_by'] = $this->currentName;
- $data['budget'] = $checkStock->price;
- $data['qty_planning'] = $this->sanitizeDecimal($data['qty_planning']);
-
- if ($planDate > $startDate) {
- $result = AssignMaterial::create($data);
- return response()->json(['status'=>'success','message'=>'Data added!', 'code'=>200], 200);
- }else{
- return response()->json(['status'=>'failed','message'=>'Failed to add data!','code'=> 400], 400);
- }
- }
-
- public function update(Request $request, $id){
- if(empty($id) || !is_int((int)$id))
- return response()->json(['status'=>'failed','message'=>'id is required!','code'=>400], 400);
-
- $data = AssignMaterial::find($id);
- if(!$data)
- return response()->json(['status'=>'failed','message'=>'Data not found!','code'=> 404], 404);
-
- $result = $data->update($request->all());
-
- if($result)
- return response()->json(['status'=>'success','message'=> 'Data updated!','code'=> 200], 200);
-
- return response()->json(['status'=>'failed','message'=>'Failed to update!','code'=> 500], 500);
- }
-
- public function delete($id)
- {
- $data = AssignMaterial::where('id', $id)->first();
-
- if($data->delete())
- return response()->json(['status'=>'success','message'=>'Data deleted!','code'=> 200], 200);
-
- return response()->json(['status'=>'failed','message'=>'Failed to delete!','code'=> 500], 500);
- }
-
- public function edit($id){
- if(empty($id) || !is_int((int)$id))
- return response()->json(['status'=>'failed','message'=>'id is required!','code'=>400], 400);
-
- $result = AssignMaterial::find($id);
-
- if($result)
- return response()->json(['status'=>'success','code'=>200,'data'=>$result], 200);
-
- return response()->json(['status'=>'failed','message'=>'Data not found!','code'=> 404], 404);
- }
-
- public function search(Request $request)
- {
- $payload = $request->all();
- $dataBuilder = $this->setUpPayload($payload, 'assign_material_to_activity');
- $builder = $dataBuilder['builder'];
- $countBuilder = $dataBuilder['count'];
- $dataGet = $builder->get();
- $totalRecord = $countBuilder->count();
- return response()->json(['status'=>'success','code'=>200,'data'=>$dataGet, 'totalRecord'=>$totalRecord], 200);
- }
-
- public function list()
- {
- $data = AssignMaterial::all();
- $countData = $data->count();
-
- if($data)
- return response()->json(['status'=>'success','code'=>200,'data'=>$data, 'totalRecord'=>$countData], 200);
-
- return response()->json(['status'=>'failed','message'=>'Failed to get the data!','code'=> 500], 500);
- }
-
- public function datatables(Request $request){
- $id_activity = $request->query('idact');
- $type = $request->query('type') ?? "material";
- $data = AssignMaterial::select(
- "assign_material_to_activity.*","m.description as material_name", "m.uom as uom"
- )
- ->join("m_req_material as m", "m.id", "=", "assign_material_to_activity.material_id")
- ->where('assign_material_to_activity.activity_id', $id_activity)
- ->where('assign_material_to_activity.type', $type)
- ->orderBy('plan_date', 'desc')
- ->get();
- return Datatables::of($data)
- ->addIndexColumn()
- ->addColumn('action', function($row){
- $actionBtn = '';
- return $actionBtn;
- })
- ->rawColumns(['action'])->make(true);
- }
-
- public function datatablesForReportActivity(Request $request){
- $id_activity = $request->query('idact');
- $data =
- AssignMaterial::select(
- AssignMaterial::raw('SUM(qty_planning) as qty_planning'),
- "m.description as material_name",
- "assign_material_to_activity.activity_id",
- "assign_material_to_activity.type"
- // "assign_material_to_activity.material_id",
- )
- ->join("m_req_material as m", "m.id", "=", "assign_material_to_activity.material_id")
- ->groupBy("m.description")
- ->groupBy("assign_material_to_activity.activity_id")
- ->groupBy("assign_material_to_activity.type")
- ->where("assign_material_to_activity.activity_id", $id_activity)->get();
- return Datatables::of($data)
- ->addIndexColumn()
- ->addColumn('qty_sum', function($row){
- $val_qty_act = AssignMaterial::select(ReportActivityMaterial::raw('SUM(ram.qty) as qty_sum'),"m.description as material_name1")
- ->join("m_req_material as m", "m.id", "=", "assign_material_to_activity.material_id")
- ->join("report_activity_material as ram", "ram.assign_material_id", "=", "assign_material_to_activity.id")
- ->groupBy("m.description")
- ->where("m.description", strval($row->material_name))
- ->where("ram.activity_id", $row->activity_id)->first();
- return $val_qty_act ? $val_qty_act->qty_sum : '-';
- })
- ->addColumn('status_activity', function($row){
- $val_status = AssignMaterial::select("status_activity")
- ->join('m_req_material as m', 'm.id', '=', 'assign_material_to_activity.material_id')
- ->where('m.description', '=', $row->material_name)
- ->where("assign_material_to_activity.activity_id", $row->activity_id)->first();
- return $val_status ? $val_status->status_activity : null;
- })
- ->addColumn('start_activity', function($row){
- $val_start = AssignMaterial::select("start_activity")
- ->join('m_req_material as m', 'm.id', '=', 'assign_material_to_activity.material_id')
- ->where('m.description', '=', $row->material_name)
- ->where("assign_material_to_activity.activity_id", $row->activity_id)->first();
- return $val_start ? $val_start->start_activity : null;
- })
- ->addColumn('finish_activity', function($row){
- $val_finish = AssignMaterial::select("finish_activity")
- ->join('m_req_material as m', 'm.id', '=', 'assign_material_to_activity.material_id')
- ->where('m.description', '=', $row->material_name)
- ->where("assign_material_to_activity.activity_id", $row->activity_id)->first();
- return $val_finish ? $val_finish->finish_activity : null;
- })
- ->addColumn('uom', function($row){
- $val_uom = RequestMaterial::select("uom")
- ->where('description', '=', $row->material_name)->first();
- return $val_uom ? $val_uom->uom : null;
- })
- ->addColumn('assign_material_id', function($row){
- $assignMaterial =AssignMaterial::select('assign_material_to_activity.id')->join("m_req_material as m", "m.id", "=", "assign_material_to_activity.material_id")
- ->where('activity_id', $row->activity_id)->where('m.description', $row->material_name)->first();
- return $assignMaterial ? $assignMaterial->id : null;
- })
- ->addColumn('action', function($row){
- $dataPlan = AssignMaterial::select('assign_material_to_activity.id')->join("m_req_material as m", "m.id", "=", "assign_material_to_activity.material_id")
- ->where('activity_id', $row->activity_id)->where('m.description', $row->material_name)->first();
- $actionBtn = '';
- $actionBtn .= '';
- return $actionBtn;
- })
- ->rawColumns(['action'])->make(true);
- }
-
- public function ForReportActivityByMaterial(Request $request){
- $id_activity = $request->idact;
- $data = AssignMaterial::select("assign_material_to_activity.*","m.description as material_name", "m.uom as uom")
- ->join("m_req_material as m", "m.id", "=", "assign_material_to_activity.material_id")
- ->where('assign_material_to_activity.activity_id', $id_activity)->get();
- foreach ($data as $key) {
- $val_qty_sum = ReportActivityMaterial::where('assign_material_id', '=', $key->id)->sum("qty");
- }
- $countData = $data->count();
- if($data){
- return response()->json(['status'=>'success','code'=>200,'data'=>$data, 'totalRecord'=>$countData], 200);
- }else{
- return response()->json(['status'=>'failed','message'=>'failed get Assign material, please try again later!','code'=>400], 400);
- }
- }
-}
+validate($request, [
+ 'activity_id' => 'required',
+ 'material_id' => 'required',
+ 'qty_planning' => 'required'
+ ]);
+
+ $activity = Activity::where('id', $request->activity_id)->first();
+
+ $checkStock = RequestMaterial::where("id", $request->material_id)->first();
+ $currentStock = $checkStock->qty;
+ if((int)$currentStock < (int)$request->qty_planning){
+ return response()->json(['status'=>'failed','message'=>'Stock is not enough!','code'=> 500]);
+ }
+
+ $start_date = $activity->start_date;
+ $start_date = substr($start_date, 0, 19); // remove the timezone offset
+ $startDate = new \DateTime(date("Y-m-d", strtotime($start_date)));
+ $planDate = new \DateTime(date("Y-m-d", strtotime($request->plan_date)));
+
+ $data = $request->all();
+ $data['created_by'] = $this->currentName;
+ $data['budget'] = $checkStock->price;
+ $data['qty_planning'] = $this->sanitizeDecimal($data['qty_planning']);
+
+ if ($planDate >= $startDate) {
+ $result = AssignMaterial::create($data);
+ return response()->json(['status'=>'success','message'=>'Data added!', 'code'=>200], 200);
+ }else{
+ return response()->json(['status'=>'failed','message'=>'Failed to add data!','code'=> 400], 400);
+ }
+ }
+
+ public function update(Request $request, $id){
+ if(empty($id) || !is_int((int)$id))
+ return response()->json(['status'=>'failed','message'=>'id is required!','code'=>400], 400);
+
+ $data = AssignMaterial::find($id);
+ if(!$data)
+ return response()->json(['status'=>'failed','message'=>'Data not found!','code'=> 404], 404);
+
+ $result = $data->update($request->all());
+
+ if($result)
+ return response()->json(['status'=>'success','message'=> 'Data updated!','code'=> 200], 200);
+
+ return response()->json(['status'=>'failed','message'=>'Failed to update!','code'=> 500], 500);
+ }
+
+ public function delete($id)
+ {
+ $data = AssignMaterial::where('id', $id)->first();
+ $reports = ReportActivityMaterial::where('assign_material_id', $data->id)->get();
+ if (isset($reports)) {
+ foreach ($reports as $report) {
+ $report->delete();
+ }
+ }
+
+ if($data->delete())
+ return response()->json(['status'=>'success','message'=>'Data deleted!','code'=> 200], 200);
+
+ return response()->json(['status'=>'failed','message'=>'Failed to delete!','code'=> 500], 500);
+ }
+
+ public function edit($id){
+ if(empty($id) || !is_int((int)$id))
+ return response()->json(['status'=>'failed','message'=>'id is required!','code'=>400], 400);
+
+ $result = AssignMaterial::find($id);
+
+ if($result)
+ return response()->json(['status'=>'success','code'=>200,'data'=>$result], 200);
+
+ return response()->json(['status'=>'failed','message'=>'Data not found!','code'=> 404], 404);
+ }
+
+ public function search(Request $request)
+ {
+ $payload = $request->all();
+ $dataBuilder = $this->setUpPayload($payload, 'assign_material_to_activity');
+ $builder = $dataBuilder['builder'];
+ $countBuilder = $dataBuilder['count'];
+ $dataGet = $builder->get();
+ $totalRecord = $countBuilder->count();
+ return response()->json(['status'=>'success','code'=>200,'data'=>$dataGet, 'totalRecord'=>$totalRecord], 200);
+ }
+
+ public function list()
+ {
+ $data = AssignMaterial::all();
+ $countData = $data->count();
+
+ if($data)
+ return response()->json(['status'=>'success','code'=>200,'data'=>$data, 'totalRecord'=>$countData], 200);
+
+ return response()->json(['status'=>'failed','message'=>'Failed to get the data!','code'=> 500], 500);
+ }
+
+ public function datatables(Request $request){
+ $id_activity = $request->query('idact');
+ $type = $request->query('type') ?? "material";
+ $data = AssignMaterial::select(
+ "assign_material_to_activity.*","m.description as material_name", "m.uom as uom"
+ )
+ ->join("m_req_material as m", "m.id", "=", "assign_material_to_activity.material_id")
+ ->where('assign_material_to_activity.activity_id', $id_activity)
+ ->where('assign_material_to_activity.type', $type)
+ ->orderBy('plan_date', 'desc')
+ ->get();
+ return Datatables::of($data)
+ ->addIndexColumn()
+ ->addColumn('action', function($row){
+ $actionBtn = '';
+ return $actionBtn;
+ })
+ ->rawColumns(['action'])->make(true);
+ }
+
+ public function datatablesForReportActivity(Request $request){
+ $id_activity = $request->query('idact');
+ $data =
+ AssignMaterial::select(
+ AssignMaterial::raw('SUM(qty_planning) as qty_planning'),
+ "m.description as material_name",
+ "assign_material_to_activity.activity_id",
+ "assign_material_to_activity.type"
+ // "assign_material_to_activity.material_id",
+ )
+ ->join("m_req_material as m", "m.id", "=", "assign_material_to_activity.material_id")
+ ->groupBy("m.description")
+ ->groupBy("assign_material_to_activity.activity_id")
+ ->groupBy("assign_material_to_activity.type")
+ ->where("assign_material_to_activity.activity_id", $id_activity)->get();
+ return Datatables::of($data)
+ ->addIndexColumn()
+ ->addColumn('qty_sum', function($row){
+ $val_qty_act = AssignMaterial::select(ReportActivityMaterial::raw('SUM(ram.qty) as qty_sum'),"m.description as material_name1")
+ ->join("m_req_material as m", "m.id", "=", "assign_material_to_activity.material_id")
+ ->join("report_activity_material as ram", "ram.assign_material_id", "=", "assign_material_to_activity.id")
+ ->groupBy("m.description")
+ ->where("m.description", strval($row->material_name))
+ ->where("ram.activity_id", $row->activity_id)->first();
+ return $val_qty_act ? $val_qty_act->qty_sum : '-';
+ })
+ ->addColumn('status_activity', function($row){
+ $val_status = AssignMaterial::select("status_activity")
+ ->join('m_req_material as m', 'm.id', '=', 'assign_material_to_activity.material_id')
+ ->where('m.description', '=', $row->material_name)
+ ->where("assign_material_to_activity.activity_id", $row->activity_id)->first();
+ return $val_status ? $val_status->status_activity : null;
+ })
+ ->addColumn('start_activity', function($row){
+ $val_start = AssignMaterial::select("start_activity")
+ ->join('m_req_material as m', 'm.id', '=', 'assign_material_to_activity.material_id')
+ ->where('m.description', '=', $row->material_name)
+ ->where("assign_material_to_activity.activity_id", $row->activity_id)->first();
+ return $val_start ? $val_start->start_activity : null;
+ })
+ ->addColumn('finish_activity', function($row){
+ $val_finish = AssignMaterial::select("finish_activity")
+ ->join('m_req_material as m', 'm.id', '=', 'assign_material_to_activity.material_id')
+ ->where('m.description', '=', $row->material_name)
+ ->where("assign_material_to_activity.activity_id", $row->activity_id)->first();
+ return $val_finish ? $val_finish->finish_activity : null;
+ })
+ ->addColumn('uom', function($row){
+ $val_uom = RequestMaterial::select("uom")
+ ->where('description', '=', $row->material_name)->first();
+ return $val_uom ? $val_uom->uom : null;
+ })
+ ->addColumn('assign_material_id', function($row){
+ $assignMaterial =AssignMaterial::select('assign_material_to_activity.id')->join("m_req_material as m", "m.id", "=", "assign_material_to_activity.material_id")
+ ->where('activity_id', $row->activity_id)->where('m.description', $row->material_name)->first();
+ return $assignMaterial ? $assignMaterial->id : null;
+ })
+ ->addColumn('action', function($row){
+ $dataPlan = AssignMaterial::select('assign_material_to_activity.id')->join("m_req_material as m", "m.id", "=", "assign_material_to_activity.material_id")
+ ->where('activity_id', $row->activity_id)->where('m.description', $row->material_name)->first();
+ $actionBtn = '';
+ $actionBtn .= '';
+ return $actionBtn;
+ })
+ ->rawColumns(['action'])->make(true);
+ }
+
+ public function ForReportActivityByMaterial(Request $request){
+ $id_activity = $request->idact;
+ $data = AssignMaterial::select("assign_material_to_activity.*","m.description as material_name", "m.uom as uom")
+ ->join("m_req_material as m", "m.id", "=", "assign_material_to_activity.material_id")
+ ->where('assign_material_to_activity.activity_id', $id_activity)->get();
+ foreach ($data as $key) {
+ $val_qty_sum = ReportActivityMaterial::where('assign_material_id', '=', $key->id)->sum("qty");
+ }
+ $countData = $data->count();
+ if($data){
+ return response()->json(['status'=>'success','code'=>200,'data'=>$data, 'totalRecord'=>$countData], 200);
+ }else{
+ return response()->json(['status'=>'failed','message'=>'failed get Assign material, please try again later!','code'=>400], 400);
+ }
+ }
+}
diff --git a/app/Http/Controllers/BroadcastController.php b/app/Http/Controllers/BroadcastController.php
index 7e0a8ca..66ca433 100644
--- a/app/Http/Controllers/BroadcastController.php
+++ b/app/Http/Controllers/BroadcastController.php
@@ -1,9 +1,177 @@
-all();
+ $data['created_by'] = $this->currentName;
+ if (isset($data['send_to_id'])) {
+ $idArray = $data['send_to_id'];
+ if (is_array($data['send_to_id'])) {
+ $data['send_to_id'] = implode(", ", $idArray);
+ }
+ }
+ $result = Broadcast::create($data);
+ if($result){
+ $data['status_send'] !== "registered" ? $this->sendNotification($data) : '';
+ return response()->json(['status'=>'success','message'=>'add broadcast successfully!','code'=>200], 200);
+ }else{
+ return response()->json(['status'=>'failed','message'=>'add broadcast failed!','code'=>400], 400);
+ }
+ }
+
+ public function edit($id){
+ if(!$id || (int) $id < 0 || $id==""){
+ return response()->json(['status'=>'failed','message'=>'id is required!','code'=>400], 400);
+ die();
+ }
+
+ $result = Broadcast::find($id);
+
+ if($result){
+ return response()->json(['status'=>'success','code'=>200,'data'=>$result], 200);
+ }else{
+ return response()->json(['status'=>'failed','message'=>'failed get data broadcast, please try again later!','code'=>400], 400);
+ }
+ }
+
+ public function update(Request $request, $id)
+ {
+ if(!$id || (int) $id < 0 || $id==""){
+ return response()->json(['status'=>'failed','message'=>'id is required!','code'=>400], 400);
+ }
+
+ $data = Broadcast::find($id);
+
+ $status_send = $request->status_send;
+
+ if($status_send === 'resend' || $status_send === 'send' && !empty($data))
+ {
+ $data['status_send'] = $status_send;
+ $this->sendNotification($data);
+ }
+
+ if($data){
+ $result = $data->update($request->all());
+ }else{
+ return response()->json(['status'=>'failed','message'=>'data broadcast not found!','code'=>400], 400);
+ die();
+ }
+
+
+ if($result){
+ return response()->json(['status'=>'success','message'=>'data broadcast successfully updated!','code'=>200], 200);
+ }else{
+ return response()->json(['status'=>'failed','message'=>'data broadcast failed updated!','code'=>400], 400);
+ }
+ }
+
+ public function delete($id)
+ {
+ $data = Broadcast::find($id);
+
+ if($data){
+ $delete = $data->delete();
+ }else{
+ return response()->json(['status'=>'failed','message'=>'data broadcast not found!','code'=>400], 400);
+ die();
+ }
+
+
+ if($delete){
+ return response()->json(['status'=>'success','message'=>'data broadcast successfully deleted!','code'=>200], 200);
+ }else{
+ return response()->json(['status'=>'failed','message'=>'data broadcast failed deleted!','code'=>400], 400);
+ }
+ }
+
+ public function search(Request $request)
+ {
+ $payload = $request->all();
+ $dataBuilder = $this->setUpPayload($payload, 'm_broadcast');
+ $builder = $dataBuilder['builder'];
+ $countBuilder = $dataBuilder['count'];
+ $dataGet = $builder->get();
+ $totalRecord = $countBuilder->count();
+ return response()->json(['status'=>'success','code'=>200,'data'=>$dataGet, 'totalRecord'=>$totalRecord], 200);
+ }
+
+ public function list()
+ {
+ $data = Broadcast::all();
+ $countData = $data->count();
+
+ if($data){
+ return response()->json(['status'=>'success','code'=>200,'data'=>$data, 'totalRecord'=>$countData], 200);
+ }else{
+ return response()->json(['status'=>'failed','message'=>'failed get list broadcast, please try again later!','code'=>400], 400);
+ }
+ }
+
+ public function sendNotification($data)
+ {
+ // send_to_type (all, roles, user)
+ if (isset($data['send_to_type'])) {
+ switch ($data['send_to_type']) {
+ case 'all':
+ $users = User::whereNotNull('fcm_token')->get();
+ if (isset($users)) {
+ foreach ($users as $user) {
+ FCMService::send(
+ $user->fcm_token,
+ [
+ 'title' => $data['title_notif'],
+ 'body' => $data['message_notif'],
+ ]
+ );
+ }
+ }
+ break;
+
+ case 'roles':
+ $users = User::where("role_id", $data['send_to_id'])->whereNotNull('fcm_token')->get();
+ if (isset($users)) {
+ foreach ($users as $user) {
+ FCMService::send(
+ $user->fcm_token,
+ [
+ 'title' => $data['title_notif'],
+ 'body' => $data['message_notif'],
+ ]
+ );
+ }
+ }
+ break;
+
+ case 'users':
+ $idArray = explode(", ", $data['send_to_id']);
+ foreach ($idArray as $key => $value) {
+ $user = User::where("id", $value)->whereNotNull('fcm_token')->first();
+ if (isset($user)) {
+ FCMService::send(
+ $user->fcm_token,
+ [
+ 'title' => $data['title_notif'],
+ 'body' => $data['message_notif'],
+ ]
+ );
+ }
+ }
+ break;
+
+ default:
+ # code...
+ break;
+ }
+ }
+ }
+}
diff --git a/app/Http/Controllers/Controller.php b/app/Http/Controllers/Controller.php
index c431f28..507129d 100644
--- a/app/Http/Controllers/Controller.php
+++ b/app/Http/Controllers/Controller.php
@@ -1,306 +1,313 @@
-currentDate = date("Y-m-d H:i:s");
- $this->currentName = auth()->user() ? auth()->user()->name : "system";
- $this->currentId = auth()->user() ? auth()->user()->id : 0;
-
- $this->pathImage = config('assets.image');
- $this->pathDocument = config('assets.project');
- $this->pathActivityDocument = config('assets.activity');
- }
-
- protected function setUpPayload($condition, $tableSelf)
- {
- $alias = "selfTable";
- $builder = DB::table($tableSelf." AS ".$alias);
- $builder = $builder->select($alias.".*");
- if($condition){
- if(isset($condition['joins'])){
- $selectColumn = [];
- $no = 0;
- foreach($condition['joins'] as $join){
- $tableJoin = isset($join['name1']) ? $join['name1'] : $alias;
- $tableName = $join['name'];
- $columnJoin = $join['column_join']; // foreign key table sini
- $columnSelf = isset($join['column_self']) ? $join['column_self'] : "id"; // primary key table lawan
- $columnResult = $join['column_results'];
-
- foreach($columnResult as $sColumn){
- $builder = $builder->addSelect($tableName.".".$sColumn." as join_".$this->listJoinAll[$no]."_".$sColumn);
- }
- $builder = $builder->leftJoin($tableName, $tableJoin.".".$columnJoin, '=', $tableName.'.'.$columnSelf);
- $no++;
- }
- }
-
- if(isset($condition['columns'])){
- $listWhere = $condition['columns'];
-
- $builder = $builder->where(function ($query) use($listWhere, $alias){
- foreach($listWhere as $where){
- $value = $where['value'];
- if($value && $value!="" && $value!=" "){
- $column = $where['name'];
- $operator = strtolower($where['logic_operator']); // like, =, <>, range
- $value2 = isset($where['value1']) ? $where['value1'] : "";
- $tableColumn = isset($where['table_name']) ? $where['table_name'] : $alias;
- $query = $this->whereCondition($query, $operator, $tableColumn, $column, $value, $value2);
- }
- }
- });
- }
-
- if(isset($condition['group_column'])){
- $builder = $this->groupWhere($builder, $condition['group_column'], $alias);
- }
-
- $data['count'] = clone $builder;
-
- if(isset($condition['paging'])){
- $builder = $builder->offset($condition['paging']['start'])->limit($condition['paging']['length']);
- }
-
- if(isset($condition['orders'])){
- $orders = $condition['orders'];
- $sortBy = $orders['ascending'] ? "ASC" : "DESC";
- $columnOrder = $orders['columns'];
- foreach($columnOrder as $column){
- $builder = $builder->orderBy($alias.".".$column, $sortBy);
- }
- }
- }
- $data['builder'] = $builder;
- return $data;
- }
-
- private function groupWhere($oldBuilder, $groupWhere, $alias)
- {
- $builder = $oldBuilder;
- $listGroupWhere = $groupWhere;
- $operator = $listGroupWhere['operator'];
- $operatorGroup = $listGroupWhere['group_operator'];
- $listWhere = $listGroupWhere['where'];
- if(strtolower($operator)=="and"){
- $builder = $builder->where(function($query) use($operatorGroup, $listWhere, $alias){
- $no = 1;
- foreach ($listWhere as $where) {
- $value = $where['value'];
- $column = $where['name'];
- $operator = strtolower($where['logic_operator']);
- $value2 = isset($where['value1']) ? $where['value1'] : "";
- $tableColumn = isset($where['table_name']) ? $where['table_name'] : $alias;
- if($value && $value!="" && $value!=" "){
- if($operatorGroup=="and"){
- $query = $this->whereCondition($query, $operator, $tableColumn, $column, $value, $value2);
- }else{
- if($no==1){
- $query = $this->whereCondition($query, $operator, $tableColumn, $column, $value, $value2);
- }else{
- $query = $this->orWhereCondition($query, $operator, $tableColumn, $column, $value, $value2);
- }
- }
- }
- $no = $no+1;
- }
- });
- }else if(strtolower($operator)=="or"){
- $builder = $builder->orWhere(function($query) use($operatorGroup, $listWhere, $alias){
- $no = 1;
- foreach ($listWhere as $where) {
- $value = $where['value'];
- $column = $where['name'];
- $operator = strtolower($where['logic_operator']);
- $value2 = isset($where['value1']) ? $where['value1'] : "";
- $tableColumn = isset($where['table_name']) ? $where['table_name'] : $alias;
- if($value && $value!="" && $value!=" "){
- if($operatorGroup=="and"){
- $query = $this->whereCondition($query, $operator, $tableColumn, $column, $value, $value2);
- }else{
- if($no==1){
- $query = $this->whereCondition($query, $operator, $tableColumn, $column, $value, $value2);
- }else{
- $query = $this->orWhereCondition($query, $operator, $tableColumn, $column, $value, $value2);
- }
- }
- }
- $no++;
- }
- });
- }
- return $builder;
- }
-
- private function whereCondition($oldQuery, $operator, $tableColumn, $column, $value, $value2)
- {
- $query = $oldQuery;
- if($operator=="range"){
- $query = $query->whereBetween($tableColumn.".".$column, [$value, $value2]);
- }else if($operator=="like"){
- $query = $query->where($tableColumn.".".$column, 'like', '%'.$value.'%');
- }else if($operator=="ilike"){
- $query = $query->where($tableColumn.".".$column, '~*', $value);
- }else if($operator=="="){
- $query = $query->where($tableColumn.".".$column, $value);
- }else if($operator=="in"){
- $query = $query->whereIn($tableColumn.".".$column, $value);
- }else if($operator=="notin"){
- $query = $query->whereNotIn($tableColumn.".".$column, $value);
- }else{
- $query = $query->where($tableColumn.".".$column, $operator, $value);
- }
- return $query;
- }
-
- private function whereConditionSingleTable($oldQuery, $operator, $column, $value, $value2){
- $query = $oldQuery;
- if($operator=="range"){
- $query = $query->whereBetween($column, [$value, $value2]);
- }else if($operator=="like"){
- $query = $query->where($column, 'like', '%'.$value.'%');
- }else if($operator=="ilike"){
- $query = $query->where($column, '~*', $value);
- }else if($operator=="="){
- $query = $query->where($column, $value);
- }else if($operator=="in"){
- $query = $query->whereIn($column, $value);
- }else if($operator=="notin"){
- $query = $query->whereNotIn($column, $value);
- }else{
- $query = $query->where($column, $operator, $value);
- }
- return $query;
- }
-
- private function orWhereCondition($oldQuery, $operator, $tableColumn, $column, $value, $value2)
- {
- $query = $oldQuery;
- if($operator=="range"){
- $query = $query->orWhereBetween($tableColumn.".".$column, [$value, $value2]);
- }else if($operator=="like"){
- $query = $query->orWhere($tableColumn.".".$column, 'like', '%'.$value.'%');
- }else if($operator=="ilike"){
- $query = $query->where($tableColumn.".".$column, '~*', $value);
- }else if($operator=="="){
- $query = $query->orWhere($tableColumn.".".$column, $value);
- }else if($operator=="in"){
- $query = $query->orWhereIn($tableColumn.".".$column, $value);
- }else if($operator=="notin"){
- $query = $query->orWhereNotIn($tableColumn.".".$column, $value);
- }else{
- $query = $query->orWhere($tableColumn.".".$column, $operator, $value);
- }
- return $query;
- }
-
- protected function calculateAllCost($activity_id, $proyek_id){
- $humanCostPlanning = $this->calculateAllHumanCost($activity_id, $proyek_id);
- $materialCostPlanning = $this->calculateMaterialCost($activity_id, $proyek_id);
- $toolsCostPlanning = 0;
-
- $allCost = $humanCostPlanning + $materialCostPlanning + $toolsCostPlanning;
- return $allCost;
- }
-
- private function calculateAllHumanCost($activity_id, $proyek_id)
- {
- $dataHuman = UserToActivity::select("ahp.standart_rate as standart_rate","ahp.max_used as max_used", "ahp.cost_per_used as cost_per_used", "ahp.uom_standart_rate as uom_standart_rate")
- ->leftJoin("assign_hr_to_proyek as ahp", "assign_hr_to_activity.user_id", "=", "ahp.user_id")
- ->where("assign_hr_to_activity.activity_id", $activity_id)->where("assign_hr_to_activity.proyek_id", $proyek_id)
- ->where("ahp.proyek_id", $proyek_id)
- ->get();
-
- $totalCost = 0;
- foreach ($dataHuman as $human) {
- $totalCost += $this->calculateHumanCost($human, $activity_id);
- }
-
- return $totalCost;
- }
-
- private function calculateHumanCost($human, $activity_id)
- {
- $activity = Activity::find($activity_id);
- $duration = $activity->duration;
- $standarRate = $human->standart_rate;
- $maxUsed = $human->max_used/100;
- if ($human->uom_standart_rate == "Hour") {
- $totalCost = ($standarRate*8*$duration)*$maxUsed;
- return $totalCost;
- }
- $totalCost = ($standarRate*$duration)*$maxUsed;
- return $totalCost;
- }
-
- private function calculateMaterialCost($activity_id, $proyek_id)
- {
- $totalCost = AssignMaterial::selectRaw("COALESCE(qty_planning,0)*COALESCE(budget,0) as totalCost")
- ->where("proyek_id", $proyek_id)
- ->where("activity_id", $activity_id)
- ->sum(AssignMaterial::raw("COALESCE(qty_planning, 0) * COALESCE(budget, 0)"));
- return $totalCost;
- }
-
- protected function getLoc($lat, $lng){
- // $response = Http::get(config('api.nominatim') . "/reverse?lat=".$lat."&lon=".$lng."&format=json");
- // return $response->json;
-
- $url = config('api.nominatim') . "/reverse?lat=".$lat."&lon=".$lng."&format=json";
- // $token = config('api.adw_token');
- $response = $this->curlRequest($url);
- return $response;
- }
-
- private function curlRequest($url){
- $ch = curl_init();
- // $headers = [
- // 'Authorization: '.$token
- // ];
- curl_setopt($ch, CURLOPT_URL, $url);
- // curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
-
- $response = curl_exec($ch);
- if ($response === false)
- $response = curl_error($ch);
- curl_close($ch);
-
- return json_decode($response);
- }
-
- protected function addDetailK3($dataDetail, $report_id){
- foreach ($dataDetail as $value) {
- $dataNew = array(
- "report_k3_id"=>$report_id,
- "checklist_k3_id"=>$value['checklist_id'],
- "name_checklist_k3"=>$value['checklist_name'],
- "created_by"=>$this->currentName
- );
-
- ReportK3Detail::create($dataNew);
- }
- }
-}
+currentDate = date("Y-m-d H:i:s");
+ $this->currentName = auth()->user() ? auth()->user()->name : "system";
+ $this->currentId = auth()->user() ? auth()->user()->id : 0;
+
+ $this->pathImage = config('assets.image');
+ $this->pathDocument = config('assets.project');
+ $this->pathActivityDocument = config('assets.activity');
+ }
+
+ protected function setUpPayload($condition, $tableSelf)
+ {
+ $alias = "selfTable";
+ $builder = DB::table($tableSelf." AS ".$alias);
+ // $builder = $builder->select($alias.".*");
+ if($condition){
+ if(isset($condition['select'])){
+ foreach($condition['select'] as $select){
+ $builder = $builder->addSelect($alias.".".$select);
+ }
+ }else{
+ $builder = $builder->addSelect($alias.".*");
+ }
+ if(isset($condition['joins'])){
+ $selectColumn = [];
+ $no = 0;
+ foreach($condition['joins'] as $join){
+ $tableJoin = isset($join['name1']) ? $join['name1'] : $alias;
+ $tableName = $join['name'];
+ $columnJoin = $join['column_join']; // foreign key table sini
+ $columnSelf = isset($join['column_self']) ? $join['column_self'] : "id"; // primary key table lawan
+ $columnResult = $join['column_results'];
+
+ foreach($columnResult as $sColumn){
+ $builder = $builder->addSelect($tableName.".".$sColumn." as join_".$this->listJoinAll[$no]."_".$sColumn);
+ }
+ $builder = $builder->leftJoin($tableName, $tableJoin.".".$columnJoin, '=', $tableName.'.'.$columnSelf);
+ $no++;
+ }
+ }
+
+ if(isset($condition['columns'])){
+ $listWhere = $condition['columns'];
+
+ $builder = $builder->where(function ($query) use($listWhere, $alias){
+ foreach($listWhere as $where){
+ $value = $where['value'];
+ if($value && $value!="" && $value!=" "){
+ $column = $where['name'];
+ $operator = strtolower($where['logic_operator']); // like, =, <>, range
+ $value2 = isset($where['value1']) ? $where['value1'] : "";
+ $tableColumn = isset($where['table_name']) ? $where['table_name'] : $alias;
+ $query = $this->whereCondition($query, $operator, $tableColumn, $column, $value, $value2);
+ }
+ }
+ });
+ }
+
+ if(isset($condition['group_column'])){
+ $builder = $this->groupWhere($builder, $condition['group_column'], $alias);
+ }
+
+ $data['count'] = clone $builder;
+
+ if(isset($condition['paging'])){
+ $builder = $builder->offset($condition['paging']['start'])->limit($condition['paging']['length']);
+ }
+
+ if(isset($condition['orders'])){
+ $orders = $condition['orders'];
+ $sortBy = $orders['ascending'] ? "ASC" : "DESC";
+ $columnOrder = $orders['columns'];
+ foreach($columnOrder as $column){
+ $builder = $builder->orderBy($alias.".".$column, $sortBy);
+ }
+ }
+ }
+ $data['builder'] = $builder;
+ return $data;
+ }
+
+ private function groupWhere($oldBuilder, $groupWhere, $alias)
+ {
+ $builder = $oldBuilder;
+ $listGroupWhere = $groupWhere;
+ $operator = $listGroupWhere['operator'];
+ $operatorGroup = $listGroupWhere['group_operator'];
+ $listWhere = $listGroupWhere['where'];
+ if(strtolower($operator)=="and"){
+ $builder = $builder->where(function($query) use($operatorGroup, $listWhere, $alias){
+ $no = 1;
+ foreach ($listWhere as $where) {
+ $value = $where['value'];
+ $column = $where['name'];
+ $operator = strtolower($where['logic_operator']);
+ $value2 = isset($where['value1']) ? $where['value1'] : "";
+ $tableColumn = isset($where['table_name']) ? $where['table_name'] : $alias;
+ if($value && $value!="" && $value!=" "){
+ if($operatorGroup=="and"){
+ $query = $this->whereCondition($query, $operator, $tableColumn, $column, $value, $value2);
+ }else{
+ if($no==1){
+ $query = $this->whereCondition($query, $operator, $tableColumn, $column, $value, $value2);
+ }else{
+ $query = $this->orWhereCondition($query, $operator, $tableColumn, $column, $value, $value2);
+ }
+ }
+ }
+ $no = $no+1;
+ }
+ });
+ }else if(strtolower($operator)=="or"){
+ $builder = $builder->orWhere(function($query) use($operatorGroup, $listWhere, $alias){
+ $no = 1;
+ foreach ($listWhere as $where) {
+ $value = $where['value'];
+ $column = $where['name'];
+ $operator = strtolower($where['logic_operator']);
+ $value2 = isset($where['value1']) ? $where['value1'] : "";
+ $tableColumn = isset($where['table_name']) ? $where['table_name'] : $alias;
+ if($value && $value!="" && $value!=" "){
+ if($operatorGroup=="and"){
+ $query = $this->whereCondition($query, $operator, $tableColumn, $column, $value, $value2);
+ }else{
+ if($no==1){
+ $query = $this->whereCondition($query, $operator, $tableColumn, $column, $value, $value2);
+ }else{
+ $query = $this->orWhereCondition($query, $operator, $tableColumn, $column, $value, $value2);
+ }
+ }
+ }
+ $no++;
+ }
+ });
+ }
+ return $builder;
+ }
+
+ private function whereCondition($oldQuery, $operator, $tableColumn, $column, $value, $value2)
+ {
+ $query = $oldQuery;
+ if($operator=="range"){
+ $query = $query->whereBetween($tableColumn.".".$column, [$value, $value2]);
+ }else if($operator=="like"){
+ $query = $query->where($tableColumn.".".$column, 'like', '%'.$value.'%');
+ }else if($operator=="ilike"){
+ $query = $query->where($tableColumn.".".$column, '~*', $value);
+ }else if($operator=="="){
+ $query = $query->where($tableColumn.".".$column, $value);
+ }else if($operator=="in"){
+ $query = $query->whereIn($tableColumn.".".$column, $value);
+ }else if($operator=="notin"){
+ $query = $query->whereNotIn($tableColumn.".".$column, $value);
+ }else{
+ $query = $query->where($tableColumn.".".$column, $operator, $value);
+ }
+ return $query;
+ }
+
+ private function whereConditionSingleTable($oldQuery, $operator, $column, $value, $value2){
+ $query = $oldQuery;
+ if($operator=="range"){
+ $query = $query->whereBetween($column, [$value, $value2]);
+ }else if($operator=="like"){
+ $query = $query->where($column, 'like', '%'.$value.'%');
+ }else if($operator=="ilike"){
+ $query = $query->where($column, '~*', $value);
+ }else if($operator=="="){
+ $query = $query->where($column, $value);
+ }else if($operator=="in"){
+ $query = $query->whereIn($column, $value);
+ }else if($operator=="notin"){
+ $query = $query->whereNotIn($column, $value);
+ }else{
+ $query = $query->where($column, $operator, $value);
+ }
+ return $query;
+ }
+
+ private function orWhereCondition($oldQuery, $operator, $tableColumn, $column, $value, $value2)
+ {
+ $query = $oldQuery;
+ if($operator=="range"){
+ $query = $query->orWhereBetween($tableColumn.".".$column, [$value, $value2]);
+ }else if($operator=="like"){
+ $query = $query->orWhere($tableColumn.".".$column, 'like', '%'.$value.'%');
+ }else if($operator=="ilike"){
+ $query = $query->where($tableColumn.".".$column, '~*', $value);
+ }else if($operator=="="){
+ $query = $query->orWhere($tableColumn.".".$column, $value);
+ }else if($operator=="in"){
+ $query = $query->orWhereIn($tableColumn.".".$column, $value);
+ }else if($operator=="notin"){
+ $query = $query->orWhereNotIn($tableColumn.".".$column, $value);
+ }else{
+ $query = $query->orWhere($tableColumn.".".$column, $operator, $value);
+ }
+ return $query;
+ }
+
+ protected function calculateAllCost($activity_id, $proyek_id){
+ $humanCostPlanning = $this->calculateAllHumanCost($activity_id, $proyek_id);
+ $materialCostPlanning = $this->calculateMaterialCost($activity_id, $proyek_id);
+ $toolsCostPlanning = 0;
+
+ $allCost = $humanCostPlanning + $materialCostPlanning + $toolsCostPlanning;
+ return $allCost;
+ }
+
+ private function calculateAllHumanCost($activity_id, $proyek_id)
+ {
+ $dataHuman = UserToActivity::select("ahp.standart_rate as standart_rate","ahp.max_used as max_used", "ahp.cost_per_used as cost_per_used", "ahp.uom_standart_rate as uom_standart_rate")
+ ->leftJoin("assign_hr_to_proyek as ahp", "assign_hr_to_activity.user_id", "=", "ahp.user_id")
+ ->where("assign_hr_to_activity.activity_id", $activity_id)->where("assign_hr_to_activity.proyek_id", $proyek_id)
+ ->where("ahp.proyek_id", $proyek_id)
+ ->get();
+
+ $totalCost = 0;
+ foreach ($dataHuman as $human) {
+ $totalCost += $this->calculateHumanCost($human, $activity_id);
+ }
+
+ return $totalCost;
+ }
+
+ private function calculateHumanCost($human, $activity_id)
+ {
+ $activity = Activity::find($activity_id);
+ $duration = $activity->duration;
+ $standarRate = $human->standart_rate;
+ $maxUsed = $human->max_used/100;
+ if ($human->uom_standart_rate == "Hour") {
+ $totalCost = ($standarRate*8*$duration)*$maxUsed;
+ return $totalCost;
+ }
+ $totalCost = ($standarRate*$duration)*$maxUsed;
+ return $totalCost;
+ }
+
+ private function calculateMaterialCost($activity_id, $proyek_id)
+ {
+ $totalCost = AssignMaterial::selectRaw("COALESCE(qty_planning,0)*COALESCE(budget,0) as totalCost")
+ ->where("proyek_id", $proyek_id)
+ ->where("activity_id", $activity_id)
+ ->sum(AssignMaterial::raw("COALESCE(qty_planning, 0) * COALESCE(budget, 0)"));
+ return $totalCost;
+ }
+
+ protected function getLoc($lat, $lng){
+ // $response = Http::get(config('api.nominatim') . "/reverse?lat=".$lat."&lon=".$lng."&format=json");
+ // return $response->json;
+
+ $url = config('api.nominatim') . "/reverse?lat=".$lat."&lon=".$lng."&format=json";
+ // $token = config('api.adw_token');
+ $response = $this->curlRequest($url);
+ return $response;
+ }
+
+ private function curlRequest($url){
+ $ch = curl_init();
+ // $headers = [
+ // 'Authorization: '.$token
+ // ];
+ curl_setopt($ch, CURLOPT_URL, $url);
+ // curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+
+ $response = curl_exec($ch);
+ if ($response === false)
+ $response = curl_error($ch);
+ curl_close($ch);
+
+ return json_decode($response);
+ }
+
+ protected function addDetailK3($dataDetail, $report_id){
+ foreach ($dataDetail as $value) {
+ $dataNew = array(
+ "report_k3_id"=>$report_id,
+ "checklist_k3_id"=>$value['checklist_id'],
+ "name_checklist_k3"=>$value['checklist_name'],
+ "created_by"=>$this->currentName
+ );
+
+ ReportK3Detail::create($dataNew);
+ }
+ }
+}
diff --git a/app/Http/Controllers/DashboardBoDController.php b/app/Http/Controllers/DashboardBoDController.php
index 273d568..143af38 100644
--- a/app/Http/Controllers/DashboardBoDController.php
+++ b/app/Http/Controllers/DashboardBoDController.php
@@ -10,19 +10,22 @@ use App\Models\User;
use App\Models\UserToVersionGantt;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;
+use Illuminate\Support\Facades\Log;
class DashboardBoDController extends Controller
{
- private function interpolateYear($year){
- if($year)
- $year = '%'.$year.'%';
+ private function interpolateYear($year)
+ {
+ if ($year)
+ $year = '%' . $year . '%';
return $year;
}
- private function curlReq($url, $token){
+ private function curlReq($url, $token)
+ {
$ch = curl_init();
$headers = [
- 'Authorization: '.$token
+ 'Authorization: ' . $token
];
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
@@ -36,45 +39,47 @@ class DashboardBoDController extends Controller
return json_decode($response);
}
- private function getInvoiceIntegration($search) {
- // 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');
- // $token = config('api.adw_token');
- // $response = $this->curlReq($url, $token);
- //
- // if(@$response->data->project_no == "")
- // return null;
- //
- return null;
+ private function getInvoiceIntegration($search)
+ {
+ 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');
+ $token = config('api.adw_token');
+ $response = $this->curlReq($url, $token);
+
+ if(@$response->data->project_no == "")
+ return null;
+
+ return $response;
}
// to do
- public function getCompanyCashFlow($year = '%') {
+ public function getCompanyCashFlow($year = '%')
+ {
$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) */
+ /* ->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){
+ foreach ($projects as $project) {
$project->expenses = 0;
$resp = null;
- if($project->kode_sortname != ""){
+ 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;
+ $totalExpenditure += (int) $cost;
$totalInvoice += $resp->data->total_invoice_amount ?? 0;
$totalPaidInvoice += $resp->data->total_invoice_paid_amount ?? 0;
}
@@ -86,20 +91,21 @@ class DashboardBoDController extends Controller
'total_budget' => (int) $totalBudgets ?? 0,
'total_expenditure' => $totalExpenditure,
'total_invoice' => $totalInvoice,
- 'total_paid_invoice' => $totalPaidInvoice ,
+ 'total_paid_invoice' => $totalPaidInvoice,
]
], 200);
}
- public function getInvoiceOutstanding($year = '%'){
+ public function getInvoiceOutstanding($year = '%')
+ {
$year = $this->interpolateYear($year);
$projects = Project::where('mulai_proyek', 'like', $year)
/* ->orWhere('akhir_proyek', 'like', $year) */
->get();
$return = [];
- foreach($projects as $project){
+ foreach ($projects as $project) {
$resp = null;
- if($project->kode_sortname != ""){
+ if ($project->kode_sortname != "") {
$resp = $this->getInvoiceIntegration($project->kode_sortname);
array_push($return, [
'project' => $project->nama,
@@ -116,7 +122,8 @@ class DashboardBoDController extends Controller
], 200);
}
- public function getTotalProjectPerScheduleHealth($year = '%'){
+ public function getTotalProjectPerScheduleHealth($year = '%')
+ {
$year = $this->interpolateYear($year);
$return = [
@@ -126,40 +133,49 @@ class DashboardBoDController extends Controller
];
$projects = Project::where('mulai_proyek', 'like', $year)->get();
- foreach($projects as $project) {
+ foreach ($projects as $project) {
$project->scurve = MasterFunctionsHelper::getSCurve($project->id);
+ $selisihProgress = 0;
+ if ($project->scurve && $project->scurve[0]) {
+ $planningArray = $project->scurve[0]['data']['percentagePlan'];
+ $actualArray = $project->scurve[0]['data']['percentageReal'];
+ $planningProgress = !empty($planningArray) ? $planningArray[count($planningArray) - 1] : 0;
+ $actualProgress = !empty($actualArray) ? $actualArray[count($actualArray) - 1] : 0;
+ }
+ $selisihProgress = $planningProgress - $actualProgress;
try {
- if(@$project->scurve['difference'] > 0 && @$project->scurve['difference'] <= 5)
- $return['warning'] += 1;
- elseif(@$project->scurve['difference'] > 5 && @$project->scurve['difference'] <= 100)
- $return['behind-schedule'] += 1;
- elseif(@$project->scurve['difference'] == 0)
- $return['on-schedule'] += 1;
+ if ($selisihProgress > 0 && $selisihProgress <= 5)
+ $return['warning'] += 1;
+ elseif ($selisihProgress == 0)
+ $return['on-schedule'] += 1;
+ else
+ $return['behind-schedule'] += 1;
} catch (\Error $e) {
- return response()->json(['msg' => $e->getMessage(), 'data' => $project], 200);
+ return response()->json(['msg' => $e->getMessage(), 'data' => $project], 200);
}
}
return response()->json(['data' => $return, 'q' => $projects], 200);
}
- public function getTotalProjectScheduleHealthPerDivision($year = '%'){
+ public function getTotalProjectScheduleHealthPerDivision($year = '%')
+ {
$year = $this->interpolateYear($year);
$divisions = Divisi::whereNull('parent')->get();
- foreach($divisions as $division){
+ foreach ($divisions as $division) {
$scheduleData = new Collection();
$behindSchedule = $warning = $onSchedule = 0;
$projects = Project::where('mulai_proyek', 'like', $year)->where('divisi_id', $division->id)->get();
- foreach($projects as $project) {
+ foreach ($projects as $project) {
$project->scurve = MasterFunctionsHelper::getSCurve($project->id);
- if(@$project->scurve['difference'] > 0 && @$project->scurve['difference'] <= 5)
+ if (@$project->scurve['difference'] > 0 && @$project->scurve['difference'] <= 5)
$warning++;
- elseif(@$project->scurve['difference'] > 5 && @$project->scurve['difference'] <= 100)
+ elseif (@$project->scurve['difference'] > 5 && @$project->scurve['difference'] <= 100)
$behindSchedule++;
- elseif(@$project->scurve['difference'] == 0)
+ elseif (@$project->scurve['difference'] == 0)
$onSchedule++;
}
@@ -175,7 +191,8 @@ class DashboardBoDController extends Controller
], 200);
}
- public function getTotalProjectPerBudgetHealth($year = '%'){
+ public function getTotalProjectPerBudgetHealth($year = '%')
+ {
$year = $this->interpolateYear($year);
return response()->json([
'data' => [
@@ -186,28 +203,30 @@ class DashboardBoDController extends Controller
], 200);
}
- private function countTotalProjectByBudgetHealthInDivision($divisi, $year, $health){
+ private function countTotalProjectByBudgetHealthInDivision($divisi, $year, $health)
+ {
return Project::where('divisi_id', $divisi)
->where('mulai_proyek', 'like', $year)
- /* ->orWhere('akhir_proyek', 'like', $year) */
+ /* ->orWhere('akhir_proyek', 'like', $year) */
->where('budget_health', $health)
->count();
}
- public function getTotalProjectBudgetHealthPerDivision($year = '%'){
+ public function getTotalProjectBudgetHealthPerDivision($year = '%')
+ {
$year = $this->interpolateYear($year);
- $divisions = Divisi::select('id','name')
+ $divisions = Divisi::select('id', 'name')
->with('children')
->whereNull('parent')
->get();
// to do : count in more than 1 level child
- foreach($divisions as $division){
+ foreach ($divisions as $division) {
$budgetData = new Collection();
$budgetData->prepend($this->countTotalProjectByBudgetHealthInDivision($division->id, $year, 'overrun'), 'overrun');
$budgetData->prepend($this->countTotalProjectByBudgetHealthInDivision($division->id, $year, 'warning'), 'warning');
$budgetData->prepend($this->countTotalProjectByBudgetHealthInDivision($division->id, $year, 'on-budget'), 'on-budget');
- foreach($division->children as $d){
+ foreach ($division->children as $d) {
$budgetData['overrun'] += $this->countTotalProjectByBudgetHealthInDivision($d->id, $year, 'overrun');
$budgetData['warning'] += $this->countTotalProjectByBudgetHealthInDivision($d->id, $year, 'warning');
$budgetData['on-budget'] += $this->countTotalProjectByBudgetHealthInDivision($d->id, $year, 'on-budget');
@@ -215,7 +234,7 @@ class DashboardBoDController extends Controller
unset($division->children);
$division->budgetData = $budgetData;
}
- foreach($divisions as $division){
+ foreach ($divisions as $division) {
}
return response()->json([
'data' => [
@@ -224,14 +243,15 @@ class DashboardBoDController extends Controller
], 200);
}
- public function getTotalProjectPerPhase($year = '%'){
+ public function getTotalProjectPerPhase($year = '%')
+ {
$year = $this->interpolateYear($year);
$projectPhases = ProjectPhase::orderBy('order')->get();
- foreach($projectPhases as $phase){
+ foreach ($projectPhases as $phase) {
$phase->totalProject = Project::where('phase_id', $phase->id)
- ->where('mulai_proyek', 'like', $year)
- /* ->orWhere('akhir_proyek', 'like', $year) */
- ->count();
+ ->where('mulai_proyek', 'like', $year)
+ /* ->orWhere('akhir_proyek', 'like', $year) */
+ ->count();
}
return response()->json([
'data' => [
@@ -240,24 +260,26 @@ class DashboardBoDController extends Controller
], 200);
}
- private function countTotalProjectInDivision($id, $year){
+ private function countTotalProjectInDivision($id, $year)
+ {
return Project::where('divisi_id', $id)
->where('mulai_proyek', 'like', $year)
->count();
}
- public function getTotalProjectPerDivision($year = '%') {
+ public function getTotalProjectPerDivision($year = '%')
+ {
$year = $this->interpolateYear($year);
- $divisions = Divisi::select('id','name')
+ $divisions = Divisi::select('id', 'name','parent','color')
->with('children')
->whereNull('parent')
->get();
// to do : count in more than 1 level child
- foreach($divisions as $v){
+ foreach ($divisions as $v) {
$v->total = $this->countTotalProjectInDivision($v->id, $year);
- foreach($v->children as $d){
+ foreach ($v->children as $d) {
$v->total += $this->countTotalProjectInDivision($d->id, $year);
}
unset($v->children);
@@ -268,27 +290,29 @@ class DashboardBoDController extends Controller
], 200);
}
- private function countTotalProjectValueInDivision($id, $year){
+ private function countTotalProjectValueInDivision($id, $year)
+ {
return Project::select(DB::raw('SUM(CAST("rencana_biaya" AS DOUBLE PRECISION))'))
->where('mulai_proyek', 'like', $year)
- /* ->orWhere('akhir_proyek', 'like', $year) */
+ /* ->orWhere('akhir_proyek', 'like', $year) */
->where('divisi_id', $id)
->pluck('sum')
->first();
}
- public function getTotalProjectValuePerDivision($year = '%') {
+ public function getTotalProjectValuePerDivision($year = '%')
+ {
$year = $this->interpolateYear($year);
- $divisions = Divisi::select('id','name')
+ $divisions = Divisi::select('id', 'name')
->with('children')
->whereNull('parent')
->get();
// to do : count in more than 1 level child
- foreach($divisions as $v){
+ foreach ($divisions as $v) {
$v->total = $this->countTotalProjectValueInDivision($v->id, $year);
- foreach($v->children as $d){
+ foreach ($v->children as $d) {
$v->total += $this->countTotalProjectValueInDivision($d->id, $year);
}
unset($v->children);
@@ -300,16 +324,17 @@ class DashboardBoDController extends Controller
}
- public function getDetailExpenditure($year = '%'){
+ public function getDetailExpenditure($year = '%')
+ {
$year = $this->interpolateYear($year);
$projects = Project::where('mulai_proyek', 'like', $year)
/* ->orWhere('akhir_proyek', 'like', $year) */
->orderBy('id', 'desc')
->get();
- foreach($projects as $project){
+ foreach ($projects as $project) {
$lastGantt = MasterFunctionsHelper::getLatestGantt($project->id);
- if($project->kode_sortname != ""){
+ if ($project->kode_sortname != "") {
$resp = $this->getInvoiceIntegration($project->kode_sortname);
$project->invoice = [
'invoiced' => $resp->data->total_invoice_amount ?? 0,
@@ -319,12 +344,12 @@ class DashboardBoDController extends Controller
$project->pm = User::find($project->pm_id);
/* $project->header = Activity::where('proyek_id', $project->id)->where('version_gantt_id', $lastGantt['last_gantt_id'])->whereNull('parent_id')->first(); */
- if(!isset($lastGantt['last_gantt_id'])){
- $project->manPowers = 0;
- } else {
- $project->manPowers = UserToVersionGantt::where('version_gantt_id', $lastGantt['last_gantt_id'])->count();
- $project->scurve = MasterFunctionsHelper::getSCurve($project->id);
- }
+ if (!isset($lastGantt['last_gantt_id'])) {
+ $project->manPowers = 0;
+ } else {
+ $project->manPowers = UserToVersionGantt::where('version_gantt_id', $lastGantt['last_gantt_id'])->count();
+ $project->scurve = MasterFunctionsHelper::getSCurve($project->id);
+ }
$project->lastGanttId = MasterFunctionsHelper::getLatestGantt($project->id);
}
@@ -334,4 +359,3 @@ class DashboardBoDController extends Controller
], 200);
}
}
-
diff --git a/app/Http/Controllers/DivisiController.php b/app/Http/Controllers/DivisiController.php
index ea7c3d4..2d056aa 100644
--- a/app/Http/Controllers/DivisiController.php
+++ b/app/Http/Controllers/DivisiController.php
@@ -1,99 +1,114 @@
-depth = $depth;
- array_push($array, $divisi);
- foreach($divisi->children as $child){
- $array = $this->getAllChildren($child, $depth + 1, $array);
- }
- return $array;
- }
-
- public function add(Request $request){
- $this->validate($request, [
- 'name' => 'required',
- 'description' => 'string',
- 'parent' => 'integer'
- ]);
-
- $data = $request->all();
- $data['created_by'] = $this->currentName;
-
- $result = Divisi::create($data);
-
- if(!$result)
- return response()->json(['status'=>'failed','message'=>'Failed to add data','code'=> 500]);
-
- return response()->json(['status'=>'success','message'=>'Data created!','code'=>200]);
- }
-
- public function update(Request $request, $id){
- if(empty($id) || !is_int((int)$id))
- return response()->json(['status'=>'failed','message'=>'id is required!','code'=>400], 400);
-
- $data = Divisi::find($id);
-
- if(!$data)
- return response()->json(['status'=>'failed','message'=> 'Data not found!','code'=> 404], 404);
-
- $result = $data->update($request->all());
-
- if(!$result)
- return response()->json(['status'=>'failed','message'=> 'Update failed!','code'=> 500], 500);
-
- return response()->json(['status'=>'success','message'=>'Data added!','code'=>200], 200);
- }
-
- public function delete($id)
- {
- if(empty($id) || !is_int((int)$id))
- return response()->json(['status'=>'failed','message'=>'id is required!','code'=>400], 400);
-
- $data = Divisi::find($id);
-
- if(!$data)
- return response()->json(['status'=>'failed','message'=> 'Data not found!','code'=> 404], 404);
-
- $delete = $data->delete();
-
- if(!$delete)
- return response()->json(['status'=>'failed','message'=> 'Delete failed!','code'=> 500], 500);
-
- return response()->json(['status'=>'success','message'=> 'Data deleted!','code'=> 200], 200);
- }
-
- public function search()
- {
- return $this->list();
- // cant use builder for this case
- }
-
- public function list()
- {
- $parentMenus = Divisi::whereNull('parent')->with('children')->get();
- $divisions = [];
- foreach($parentMenus as $menu){
- $childs = $this->getAllChildren($menu);
- foreach($childs as $d){
- $d->displayName = ' ' . $d->name;
- for($i=0; $i < $d->depth; $i++){
- $d->displayName = '--' . $d->displayName ;
- }
- array_push($divisions, $d);
- }
- }
- $countData = count($divisions);
- if($countData == 0)
- return response()->json(['status'=>'failed','message'=>'Data not found!','code'=> 404], 404);
-
- return response()->json(['status'=>'success','code'=>200,'data'=> $divisions, 'totalRecord'=> $countData], 200);
- }
-}
+depth = $depth;
+ array_push($array, $divisi);
+ foreach($divisi->children as $child){
+ $array = $this->getAllChildren($child, $depth + 1, $array);
+ }
+ return $array;
+ }
+
+ public function add(Request $request){
+ $this->validate($request, [
+ 'name' => 'string|required|unique:m_divisi,name',
+ 'description' => 'nullable|string',
+ 'parent' => 'nullable|integer',
+ 'color'=>'nullable|string|max:10'
+ ]);
+
+ $data = $request->all();
+ $data['created_by'] = $this->currentName;
+
+ $result = Divisi::create($data);
+
+ if(!$result)
+ return response()->json(['status'=>'failed','message'=>'Failed to add data','code'=> 500]);
+
+ return response()->json(['status'=>'success','message'=>'Data created!','code'=>200]);
+ }
+
+ public function update(Request $request, $id){
+ if(empty($id) || !is_int((int)$id))
+ return response()->json(['status'=>'failed','message'=>'id is required!','code'=>400], 400);
+
+ $this->validate($request, [
+ 'name' => 'string|required',
+ 'description' => 'nullable|string',
+ 'parent' => 'nullable|integer'
+ ]);
+ $data = Divisi::find($id);
+
+ $request->name !== $data['name'] ? $this->validate($request,['name'=>'unique:m_divisi,name']) : '';
+
+ if(!$data)
+ return response()->json(['status'=>'failed','message'=> 'Data not found!','code'=> 404], 404);
+
+ $result = $data->update($request->all());
+
+ if(!$result)
+ return response()->json(['status'=>'failed','message'=> 'Update failed!','code'=> 500], 500);
+
+ return response()->json(['status'=>'success','message'=>'Data added!','code'=>200], 200);
+ }
+
+ public function delete($id)
+ {
+ if(empty($id) || !is_int((int)$id))
+ return response()->json(['status'=>'failed','message'=>'id is required!','code'=>400], 400);
+
+ $data = Divisi::find($id);
+
+ if(!$data)
+ return response()->json(['status'=>'failed','message'=> 'Data not found!','code'=> 404], 404);
+
+ $delete = $data->delete();
+
+ if(!$delete)
+ return response()->json(['status'=>'failed','message'=> 'Delete failed!','code'=> 500], 500);
+
+ return response()->json(['status'=>'success','message'=> 'Data deleted!','code'=> 200], 200);
+ }
+
+ public function search(Request $request)
+ {
+ $payload = $request->all();
+ $dataBuilder = $this->setUpPayload($payload, 'm_divisi');
+ $builder = $dataBuilder['builder'];
+ $countBuilder = $dataBuilder['count'];
+ $dataGet = $builder->get();
+ $totalRecord = $countBuilder->count();
+ return response()->json(['status'=>'success','code'=>200,'data'=>$dataGet, 'totalRecord'=>$totalRecord], 200);
+ //return $this->list();
+ // cant use builder for this case
+ }
+
+ public function list()
+ {
+ $parentMenus = Divisi::whereNull('parent')->with('children')->get();
+ $divisions = [];
+ foreach($parentMenus as $menu){
+ $childs = $this->getAllChildren($menu);
+ foreach($childs as $d){
+ $d->displayName = ' ' . $d->name;
+ for($i=0; $i < $d->depth; $i++){
+ $d->displayName = '--' . $d->displayName ;
+ }
+ array_push($divisions, $d);
+ }
+ }
+ $countData = count($divisions);
+ if($countData == 0)
+ return response()->json(['status'=>'failed','message'=>'Data not found!','code'=> 404], 404);
+
+ return response()->json(['status'=>'success','code'=>200,'data'=> $divisions, 'totalRecord'=> $countData], 200);
+ }
+}
diff --git a/app/Http/Controllers/HierarchyFtthController.php b/app/Http/Controllers/HierarchyFtthController.php
index 388bb2a..3b3f64f 100644
--- a/app/Http/Controllers/HierarchyFtthController.php
+++ b/app/Http/Controllers/HierarchyFtthController.php
@@ -110,12 +110,15 @@ class HierarchyFtthController extends Controller
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) {
@@ -149,6 +152,30 @@ class HierarchyFtthController extends Controller
}
}
}
+
+ public function getTreeByGantt($gantt_id)
+ {
+ $finalData = [];
+ $gantt = VersionGantt::find($gantt_id);
+ if ($gantt->hierarchy_ftth_id) {
+ $ftth = HierarchyFtth::find($gantt->hierarchy_ftth_id);
+ array_push($finalData, $ftth);
+ if($ftth->parent_id){
+ $this->getParents($finalData, $ftth->parent_id);
+ }
+ } else {
+ return response()->json(['status'=>'success','data'=>$finalData,'code'=>200], 200);
+ }
+ return response()->json(['status'=>'success','data'=>$finalData,'code'=>200], 200);
+ }
+
+ public function getParents(&$data, $id){
+ $ftth = HierarchyFtth::find($id);
+ array_push($data, $ftth);
+ if ($ftth->parent_id) {
+ $this->getParents($data, $ftth->parent_id);
+ }
+ }
public function getTreeByProject($project_id)
{
@@ -165,6 +192,7 @@ class HierarchyFtthController extends Controller
foreach ($progress as $p) {
if ($p->id == $gantt->id) {
$gantt->progress = $p->persentase_progress;
+ $gantt->bobot_planning = $p->bobot_planning ? $p->bobot_planning : 0;
}
}
}
@@ -192,6 +220,7 @@ class HierarchyFtthController extends Controller
foreach ($progress as $p) {
if ($p->id == $gantt->id) {
$gantt->progress = $p->persentase_progress;
+ $gantt->bobot_planning = $p->bobot_planning ? $p->bobot_planning : 0;
}
}
}
@@ -204,7 +233,7 @@ class HierarchyFtthController extends Controller
}
public function ganttProgress($column, $value){
- $progress = VersionGantt::select('m_version_gantt.id','m_activity.persentase_progress')
+ $progress = VersionGantt::select('m_version_gantt.id','m_activity.persentase_progress', 'm_activity.bobot_planning')
->join('m_activity', 'm_version_gantt.id', '=', 'm_activity.version_gantt_id')
->where("m_version_gantt.".$column, $value)
->where('m_activity.type_activity', "project")
diff --git a/app/Http/Controllers/HumanResourceController.php b/app/Http/Controllers/HumanResourceController.php
index 8e23f87..be26a1c 100644
--- a/app/Http/Controllers/HumanResourceController.php
+++ b/app/Http/Controllers/HumanResourceController.php
@@ -1,178 +1,199 @@
-validate($request, [
- 'role_id' => 'required',
- 'name' => 'required',
- 'ktp_number' => 'required',
- 'employee_type' => 'required'
- ]);
-
- $data = $request->all();
-
- if(isset($request->password) && $request->password!=""){
- $data['password'] = md5($request->password);
- }
-
- $result = HumanResource::create($data);
-
- if($result){
- return response()->json(['status'=>'success','message'=>'Human Resource Pool successfull created','code'=>200]);
- }else{
- return response()->json(['status'=>'failed','message'=>'Human Resource Pool failed created','code'=>400]);
- }
- }
-
- public function edit($id){
- if(!$id || (int) $id < 0 || $id==""){
- return response()->json(['status'=>'failed','message'=>'id is required!','code'=>400], 400);
- die();
- }
-
- $result = HumanResource::find($id);
-
- if($result){
- return response()->json(['status'=>'success','code'=>200,'data'=>$result], 200);
- }else{
- return response()->json(['status'=>'failed','message'=>'failed get data human resource, please try again later!','code'=>400], 400);
- }
- }
-
- public function update(Request $request, $id){
-
- if(!$id || (int) $id < 0 || $id==""){
- return response()->json(['status'=>'failed','message'=>'id is required!','code'=>400], 400);
- }
-
- $humanresource = HumanResource::find($id);
-
- $data = $request->all();
-
- if(isset($request->password) && $request->password!="" ){
- $data['password'] = md5($request->password);
- }
-
- if(isset($data['username']) && HumanResource::where('username', $data['username'])->where('id', '<>', $id)->exists()){
- return response()->json(['status'=>'failed','message'=>'Username already exists!','code'=>400], 400);
- }
-
- if($humanresource){
- $result = $humanresource->update($data);
- }else{
- return response()->json(['status'=>'failed','message'=>'data Human Resource Pool not found!','code'=>400], 400);
- die();
- }
-
- if($result){
- return response()->json(['status'=>'success','message'=>'Human Resource Pool successfully updated!','code'=>200], 200);
- }else{
- return response()->json(['status'=>'failed','message'=>'Human Resource Pool failed updated!','code'=>400], 400);
- }
- }
-
- public function delete($id)
- {
- $data = HumanResource::find($id);
-
- if($data){
- $delete = $data->delete();
- }else{
- return response()->json(['status'=>'failed','message'=>'data Human Resource Pool not found!','code'=>400], 400);
- die();
- }
-
-
- if($delete){
- return response()->json(['status'=>'success','message'=>'Human Resource Pool successfully deleted!','code'=>200], 200);
- }else{
- return response()->json(['status'=>'failed','message'=>'Human Resource Pool failed deleted!','code'=>400], 400);
- }
- }
-
- public function search(Request $request)
- {
- $payload = $request->all();
- $dataBuilder = $this->setUpPayload($payload, 'm_users');
- $builder = $dataBuilder['builder'];
- $countBuilder = $dataBuilder['count'];
- $dataGet = $builder->get();
- $totalRecord = $countBuilder->count();
- return response()->json(['status'=>'success','code'=>200,'data'=>$dataGet, 'totalRecord'=>$totalRecord], 200);
- }
-
- public function list()
- {
- $data = HumanResource::all();
- $countData = $data->count();
-
- if($data){
- return response()->json(['status'=>'success','code'=>200,'data'=>$data, 'totalRecord'=>$countData], 200);
- }else{
- return response()->json(['status'=>'failed','message'=>'failed get list human resource, please try again later!','code'=>400], 400);
- }
- }
-
- public function select(Request $request){
-
- $search = $request->query('search');
-
- $idActivity = (int)$request->query('idact');
- $idProyek = (int)$request->query('idProyek');
-
- $forbidden = [];
-
- if($idActivity && $idActivity > 0){
- $dataF = UserToActivity::select("user_id")->where("activity_id", $idActivity)->get();
- foreach($dataF as $val){
- $forbidden[] = $val->user_id;
- }
- }
-
- if($search && !empty($search)){
- $data = UserToProyek::select("m_users.id as id", "m_users.name as name", "assign_hr_to_proyek.project_role as proyek_role")->join('m_users', 'm_users.id', '=', 'assign_hr_to_proyek.user_id')
- ->where("assign_hr_to_proyek.proyek_id", $idProyek)->where("m_users.name", 'like', '%'.$search.'%')->whereNotIn("m_users.id", $forbidden)->get();
- }else{
- $data = UserToProyek::select("m_users.id as id", "m_users.name as name", "assign_hr_to_proyek.project_role as proyek_role")->where("assign_hr_to_proyek.proyek_id", $idProyek)->join('m_users', 'm_users.id', '=', 'assign_hr_to_proyek.user_id')->whereNotIn("m_users.id", $forbidden)->get();
- }
-
- return response()->json($data);
- }
-
- public function checkOldPassword(Request $request, $id)
- {
- if(!$id || (int) $id < 0 || $id==""){
- return response()->json(['status'=>'failed','message'=>'id is required!','code'=>400], 400);
- die();
- }
-
- $data = $request->all();
-
- if(isset($request->old_password) && $request->old_password!="" ){
- $result = HumanResource::find($id);
- $data['old_password'] = md5($request->old_password);
- if($data['old_password'] !== $result->password) {
- return response()->json(['status'=>'failed','message'=>"old password seems doesn't match in records. please try again.",'code'=>400], 400);
- }
- elseif($data['old_password'] === $result->password) {
- return response()->json(['status'=>'success','message'=>"old password match",'data'=>$result,'code'=>200], 200);
- }
- }
- else {
- return response()->json(['status'=>'failed','message'=>'old_password is required!','code'=>400], 400);
- }
- }
-
- public function sync(){
- Artisan::call('sync:integration-human-resources');
- }
-}
+validate($request, [
+ 'role_id' => 'required',
+ 'name' => 'required',
+ 'ktp_number' => 'required|numeric|unique:m_users,ktp_number',
+ 'employee_type' => 'required'
+ ]);
+
+ $data = $request->all();
+
+ if (isset($request->password) && $request->password != "") {
+ $data['password'] = md5($request->password);
+ }
+
+ $result = HumanResource::create($data);
+
+ if ($result) {
+ return response()->json(['status' => 'success', 'message' => 'Human Resource Pool successfull created', 'code' => 200]);
+ } else {
+ return response()->json(['status' => 'failed', 'message' => 'Human Resource Pool failed created', 'code' => 400]);
+ }
+ }
+
+ public function edit($id)
+ {
+ if (!$id || (int) $id < 0 || $id == "") {
+ return response()->json(['status' => 'failed', 'message' => 'id is required!', 'code' => 400], 400);
+ die();
+ }
+
+ $result = HumanResource::find($id);
+
+ if ($result) {
+ return response()->json(['status' => 'success', 'code' => 200, 'data' => $result], 200);
+ } else {
+ return response()->json(['status' => 'failed', 'message' => 'failed get data human resource, please try again later!', 'code' => 400], 400);
+ }
+ }
+
+ public function update(Request $request, $id)
+ {
+
+ if (!$id || (int) $id < 0 || $id == "") {
+ return response()->json(['status' => 'failed', 'message' => 'id is required!', 'code' => 400], 400);
+ }
+ $humanresource = HumanResource::find($id);
+
+ $request->ktp_number !== $humanresource['ktp_number'] ? $this->validate($request,['ktp_number'=>'unique:m_users,ktp_number|numeric']) : '';
+ $request->email !== $humanresource['email'] ? $this->validate($request,['email'=>'unique:m_users,email|email']) : '';
+ $request->password ? $this->validate($request,['password'=>'required|min:8']) : '';
+
+ $data = $request->all();
+
+ if (isset($request->password) && $request->password != "") {
+ $data['password'] = md5($request->password);
+ }
+
+ if (isset($data['username']) && HumanResource::where('username', $data['username'])->where('id', '<>', $id)->exists()) {
+ return response()->json(['status' => 'failed', 'message' => 'Username already exists!', 'code' => 400], 400);
+ }
+
+ if ($humanresource) {
+ $result = $humanresource->update($data);
+ } else {
+ return response()->json(['status' => 'failed', 'message' => 'data Human Resource Pool not found!', 'code' => 400], 400);
+ die();
+ }
+
+ if ($result) {
+ return response()->json(['status' => 'success', 'message' => 'Human Resource Pool successfully updated!', 'code' => 200], 200);
+ } else {
+ return response()->json(['status' => 'failed', 'message' => 'Human Resource Pool failed updated!', 'code' => 400], 400);
+ }
+ }
+
+ public function delete($id)
+ {
+ $data = HumanResource::find($id);
+
+ if ($data) {
+ $delete = $data->delete();
+ } else {
+ return response()->json(['status' => 'failed', 'message' => 'data Human Resource Pool not found!', 'code' => 400], 400);
+ die();
+ }
+
+
+ if ($delete) {
+ return response()->json(['status' => 'success', 'message' => 'Human Resource Pool successfully deleted!', 'code' => 200], 200);
+ } else {
+ return response()->json(['status' => 'failed', 'message' => 'Human Resource Pool failed deleted!', 'code' => 400], 400);
+ }
+ }
+
+ public function search(Request $request)
+ {
+ $payload = $request->all();
+ $dataBuilder = $this->setUpPayload($payload, 'm_users');
+ $builder = $dataBuilder['builder'];
+ $countBuilder = $dataBuilder['count'];
+ $dataGet = $builder->get();
+ $totalRecord = $countBuilder->count();
+ return response()->json(['status' => 'success', 'code' => 200, 'data' => $dataGet, 'totalRecord' => $totalRecord], 200);
+ }
+
+ public function list()
+ {
+ $data = HumanResource::select('id', 'name', 'role_id')->get();
+ $countData = $data->count();
+
+ if ($data) {
+ return response()->json(['status' => 'success', 'code' => 200, 'data' => $data, 'totalRecord' => $countData], 200);
+ } else {
+ return response()->json(['status' => 'failed', 'message' => 'failed get list human resource, please try again later!', 'code' => 400], 400);
+ }
+ }
+
+ public function select(Request $request)
+ {
+
+ $search = $request->query('search');
+
+ $idActivity = (int)$request->query('idact');
+ $idProyek = (int)$request->query('idProyek');
+
+ $forbidden = [];
+
+ if ($idActivity && $idActivity > 0) {
+ $dataF = UserToActivity::select("user_id")->where("activity_id", $idActivity)->get();
+ foreach ($dataF as $val) {
+ $forbidden[] = $val->user_id;
+ }
+ }
+
+ if ($search && !empty($search)) {
+ $data = UserToProyek::select("m_users.id as id", "m_users.name as name", "assign_hr_to_proyek.project_role as proyek_role")
+ ->join('m_users', 'm_users.id', '=', 'assign_hr_to_proyek.user_id')
+ ->where("assign_hr_to_proyek.proyek_id", $idProyek)
+ ->where(function ($query) {
+ $query->where("assign_hr_to_proyek.is_customer", "!=", true)
+ ->orWhereNull("assign_hr_to_proyek.is_customer");
+ })
+ ->where("m_users.name", 'like', '%' . $search . '%')
+ ->whereNotIn("m_users.id", $forbidden)->get();
+ } else {
+ $data = UserToProyek::select("m_users.id as id", "m_users.name as name", "assign_hr_to_proyek.project_role as proyek_role")
+ ->where("assign_hr_to_proyek.proyek_id", $idProyek)
+ ->where(function ($query) {
+ $query->where("assign_hr_to_proyek.is_customer", "!=", true)
+ ->orWhereNull("assign_hr_to_proyek.is_customer");
+ })
+ ->join('m_users', 'm_users.id', '=', 'assign_hr_to_proyek.user_id')
+ ->whereNotIn("m_users.id", $forbidden)
+ ->get();
+ }
+
+ return response()->json($data);
+ }
+
+ public function checkOldPassword(Request $request, $id)
+ {
+ if (!$id || (int) $id < 0 || $id == "") {
+ return response()->json(['status' => 'failed', 'message' => 'id is required!', 'code' => 400], 400);
+ die();
+ }
+
+ $data = $request->all();
+
+ if (isset($request->old_password) && $request->old_password != "") {
+ $result = HumanResource::find($id);
+ $data['old_password'] = md5($request->old_password);
+ if ($data['old_password'] !== $result->password) {
+ return response()->json(['status' => 'failed', 'message' => "old password seems doesn't match in records. please try again.", 'code' => 400], 400);
+ } elseif ($data['old_password'] === $result->password) {
+ return response()->json(['status' => 'success', 'message' => "old password match", 'data' => $result, 'code' => 200], 200);
+ }
+ } else {
+ return response()->json(['status' => 'failed', 'message' => 'old_password is required!', 'code' => 400], 400);
+ }
+ }
+
+ public function sync()
+ {
+ Artisan::call('sync:integration-human-resources');
+ }
+}
diff --git a/app/Http/Controllers/MapMonitoringController.php b/app/Http/Controllers/MapMonitoringController.php
index 26b36cb..5c17475 100644
--- a/app/Http/Controllers/MapMonitoringController.php
+++ b/app/Http/Controllers/MapMonitoringController.php
@@ -15,56 +15,62 @@ class MapMonitoringController extends Controller
// default map monitoring shows today's presence lat lon in the map
public function search(Request $request)
- {
+ {
$dateNow = Carbon::today()->addHour(7)->format('Y-m-d');
// get distinct human assign project
$hr_assign_project = DB::table('assign_hr_to_proyek')
- ->select('user_id')
- ->whereIn('proyek_id', $request->project_id)
- ->distinct()
- ->get();
+ ->select('user_id')
+ ->whereIn('proyek_id', $request->project_id)
+ ->distinct()
+ ->get();
// get position hr in presensi
$tmp = [];
- foreach($hr_assign_project as $key){
+ foreach ($hr_assign_project as $key) {
$presensi = DB::table('t_clock_in_out as tcio')
- ->select('tcio.id as clock_in_out_id','mu.id as user_id', 'mu.name as fullname', 'tcio.clock_in', 'tcio.clock_out', 'tcio.clock_in_lat', 'tcio.clock_in_lng',
- 'tcio.clock_out_lat', 'tcio.clock_out_lng', 'tcio.clock_in_loc', 'tcio.clock_out_loc', 'tcio.clock_in_boundary',
- 'tcio.clock_out_boundary', 'mu.username', 'tcio.date_presence', 'tcio.created_at')
- ->join('m_users as mu', 'mu.id', '=', 'tcio.user_id')
- ->where('mu.id', $key->user_id)
- ->orderBy('tcio.id', 'DESC')
- ->first();
- $project = DB::table('assign_hr_to_proyek as ahtp')
- ->select('ahtp.proyek_id as id', 'mp.nama as project_name')
- ->join('m_proyek as mp', 'mp.id', '=', 'ahtp.proyek_id')
- ->whereIn('ahtp.proyek_id', $request->project_id)
- ->where('ahtp.user_id', $key->user_id)
- ->get();
- if($presensi && isset($presensi->user_id)){
+ ->select(
+ 'tcio.id as clock_in_out_id',
+ 'mu.id as user_id',
+ 'mu.name as fullname',
+ 'tcio.clock_in',
+ 'tcio.clock_out',
+ 'tcio.clock_in_lat',
+ 'tcio.clock_in_lng',
+ 'tcio.clock_in_loc',
+ 'tcio.clock_out_loc',
+ 'tcio.date_presence'
+ )
+ ->join('m_users as mu', 'mu.id', '=', 'tcio.user_id')
+ ->where('mu.id', $key->user_id)
+ ->orderBy('tcio.clock_in', 'DESC')
+ ->first();
+ $project = DB::table('assign_hr_to_proyek as ahtp')
+ ->select('ahtp.proyek_id as id', 'mp.nama as project_name')
+ ->join('m_proyek as mp', 'mp.id', '=', 'ahtp.proyek_id')
+ ->whereIn('ahtp.proyek_id', $request->project_id)
+ ->where('ahtp.user_id', $key->user_id)
+ ->get();
+ if ($presensi && isset($presensi->user_id)) {
$image = DB::table('m_image')->select('image')->where('category', 'presensi')->where('ref_id', $presensi->clock_in_out_id)->first();
+ $waypoint = DB::table('m_waypoint')->select('lat', 'lon', 'wptime')->where('user_id', $presensi->user_id)->orderBy('wptime', 'DESC')->first();
$tmp[] = array(
- 'user_id' => $presensi->user_id,
- 'clock_in' => $presensi->clock_in,
- 'clock_out' => $presensi->clock_out,
- 'date_presence' => $presensi->date_presence,
- 'clock_in_lat' => $presensi->clock_in_lat,
- 'clock_in_lng' => $presensi->clock_in_lng,
- 'clock_out_lat' => $presensi->clock_out_lat,
- 'clock_out_lng' => $presensi->clock_out_lng,
- 'clock_in_loc' => $presensi->clock_in_loc,
- 'clock_out_loc' => $presensi->clock_out_loc,
- 'clock_in_boundary' => $presensi->clock_in_boundary,
- 'clock_out_boundary' => $presensi->clock_out_boundary,
- 'username' => $presensi->username,
- 'name' => $presensi->fullname,
- 'image_selfie' => isset($image->image) ? $image->image : '-',
- 'created_at' => $presensi->created_at,
- 'presence_status' => $presensi->date_presence == $dateNow ? true : false,//true, //status date_presence,
- 'projects' => $project
+ 'user_id' => $presensi->user_id,
+ 'wp_lat' => isset($waypoint) ? $waypoint->lat : $presensi->clock_in_lat,
+ 'wp_lon' => isset($waypoint) ? $waypoint->lon : $presensi->clock_in_lng,
+ 'wp_time' => isset($waypoint) ? $waypoint->wptime : $presensi->clock_in,
+ 'clock_in' => $presensi->clock_in,
+ 'clock_out' => $presensi->clock_out,
+ 'clock_in_lat' => $presensi->clock_in_lat,
+ 'clock_in_lng' => $presensi->clock_in_lng,
+ 'clock_in_loc' => $presensi->clock_in_loc,
+ 'clock_out_loc' => $presensi->clock_out_loc,
+ 'name' => $presensi->fullname,
+ 'image_selfie' => isset($image->image) ? $image->image : '-',
+ 'presence_status' => $presensi->date_presence == $dateNow ? true : false, //true, //status date_presence,
+ 'projects' => $project
);
}
}
- return response()->json(['status'=>'success','code'=>200, 'data' => $tmp, 'totalRecord'=>count($tmp)], 200);
+ return response()->json(['status' => 'success', 'code' => 200, 'data' => $tmp, 'totalRecord' => count($tmp)], 200);
}
public function list()
@@ -72,12 +78,12 @@ class MapMonitoringController extends Controller
$data = Presence::all();
$countData = $data->count();
- if($data){
- return response()->json(['status'=>'success','code'=>200,'data'=>$data, 'totalRecord'=>$countData], 200);
- }else{
- return response()->json(['status'=>'failed','message'=>'failed get list presence, please try again later!','code'=>400], 400);
+ if ($data) {
+ return response()->json(['status' => 'success', 'code' => 200, 'data' => $data, 'totalRecord' => $countData], 200);
+ } else {
+ return response()->json(['status' => 'failed', 'message' => 'failed get list presence, please try again later!', 'code' => 400], 400);
}
}
-
-}
+
+}
\ No newline at end of file
diff --git a/app/Http/Controllers/MenuController.php b/app/Http/Controllers/MenuController.php
index 679c533..6ff9324 100644
--- a/app/Http/Controllers/MenuController.php
+++ b/app/Http/Controllers/MenuController.php
@@ -1,151 +1,159 @@
-validate($request, [
- 'icon' => 'required',
- 'name' => 'required',
- 'url' => 'required',
- 'sequence' => 'required',
- ]);
-
- $data = $request->all();
-
- $data['created_by'] = $this->currentName;
-
- $result = Menu::create($data);
-
- if($result){
- return response()->json(['status'=>'success','message'=>'add data menu successfully!','code'=>200], 200);
- }else{
- return response()->json(['status'=>'failed','message'=>'add data menu failed!','code'=>400], 400);
- }
- }
-
- public function edit($id){
- if(!$id || (int) $id < 0 || $id==""){
- return response()->json(['status'=>'failed','message'=>'id is required!','code'=>400], 400);
- die();
- }
-
- $result = Menu::find($id);
-
- if($result){
- return response()->json(['status'=>'success','code'=>200,'data'=>$result], 200);
- }else{
- return response()->json(['status'=>'failed','message'=>'failed get data menu, please try again later!','code'=>400], 400);
- }
- }
-
- public function update(Request $request, $id)
- {
- if(!$id || (int) $id < 0 || $id==""){
- return response()->json(['status'=>'failed','message'=>'id is required!','code'=>400], 400);
- }
-
- $data = Menu::find($id);
-
- if($data){
- $result = $data->update($request->all());
- }else{
- return response()->json(['status'=>'failed','message'=>'data menu not found!','code'=>400], 400);
- die();
- }
-
-
- if($result){
- return response()->json(['status'=>'success','message'=>'data menu successfully updated!','code'=>200], 200);
- }else{
- return response()->json(['status'=>'failed','message'=>'data menu failed updated!','code'=>400], 400);
- }
- }
-
- public function delete($id)
- {
- $data = Menu::find($id);
-
- if($data){
- $delete = $data->delete();
- }else{
- return response()->json(['status'=>'failed','message'=>'data menu not found!','code'=>400], 400);
- die();
- }
-
-
- if($delete){
- return response()->json(['status'=>'success','message'=>'data menu successfully deleted!','code'=>200], 200);
- }else{
- return response()->json(['status'=>'failed','message'=>'data menu failed deleted!','code'=>400], 400);
- }
- }
-
- public function search(Request $request)
- {
- $payload = $request->all();
- $dataBuilder = $this->setUpPayload($payload, 'm_menu');
- $builder = $dataBuilder['builder'];
- $countBuilder = $dataBuilder['count'];
- $dataGet = $builder->get();
- $totalRecord = $countBuilder->count();
- return response()->json(['status'=>'success','code'=>200,'data'=>$dataGet, 'totalRecord'=>$totalRecord], 200);
- }
-
- public function listMenu($id)
- {
- $dataParent = RoleMenu::select("m_menu.*")
- ->join('m_menu', 'm_menu.id', '=', 't_roles_menu.menu_id')
- ->join('m_roles', 'm_roles.id', '=', 't_roles_menu.role_id')
- ->whereNull('m_menu.parent_id')
- ->where('m_roles.id', $id)
- ->orderBy('m_menu.sequence', 'ASC')
- ->get();
-
- $finalData = [];
- foreach($dataParent as $data){
- $data->children = $this->getChildrenMenu($data->id, $id);
- $finalData[] = $data;
- }
-
- return response()->json(['status'=>'success','code'=>200,'data'=>$finalData], 200);
- }
-
- protected function getChildrenMenu($id, $role_id)
- {
- $dataChildren = RoleMenu::select("m_menu.*")
- ->join('m_menu', 'm_menu.id', '=', 't_roles_menu.menu_id')
- ->join('m_roles', 'm_roles.id', '=', 't_roles_menu.role_id')
- ->where('m_roles.id', $role_id)
- ->where('m_menu.parent_id', $id)
- ->orderBy('m_menu.sequence', 'ASC')
- ->get();
- $children = [];
- if($dataChildren){
- foreach($dataChildren as $data)
- {
- $data->children = $this->getChildrenMenu($data->id, $role_id);
- $children[] = $data;
- }
- }
- return $children;
- }
-
- public function list()
- {
- $data = Menu::all();
- $countData = $data->count();
-
- if($data){
- return response()->json(['status'=>'success','code'=>200,'data'=>$data, 'totalRecord'=>$countData], 200);
- }else{
- return response()->json(['status'=>'failed','message'=>'failed get list menu, please try again later!','code'=>400], 400);
- }
- }
-}
+validate($request, [
+ 'icon' => 'required',
+ 'name' => 'string|required|unique:m_menu,name',
+ 'url' => 'required|unique:m_menu,url',
+ 'sequence' => 'required|integer',
+ ]);
+
+ $data = $request->all();
+
+ $data['created_by'] = $this->currentName;
+
+ $result = Menu::create($data);
+
+ if($result){
+ return response()->json(['status'=>'success','message'=>'add data menu successfully!','code'=>200], 200);
+ }else{
+ return response()->json(['status'=>'failed','message'=>'add data menu failed!','code'=>400], 400);
+ }
+ }
+
+ public function edit($id){
+ if(!$id || (int) $id < 0 || $id==""){
+ return response()->json(['status'=>'failed','message'=>'id is required!','code'=>400], 400);
+ die();
+ }
+
+ $result = Menu::find($id);
+
+ if($result){
+ return response()->json(['status'=>'success','code'=>200,'data'=>$result], 200);
+ }else{
+ return response()->json(['status'=>'failed','message'=>'failed get data menu, please try again later!','code'=>400], 400);
+ }
+ }
+
+ public function update(Request $request, $id)
+ {
+ if(!$id || (int) $id < 0 || $id==""){
+ return response()->json(['status'=>'failed','message'=>'id is required!','code'=>400], 400);
+ }
+ $this->validate($request, [
+ 'icon' => 'required',
+ 'name' => 'string|required',
+ 'url' => 'required',
+ 'sequence' => 'required|integer',
+ ]);
+ $data = Menu::find($id);
+
+ $request->name !== $data['name'] ? $this->validate($request,['name'=>'unique:m_menu,name']) : '';
+ $request->url !== $data['url'] ? $this->validate($request,['url'=>'unique:m_menu,url']) : '';
+
+ if($data){
+ $result = $data->update($request->all());
+ }else{
+ return response()->json(['status'=>'failed','message'=>'data menu not found!','code'=>400], 400);
+ die();
+ }
+
+
+ if($result){
+ return response()->json(['status'=>'success','message'=>'data menu successfully updated!','code'=>200], 200);
+ }else{
+ return response()->json(['status'=>'failed','message'=>'data menu failed updated!','code'=>400], 400);
+ }
+ }
+
+ public function delete($id)
+ {
+ $data = Menu::find($id);
+
+ if($data){
+ $delete = $data->delete();
+ }else{
+ return response()->json(['status'=>'failed','message'=>'data menu not found!','code'=>400], 400);
+ die();
+ }
+
+
+ if($delete){
+ return response()->json(['status'=>'success','message'=>'data menu successfully deleted!','code'=>200], 200);
+ }else{
+ return response()->json(['status'=>'failed','message'=>'data menu failed deleted!','code'=>400], 400);
+ }
+ }
+
+ public function search(Request $request)
+ {
+ $payload = $request->all();
+ $dataBuilder = $this->setUpPayload($payload, 'm_menu');
+ $builder = $dataBuilder['builder'];
+ $countBuilder = $dataBuilder['count'];
+ $dataGet = $builder->get();
+ $totalRecord = $countBuilder->count();
+ return response()->json(['status'=>'success','code'=>200,'data'=>$dataGet, 'totalRecord'=>$totalRecord], 200);
+ }
+
+ public function listMenu($id)
+ {
+ $dataParent = RoleMenu::select("m_menu.*")
+ ->join('m_menu', 'm_menu.id', '=', 't_roles_menu.menu_id')
+ ->join('m_roles', 'm_roles.id', '=', 't_roles_menu.role_id')
+ ->whereNull('m_menu.parent_id')
+ ->where('m_roles.id', $id)
+ ->orderBy('m_menu.sequence', 'ASC')
+ ->get();
+
+ $finalData = [];
+ foreach($dataParent as $data){
+ $data->children = $this->getChildrenMenu($data->id, $id);
+ $finalData[] = $data;
+ }
+
+ return response()->json(['status'=>'success','code'=>200,'data'=>$finalData], 200);
+ }
+
+ protected function getChildrenMenu($id, $role_id)
+ {
+ $dataChildren = RoleMenu::select("m_menu.*")
+ ->join('m_menu', 'm_menu.id', '=', 't_roles_menu.menu_id')
+ ->join('m_roles', 'm_roles.id', '=', 't_roles_menu.role_id')
+ ->where('m_roles.id', $role_id)
+ ->where('m_menu.parent_id', $id)
+ ->orderBy('m_menu.sequence', 'ASC')
+ ->get();
+ $children = [];
+ if($dataChildren){
+ foreach($dataChildren as $data)
+ {
+ $data->children = $this->getChildrenMenu($data->id, $role_id);
+ $children[] = $data;
+ }
+ }
+ return $children;
+ }
+
+ public function list()
+ {
+ $data = Menu::all();
+ $countData = $data->count();
+
+ if($data){
+ return response()->json(['status'=>'success','code'=>200,'data'=>$data, 'totalRecord'=>$countData], 200);
+ }else{
+ return response()->json(['status'=>'failed','message'=>'failed get list menu, please try again later!','code'=>400], 400);
+ }
+ }
+}
diff --git a/app/Http/Controllers/PresenceController.php b/app/Http/Controllers/PresenceController.php
index 3dba574..17843f4 100644
--- a/app/Http/Controllers/PresenceController.php
+++ b/app/Http/Controllers/PresenceController.php
@@ -1,473 +1,640 @@
-validate($request, [
- 'user_id' => 'required'
- ]);
-
- $checkLocation = $this->checkLocation($request);
- $statusBoundary = false;
- $date = date_create($request->clock_time);
- // assign and in boundary
- if(count($checkLocation) > 0 && $checkLocation[0]['boundary']){
- $statusBoundary = true;
- }
-
- // not assign
- if(!$checkLocation[0]['status_assign'] && $checkLocation[0]['boundary'] == false){
- $data=array(
- 'id' => null,
- 'boundary' => $statusBoundary
- );
- return response()->json(['status'=>'failed', 'data'=>$data, 'message'=>'Tidak dapat melakukan presensi. Anda belum di assign ke area kerja.','code'=>200], 200);
- }
- // assign and not in boundary
- if($checkLocation[0]['status_assign'] && $checkLocation[0]['boundary'] == false){
- $data=array(
- 'id' => null,
- 'boundary' => true
- );
- return response()->json(['status'=>'failed', 'data'=>$data, 'message'=>'Tidak dapat melakukan presensi. Anda berada di luar area kerja.','code'=>200], 200);
- }
-
- if($request->type=="out"){
- $clock_out_loc = $this->getLoc($request->clock_out_lat, $request->clock_out_lng)->display_name;
- $dataUpdate = array(
- "clock_out"=>$request->clock_time,
- "clock_out_lat" => $request->clock_out_lat,
- "clock_out_lng" => $request->clock_out_lng,
- "updated_by"=>$this->currentName,
- "clock_out_loc" => $clock_out_loc,
- "clock_out_boundary" => $statusBoundary
- );
-
- $resultUpdate = $this->updateFormAdd($dataUpdate, $request->user_id);
- if($resultUpdate && $resultUpdate > 0){
- if($statusBoundary){
- for ($i=0; $i < count($checkLocation); $i++) {
- # code...
- DB::table('clock_in_out_boundary')->insert([
- "clock_in_out_id" => $resultUpdate,
- "user_id" => $request->user_id,
- "activity_id" => $checkLocation[$i]['activity_id'],
- "type" => $request->type,
- "created_at" => $date,
- "created_by" => $this->currentName
- ]);
- };
- };
- $data=array(
- 'id' => $resultUpdate,
- 'boundary' => $statusBoundary
- );
-
- return response()->json(['status'=>'success', 'data'=>$data,'message'=>'clock out success!','code'=>200], 200);
- }
- else{
- return response()->json(['status'=>'failed','message'=>'clock out failed please try again!','code'=>400], 400);
- }
- die();
- }
-
- $onlyDate = date_format($date,"Y-m-d");
- $clock_in_loc = $this->getLoc($request->clock_in_lat, $request->clock_in_lng)->display_name;
-
- $dataAdd = array(
- 'user_id'=> $request->user_id,
- 'clock_in'=> $request->clock_time,
- 'date_presence'=> $onlyDate,
- 'created_by' => $this->currentName,
- 'clock_in_lat' => $request->clock_in_lat,
- 'clock_in_lng' => $request->clock_in_lng,
- 'clock_in_loc' => $clock_in_loc,
- 'clock_in_boundary' => $statusBoundary
- );
-
- $result = Presence::create($dataAdd);
- $data=array(
- 'id' => $result->id,
- 'boundary' => $statusBoundary
- );
- if($result){
- if($statusBoundary){
- for ($i=0; $i < count($checkLocation); $i++) {
- # code...
- DB::table('clock_in_out_boundary')->insert([
- "clock_in_out_id" => $result->id,
- "user_id" => $request->user_id,
- "activity_id" => $checkLocation[$i]['activity_id'],
- "type" => $request->type,
- "created_at" => $date,
- "created_by" => $this->currentName
- ]);
- };
- };
- return response()->json(['status'=>'success', 'data' => $data,'message'=>'clock in successfully!','code'=>200], 200);
- }else{
- return response()->json(['status'=>'failed','message'=>'clock in failed!','code'=>400], 400);
- }
- }
-
- public function reportK3(Request $request){
- // return response()->json(['status'=>'success', 'message'=>$request->report_k3['detail'],'code'=>200], 200);
-
- $this->validate($request, [
- 'user_id' => 'required'
- ]);
-
- $checkLocation = $this->checkLocation($request);
- $statusBoundary = false;
- $date = date_create($request->time);
- // assign and in boundary
- if(count($checkLocation) > 0 && $checkLocation[0]['boundary']){
- $statusBoundary = true;
- }
-
- // not assign
- if(!$checkLocation[0]['status_assign'] && $checkLocation[0]['boundary'] == false){
- $data=array(
- 'id' => null,
- 'boundary' => $statusBoundary
- );
- return response()->json(['status'=>'failed', 'data'=>$data, 'message'=>'Tidak dapat melakukan presensi. Anda belum di assign ke area kerja.','code'=>200], 200);
- }
- // assign and not in boundary
- if($checkLocation[0]['status_assign'] && $checkLocation[0]['boundary'] == false){
- $data=array(
- 'id' => null,
- 'boundary' => true
- );
- return response()->json(['status'=>'failed', 'data'=>$data, 'message'=>'Tidak dapat melakukan presensi. Anda berada di luar area kerja.','code'=>200], 200);
- }
-
- if($request->clock_in_out['type']=="out"){
- $clock_out_loc = $this->getLoc($request->clock_in_out['clock_out_lat'], $request->clock_in_out['clock_out_lng'])->display_name;
- $dataUpdate = array(
- "clock_out"=>$request->time,
- "clock_out_lat" => $request->clock_in_out['clock_out_lat'],
- "clock_out_lng" => $request->clock_in_out['clock_out_lng'],
- "updated_by"=>$this->currentName,
- "clock_out_loc" => $clock_out_loc,
- "clock_out_boundary" => $statusBoundary
- );
-
- $resultUpdate = $this->updateFormAdd($dataUpdate, $request->user_id);
- if($resultUpdate && $resultUpdate > 0){
- if($statusBoundary){
- for ($i=0; $i < count($checkLocation); $i++) {
- # code...
- DB::table('clock_in_out_boundary')->insert([
- "clock_in_out_id" => $resultUpdate,
- "user_id" => $request->user_id,
- "activity_id" => $checkLocation[$i]['activity_id'],
- "type" => $request->clock_in_out['type'],
- "created_at" => $date,
- "created_by" => $this->currentName
- ]);
- };
- };
- $data=array(
- 'presence_id' => $resultUpdate,
- 'boundary' => $statusBoundary
- );
-
- return response()->json(['status'=>'success', 'data'=>$data,'message'=>'clock out success!','code'=>200], 200);
- }
- else{
- return response()->json(['status'=>'failed','message'=>'clock out failed please try again!','code'=>400], 400);
- }
- die();
- }
-
- $onlyDate = date_format($date,"Y-m-d");
- $clock_in_loc = $this->getLoc($request->clock_in_out['clock_in_lat'], $request->clock_in_out['clock_in_lng'])->display_name;
-
- $dataFormK3 = array(
- "user_id" => $request->user_id,
- "proyek_id" => $request->report_k3['proyek_id'],
- "report_date" => $request->time,
- "description" => $request->report_k3['description']
- );
-
- $dataFormPresence = array(
- 'user_id' => $request->user_id,
- 'clock_in' => $request->time,
- 'date_presence' => $onlyDate,
- 'created_by' => $this->currentName,
- 'clock_in_lat' => $request->clock_in_out['clock_in_lat'],
- 'clock_in_lng' => $request->clock_in_out['clock_in_lng'],
- 'clock_in_loc' => $clock_in_loc,
- 'clock_in_boundary' => $statusBoundary
- );
-
- $result = Presence::create($dataFormPresence);
- $data=array(
- 'presence_id' => $result->id,
- 'boundary' => $statusBoundary
- );
- if($result){
- if($statusBoundary){
- $insertk3 = $this->insertK3($dataFormK3, $request->report_k3['detail']) ;
- for ($i=0; $i < count($checkLocation); $i++) {
- # code...
- DB::table('clock_in_out_boundary')->insert([
- "clock_in_out_id" => $result->id,
- "user_id" => $request->user_id,
- "activity_id" => $checkLocation[$i]['activity_id'],
- "type" => $request->type,
- "created_at" => $date,
- "created_by" => $this->currentName
- ]);
- };
- $data['report_id'] = $insertk3->id;
- };
- return response()->json(['status'=>'success', 'data'=> $data, 'message'=>'clock in successfully!','code'=>200], 200);
- }else{
- return response()->json(['status'=>'failed','message'=>'clock in failed!','code'=>400], 400);
- }
- }
-
- private function insertK3($params, $details){
- $insert = ReportK3::create($params);
- if($insert && $details){
- $this->addDetailK3($details, $insert->id);
- }
- return $insert;
- }
-
- private function checkLocation($params){
- // cek user tersebut apakah punya assign task yang ada bondary nya
- // geom ada di table activity
- // $clock_time =
- $geom = DB::table("assign_hr_to_activity as ahta")->select("ma.geom", "ma.id")
- ->join("m_activity as ma", "ma.id", "=", "ahta.activity_id")
- ->where("ahta.user_id", $params->user_id)
- ->whereNotNull("ma.geom")
- ->whereDate("ma.start_date", "<=", $params->time)
- ->whereDate("ma.end_date", ">=", $params->time)
- ->get();
- $temp = [];
- if (count($geom) > 0) {
- foreach($geom as $dataGeom){
- $valGeom = json_decode($dataGeom->geom);
- if($params->clock_in_out['type']=="out"){
- $check = DB::select(DB::raw("SELECT ST_Intersects(ST_GeomFromGeoJSON('".json_encode($valGeom->geometry)."'), ST_GeomFromText('POINT(".$params->clock_in_out['clock_out_lng']." ".$params->clock_in_out['clock_out_lat'].")', 4326)) as boundary"));
- }else{
- $check = DB::select(DB::raw("SELECT ST_Intersects(ST_GeomFromGeoJSON('".json_encode($valGeom->geometry)."'), ST_GeomFromText('POINT(".$params->clock_in_out['clock_in_lng']." ".$params->clock_in_out['clock_in_lat'].")', 4326)) as boundary"));
- }
- foreach ($check as $key) {
- // assign and in boundary
- if($key->boundary){
- $temp[]=array(
- "activity_id" => $dataGeom->id,
- "boundary" => $key->boundary,
- "status_assign" => true
- );
- }
- }
- // assign and not in boundary
- if(count($temp) < 1){
- $temp[]=array(
- "activity_id" => null,
- "boundary" => false,
- "status_assign" => true
- // "geom" => $geom,
- // "cek" => $check[0]->boundary
- );
- }
- }
- }else{
- // not assign
- $temp[]=array(
- "activity_id" => null,
- "boundary" => false,
- "status_assign" => false
- );
- }
- return $temp;
- }
-
- public function edit($id){
- if(!$id || (int) $id < 0 || $id==""){
- return response()->json(['status'=>'failed','message'=>'id is required!','code'=>400], 400);
- die();
- }
-
- $result = Presence::find($id);
-
- if($result){
- return response()->json(['status'=>'success','code'=>200,'data'=>$result], 200);
- }else{
- return response()->json(['status'=>'failed','message'=>'failed get data project, please try again later!','code'=>400], 400);
- }
- }
-
- public function clockinout($id) {
- $dateTimeNow = Carbon::now()->addHour(7);
- $dataPresence = Presence::where('user_id', $id)->orderBy('id', 'DESC')->first();
-
- if($dataPresence){
-
- $dateNow = date("Y-m-d");
- $dateA = strtotime($dataPresence->clock_in);
- $dayClockin = date("Y-m-d", $dateA);
- if($dayClockin == $dateNow){
- $clock_in = $dataPresence->clock_in;
- $clock_out = $dataPresence->clock_out;
- }else{
- $clock_in = null;
- $clock_out = null;
- }
- $res_data = array(
- "id" => $dataPresence->id,
- "at" => $dateTimeNow,
- "user_id"=> $id,
- "clock_in"=> $clock_in,
- "clock_out"=> $clock_out,
- "last_clock_in"=> $dataPresence->clock_in,
- "last_clock_out"=> $dataPresence->clock_out,
- "in_working_time"=> true
- );
- return response()->json(['status'=>'success','data'=>$res_data,'code'=>200], 200);
- }
- $res_data = array(
- "id" => null,
- "at" => $dateTimeNow,
- "user_id"=> $id,
- "clock_in"=> null,
- "clock_out"=> null,
- "last_clock_in"=> null,
- "last_clock_out"=> null,
- "in_working_time"=> true
- );
- return response()->json(['status'=>'success','data'=>$res_data,'code'=>200], 200);
- }
-
- private function updateFormAdd($data, $id){
- $date = date_create($data['clock_out']);
- $onlyDate = date_format($date,"Y-m-d");
-
- $dataPresence = Presence::where('user_id',$id)
- ->where("clock_in", "<=", $data["clock_out"])
- ->orderByDesc("id")
- ->first();
-
- if($dataPresence){
- $queryUpdate = $dataPresence->update($data);
- if($queryUpdate){
- $getDataUpdate = Presence::where('user_id', $id)->where("date_presence", $onlyDate)->first();
- return $getDataUpdate->id;
- }else{
- return false;
- }
- }else{
- return false;
- }
- die();
- }
-
- public function update(Request $request, $id)
- {
- if(!$id || (int) $id < 0 || $id==""){
- return response()->json(['status'=>'failed','message'=>'id is required!','code'=>400], 400);
- }
-
- $data = Presence::find($id);
-
- if($data){
- $result = $data->update($request->all());
- }else{
- return response()->json(['status'=>'failed','message'=>'data presence not found!','code'=>400], 400);
- die();
- }
-
- if($result){
- return response()->json(['status'=>'success','message'=>'data presence successfully updated!','code'=>200], 200);
- }else{
- return response()->json(['status'=>'failed','message'=>'data presence failed updated!','code'=>400], 400);
- }
- }
-
- public function delete($id)
- {
- $data = Presence::find($id);
-
- if($data){
- $delete = $data->delete();
- }else{
- return response()->json(['status'=>'failed','message'=>'data presence not found!','code'=>400], 400);
- die();
- }
-
- if($delete){
- return response()->json(['status'=>'success','message'=>'data presence successfully deleted!','code'=>200], 200);
- }else{
- return response()->json(['status'=>'failed','message'=>'data presence failed deleted!','code'=>400], 400);
- }
- }
-
- public function search(Request $request)
- {
- $payload = $request->all();
- $dataBuilder = $this->setUpPayload($payload, 't_clock_in_out');
- $builder = $dataBuilder['builder'];
- $countBuilder = $dataBuilder['count'];
- $dataGet = $builder->get();
- $totalRecord = $countBuilder->count();
- return response()->json(['status'=>'success','code'=>200,'data'=>$dataGet, 'totalRecord'=>$totalRecord], 200);
- }
-
- public function list()
- {
- $data = Presence::all();
- $countData = $data->count();
-
- if($data){
- return response()->json(['status'=>'success','code'=>200,'data'=>$data, 'totalRecord'=>$countData], 200);
- }else{
- return response()->json(['status'=>'failed','message'=>'failed get list presence, please try again later!','code'=>400], 400);
- }
- }
-
- public function bulkUpdateLocation()
- {
- $data = Presence::all();
- $finalData = [];
- foreach($data as $objRow) {
- $presence = Presence::find($objRow->id);
-
- $clock_in_lat = $objRow->clock_in_lat;
- $clock_in_lng = $objRow->clock_in_lng;
- $objRow->clock_in_loc = "";
- if (isset($clock_in_lat) && isset($clock_in_lng)) {
- $objRow->clock_in_loc = $this->getLoc($clock_in_lat, $clock_in_lng)->display_name;
- }
-
- $clock_out_lat = $objRow->clock_out_lat;
- $clock_out_lng = $objRow->clock_out_lng;
- $objRow->clock_out_loc = "";
- if (isset($clock_out_lat) && isset($clock_out_lng) && $clock_out_lng != null) {
- $locAddress = $this->getLoc($clock_out_lat, $clock_out_lng);
- $objRow->clock_out_loc = isset($locAddress->display_name) ? $locAddress->display_name : "-";
- }
-
-
- $presence->clock_in_loc = $objRow->clock_in_loc;
- $presence->clock_out_loc = $objRow->clock_out_loc;
- $presence->save();
- }
- return response()->json(['status'=>'success','message'=>'success update!','code'=>200], 200);
- }
-}
+validate($request, [
+ 'user_id' => 'required'
+ ]);
+
+ $checkLocation = $this->checkLocation($request);
+ $statusBoundary = false;
+ $date = date_create($request->clock_time);
+ // assign and in boundary
+ if(count($checkLocation) > 0 && $checkLocation[0]['boundary']){
+ $statusBoundary = true;
+ }
+ $statusRestriction = HumanResource::select('status_boundary')->where('id', $request->user_id)->first();
+ if (!$statusRestriction->status_boundary) {
+ $statusBoundary = true;
+ }
+ // not assign
+ if(!$checkLocation[0]['status_assign'] && $checkLocation[0]['boundary'] == false && $statusBoundary == false){
+ $data=array(
+ 'id' => null,
+ 'boundary' => $statusBoundary
+ );
+ return response()->json(['status'=>'failed', 'data'=>$data, 'message'=>'Tidak dapat melakukan presensi. Anda belum di assign ke area kerja.','code'=>200], 200);
+ }
+ // assign and not in boundary
+ if($checkLocation[0]['status_assign'] && $checkLocation[0]['boundary'] == false && $statusBoundary == false){
+ $data=array(
+ 'id' => null,
+ 'boundary' => true
+ );
+ return response()->json(['status'=>'failed', 'data'=>$data, 'message'=>'Tidak dapat melakukan presensi. Anda berada di luar area kerja.','code'=>200], 200);
+ }
+
+ if($request->type=="out"){
+ $clock_out_loc = $this->getLoc($request->clock_out_lat, $request->clock_out_lng)->display_name;
+ $dataUpdate = array(
+ "clock_out"=>$request->clock_time,
+ "clock_out_lat" => $request->clock_out_lat,
+ "clock_out_lng" => $request->clock_out_lng,
+ "updated_by"=>$this->currentName,
+ "clock_out_loc" => $clock_out_loc,
+ "clock_out_boundary" => $statusBoundary
+ );
+
+ $resultUpdate = $this->updateFormAdd($dataUpdate, $request->user_id);
+ if($resultUpdate && $resultUpdate > 0){
+ if($statusBoundary){
+ for ($i=0; $i < count($checkLocation); $i++) {
+ # code...
+ DB::table('clock_in_out_boundary')->insert([
+ "clock_in_out_id" => $resultUpdate,
+ "user_id" => $request->user_id,
+ "activity_id" => $checkLocation[$i]['activity_id'] ? $checkLocation[$i]['activity_id'] : 0,
+ "type" => $request->type,
+ "created_at" => $date,
+ "created_by" => $this->currentName
+ ]);
+ };
+ };
+ $data=array(
+ 'id' => $resultUpdate,
+ 'boundary' => $statusBoundary
+ );
+
+ return response()->json(['status'=>'success', 'data'=>$data,'message'=>'clock out success!','code'=>200], 200);
+ }
+ else{
+ return response()->json(['status'=>'failed','message'=>'clock out failed please try again!','code'=>400], 400);
+ }
+ die();
+ }
+
+ $onlyDate = date_format($date,"Y-m-d");
+ // $clock_in_loc = $this->getLoc($request->clock_in_lat, $request->clock_in_lng)->display_name;
+ $clock_in_loc = "test";
+
+ $dataAdd = array(
+ 'user_id'=> $request->user_id,
+ 'clock_in'=> $request->clock_time,
+ 'date_presence'=> $onlyDate,
+ 'created_by' => $this->currentName,
+ 'clock_in_lat' => $request->clock_in_lat,
+ 'clock_in_lng' => $request->clock_in_lng,
+ 'clock_in_loc' => $clock_in_loc,
+ 'clock_in_boundary' => $statusBoundary
+ );
+
+ $result = Presence::create($dataAdd);
+ $data=array(
+ 'id' => $result->id,
+ 'boundary' => $statusBoundary
+ );
+ if($result){
+ if($statusBoundary){
+ for ($i=0; $i < count($checkLocation); $i++) {
+ # code...
+ DB::table('clock_in_out_boundary')->insert([
+ "clock_in_out_id" => $result->id,
+ "user_id" => $request->user_id,
+ "activity_id" => $checkLocation[$i]['activity_id'],
+ "type" => $request->type,
+ "created_at" => $date,
+ "created_by" => $this->currentName
+ ]);
+ };
+ };
+ return response()->json(['status'=>'success', 'data' => $data,'message'=>'clock in successfully!','code'=>200], 200);
+ }else{
+ return response()->json(['status'=>'failed','message'=>'clock in failed!','code'=>400], 400);
+ }
+ }
+
+ public function reportK3(Request $request){
+ // return response()->json(['status'=>'success', 'message'=>$request->report_k3['detail'],'code'=>200], 200);
+
+ $this->validate($request, [
+ 'user_id' => 'required'
+ ]);
+
+ $checkLocation = $this->checkLocation($request);
+ $statusBoundary = false;
+ $date = date_create($request->time);
+ // assign and in boundary
+ if(count($checkLocation) > 0 && $checkLocation[0]['boundary']){
+ $statusBoundary = true;
+ }
+ $statusRestriction = HumanResource::select('status_boundary')->where('id', $request->user_id)->first();
+ if (!$statusRestriction->status_boundary) {
+ $statusBoundary = true;
+ }
+ // not assign
+ if(!$checkLocation[0]['status_assign'] && $checkLocation[0]['boundary'] == false && $statusBoundary == false){
+ $data=array(
+ 'id' => null,
+ 'boundary' => $statusBoundary
+ );
+ return response()->json(['status'=>'failed', 'data'=>$data, 'message'=>'Tidak dapat melakukan presensi. Anda belum di assign ke area kerja.','code'=>200], 200);
+ }
+ // assign and not in boundary
+ if($checkLocation[0]['status_assign'] && $checkLocation[0]['boundary'] == false && $statusBoundary == false){
+ $data=array(
+ 'id' => null,
+ 'boundary' => true
+ );
+ return response()->json(['status'=>'failed', 'data'=>$data, 'message'=>'Tidak dapat melakukan presensi. Anda berada di luar area kerja.','code'=>200], 200);
+ }
+
+ if($request->clock_in_out['type']=="out"){
+ $clock_out_loc = $this->getLoc($request->clock_in_out['clock_out_lat'], $request->clock_in_out['clock_out_lng'])->display_name;
+ $dataUpdate = array(
+ "clock_out"=>$request->time,
+ "clock_out_lat" => $request->clock_in_out['clock_out_lat'],
+ "clock_out_lng" => $request->clock_in_out['clock_out_lng'],
+ "updated_by"=>$this->currentName,
+ "clock_out_loc" => $clock_out_loc,
+ "clock_out_boundary" => $statusBoundary
+ );
+
+ $resultUpdate = $this->updateFormAdd($dataUpdate, $request->user_id);
+ if($resultUpdate && $resultUpdate > 0){
+ if($statusBoundary){
+ for ($i=0; $i < count($checkLocation); $i++) {
+ # code...
+ DB::table('clock_in_out_boundary')->insert([
+ "clock_in_out_id" => $resultUpdate,
+ "user_id" => $request->user_id,
+ "activity_id" => $checkLocation[$i]['activity_id'] ? $checkLocation[$i]['activity_id'] : 0,
+ "type" => $request->clock_in_out['type'],
+ "created_at" => $date,
+ "created_by" => $this->currentName
+ ]);
+ };
+ };
+ $data=array(
+ 'presence_id' => $resultUpdate,
+ 'boundary' => $statusBoundary
+ );
+
+ return response()->json(['status'=>'success', 'data'=>$data,'message'=>'clock out success!','code'=>200], 200);
+ }
+ else{
+ return response()->json(['status'=>'failed','message'=>'clock out failed please try again!','code'=>400], 400);
+ }
+ die();
+ }
+
+ $onlyDate = date_format($date,"Y-m-d");
+ $clock_in_loc = $this->getLoc($request->clock_in_out['clock_in_lat'], $request->clock_in_out['clock_in_lng'])->display_name;
+
+ $dataFormK3 = array(
+ "user_id" => $request->user_id,
+ "proyek_id" => $request->report_k3['proyek_id'],
+ "report_date" => $request->time,
+ "description" => $request->report_k3['description']
+ );
+
+ $dataFormPresence = array(
+ 'user_id' => $request->user_id,
+ 'clock_in' => $request->time,
+ 'date_presence' => $onlyDate,
+ 'created_by' => $this->currentName,
+ 'clock_in_lat' => $request->clock_in_out['clock_in_lat'],
+ 'clock_in_lng' => $request->clock_in_out['clock_in_lng'],
+ 'clock_in_loc' => $clock_in_loc,
+ 'clock_in_boundary' => $statusBoundary
+ );
+
+ $result = Presence::create($dataFormPresence);
+ $data=array(
+ 'presence_id' => $result->id,
+ 'boundary' => $statusBoundary
+ );
+ if($result){
+ if($statusBoundary){
+ $insertk3 = $this->insertK3($dataFormK3, $request->report_k3['detail']) ;
+ for ($i=0; $i < count($checkLocation); $i++) {
+ # code...
+ DB::table('clock_in_out_boundary')->insert([
+ "clock_in_out_id" => $result->id,
+ "user_id" => $request->user_id,
+ "activity_id" => $checkLocation[$i]['activity_id'] ? $checkLocation[$i]['activity_id'] : 0,
+ "type" => $request->type,
+ "created_at" => $date,
+ "created_by" => $this->currentName
+ ]);
+ };
+ $data['report_id'] = $insertk3->id;
+ };
+ return response()->json(['status'=>'success', 'data'=> $data, 'message'=>'clock in successfully!','code'=>200], 200);
+ }else{
+ return response()->json(['status'=>'failed','message'=>'clock in failed!','code'=>400], 400);
+ }
+ }
+
+ private function insertK3($params, $details){
+ $insert = ReportK3::create($params);
+ if($insert && $details){
+ $this->addDetailK3($details, $insert->id);
+ }
+ return $insert;
+ }
+
+ private function checkLocation($params){
+ // cek user tersebut apakah punya assign task yang ada bondary nya
+ // geom ada di table activity
+ // $clock_time =
+ $user = HumanResource::find($params->user_id);
+ $geomQuery = DB::table("assign_hr_to_activity as ahta")->select("ma.geom", "ma.id")
+ ->join("m_activity as ma", "ma.id", "=", "ahta.activity_id")
+ ->where("ahta.user_id", $params->user_id)
+ ->whereNotNull("ma.geom")
+ ->whereDate("ma.start_date", "<=", $params->time)
+ ->whereDate("ma.end_date", ">=", $params->time);
+ if (isset($params->report_k3['proyek_id'])) {
+ $geom = $geomQuery->where("ma.proyek_id", $params->report_k3['proyek_id'])->get();
+ } else {
+ $geom = $geomQuery->get();
+ }
+ $temp = [];
+ if (count($geom) > 0) {
+ foreach($geom as $dataGeom){
+ $valGeom = json_decode($dataGeom->geom);
+ if($params->clock_in_out['type']=="out"){
+ if($valGeom->type == "FeatureCollection"){
+ $multiArea = $valGeom->features;
+ foreach($multiArea as $area){
+ if ($area->geometry->type === "Point") {
+ $pointCoordinates = $area->geometry->coordinates;
+ $pointLng = $pointCoordinates[0];
+ $pointLat = $pointCoordinates[1];
+
+ $check = DB::select(DB::raw("SELECT ST_Distance(
+ ST_GeomFromGeoJSON('" . json_encode($area->geometry) . "'),
+ ST_GeomFromText('POINT(" . $params->clock_in_out['clock_in_lng'] . " " . $params->clock_in_out['clock_in_lat'] . ")', 4326)
+ ) <= " . $area->properties->radius . " as within_radius"));
+
+ if ($check[0]->within_radius) {
+ break;
+ }
+ }
+ $check = DB::select(DB::raw("SELECT ST_Intersects(ST_GeomFromGeoJSON('".json_encode($area->geometry)."'),
+ ST_GeomFromText('POINT(".$params->clock_in_out['clock_out_lng']." ".$params->clock_in_out['clock_out_lat'].")', 4326)) as boundary"));
+ if($check[0]->boundary){
+ break;
+ }
+ }
+ }else{
+ $check = DB::select(DB::raw("SELECT ST_Intersects(ST_GeomFromGeoJSON('".json_encode($valGeom->geometry)."'),
+ ST_GeomFromText('POINT(".$params->clock_in_out['clock_out_lng']." ".$params->clock_in_out['clock_out_lat'].")', 4326)) as boundary"));
+ }
+ }else{
+ if($valGeom->type == "FeatureCollection"){
+ $multiArea = $valGeom->features;
+ foreach($multiArea as $area){
+ if ($area->geometry->type === "Point") {
+ $pointCoordinates = $area->geometry->coordinates;
+ $pointLng = $pointCoordinates[0];
+ $pointLat = $pointCoordinates[1];
+
+ $check = DB::select(DB::raw("SELECT ST_Distance(
+ ST_GeomFromGeoJSON('" . json_encode($area->geometry) . "'),
+ ST_GeomFromText('POINT(" . $params->clock_in_out['clock_in_lng'] . " " . $params->clock_in_out['clock_in_lat'] . ")', 4326)
+ ) <= " . $area->properties->radius . " as within_radius"));
+
+ if ($check[0]->within_radius) {
+ break;
+ }
+ }
+ $check = DB::select(DB::raw("SELECT ST_Intersects(ST_GeomFromGeoJSON('".json_encode($area->geometry)."'),
+ ST_GeomFromText('POINT(".$params->clock_in_out['clock_in_lng']." ".$params->clock_in_out['clock_in_lat'].")', 4326)) as boundary"));
+ if($check[0]->boundary){
+ break;
+ }
+ }
+ }else{
+ $check = DB::select(DB::raw("SELECT ST_Intersects(ST_GeomFromGeoJSON('".json_encode($valGeom->geometry)."'),
+ ST_GeomFromText('POINT(".$params->clock_in_out['clock_in_lng']." ".$params->clock_in_out['clock_in_lat'].")', 4326)) as boundary"));
+ }
+ }
+ if(!$user->status_boundary || count($check)>0){
+ if(!$user->status_boundary || (isset($check[0]->boundary) && $check[0]->boundary)){
+ $temp[]=array(
+ "activity_id" => $dataGeom->id,
+ "boundary" => $check[0]->boundary,
+ "status_assign" => true
+ );
+ } else if (!$user->status_boundary || (isset($check[0]->within_radius) && $check[0]->within_radius)) {
+ $temp[]=array(
+ "activity_id" => $dataGeom->id,
+ "boundary" => $check[0]->within_radius,
+ "status_assign" => true
+ );
+ }
+ } else {
+ // bypass work area restriction
+ $temp[]=array(
+ "activity_id" => null,
+ "boundary" => true,
+ "status_assign" => true
+ );
+ }
+ }
+ // assign and not in boundary
+ if(count($temp) < 1){
+ $temp[]=array(
+ "activity_id" => null,
+ "boundary" => false,
+ "status_assign" => true
+ // "geom" => $geom,
+ // "cek" => $check[0]->boundary
+ );
+ }
+ }
+ else{
+ if ($user->status_boundary) {
+ // bypass work area restriction
+ $temp[]=array(
+ "activity_id" => null,
+ "boundary" => true,
+ "status_assign" => true
+ );
+ } else {
+ // not assign
+ $temp[]=array(
+ "activity_id" => null,
+ "boundary" => false,
+ "status_assign" => false
+ );
+ }
+ }
+ return $temp;
+ }
+
+ public function checkLocationTest(Request $request){
+ // cek user tersebut apakah punya assign task yang ada bondary nya
+ // geom ada di table activity
+ // $clock_time =
+ $params = $request;
+ $geom = DB::table("assign_hr_to_activity as ahta")->select("ma.geom", "ma.id")
+ ->join("m_activity as ma", "ma.id", "=", "ahta.activity_id")
+ ->where("ahta.user_id", $params->user_id)
+ ->whereNotNull("ma.geom")
+ ->whereDate("ma.start_date", "<=", $params->time)
+ ->whereDate("ma.end_date", ">=", $params->time)
+ ->get();
+ $temp = [];
+ // return json_encode($geom);
+ if (count($geom) > 0) {
+ foreach($geom as $dataGeom){
+ $valGeom = json_decode($dataGeom->geom);
+ if($params->clock_in_out['type']=="out"){
+ if($valGeom->type == "FeatureCollection"){
+ // return count($valGeom->features);
+ $multiArea = $valGeom->features;
+ foreach($multiArea as $area){
+ $check = DB::select(DB::raw("SELECT ST_Intersects(ST_GeomFromGeoJSON('".json_encode($area->geometry)."'),
+ ST_GeomFromText('POINT(".$params->clock_in_out['clock_out_lng']." ".$params->clock_in_out['clock_out_lat'].")', 4326)) as boundary"));
+ if($check[0]->boundary){
+ break;
+ }
+ }
+ }else{
+ $check = DB::select(DB::raw("SELECT ST_Intersects(ST_GeomFromGeoJSON('".json_encode($valGeom->geometry)."'),
+ ST_GeomFromText('POINT(".$params->clock_in_out['clock_out_lng']." ".$params->clock_in_out['clock_out_lat'].")', 4326)) as boundary"));
+ }
+ }else{
+ if($valGeom->type == "FeatureCollection"){
+ // return count($valGeom->features);
+ $multiArea = $valGeom->features;
+ foreach($multiArea as $area){
+ $check = DB::select(DB::raw("SELECT ST_Intersects(ST_GeomFromGeoJSON('".json_encode($area->geometry)."'),
+ ST_GeomFromText('POINT(".$params->clock_in_out['clock_in_lng']." ".$params->clock_in_out['clock_in_lat'].")', 4326)) as boundary"));
+ if($check[0]->boundary){
+ break;
+ }
+ }
+ }else{
+ $check = DB::select(DB::raw("SELECT ST_Intersects(ST_GeomFromGeoJSON('".json_encode($valGeom->geometry)."'),
+ ST_GeomFromText('POINT(".$params->clock_in_out['clock_in_lng']." ".$params->clock_in_out['clock_in_lat'].")', 4326)) as boundary"));
+ }
+ }
+ if(count($check)>0){
+ if($check[0]->boundary){
+ $temp[]=array(
+ "activity_id" => $dataGeom->id,
+ "boundary" => $check[0]->boundary,
+ "status_assign" => true
+ );
+ }
+ }
+ }
+ // assign and not in boundary
+ if(count($temp) < 1){
+ $temp[]=array(
+ "activity_id" => null,
+ "boundary" => false,
+ "status_assign" => true
+ // "geom" => $geom,
+ // "cek" => $check[0]->boundary
+ );
+ }
+ }
+ else{
+ // not assign
+ $temp[]=array(
+ "activity_id" => null,
+ "boundary" => false,
+ "status_assign" => false
+ );
+ }
+ return $temp;
+ }
+
+ public function edit($id){
+ if(!$id || (int) $id < 0 || $id==""){
+ return response()->json(['status'=>'failed','message'=>'id is required!','code'=>400], 400);
+ die();
+ }
+
+ $result = Presence::find($id);
+
+ if($result){
+ return response()->json(['status'=>'success','code'=>200,'data'=>$result], 200);
+ }else{
+ return response()->json(['status'=>'failed','message'=>'failed get data project, please try again later!','code'=>400], 400);
+ }
+ }
+
+ public function clockinout($id) {
+ $dateTimeNow = Carbon::now()->addHour(7);
+ $dataPresence = Presence::where('user_id', $id)->orderBy('id', 'DESC')->first();
+
+ if($dataPresence){
+
+ $dateNow = date("Y-m-d");
+ $dateA = strtotime($dataPresence->clock_in);
+ $dayClockin = date("Y-m-d", $dateA);
+ if($dayClockin == $dateNow){
+ $clock_in = $dataPresence->clock_in;
+ $clock_out = $dataPresence->clock_out;
+ }else{
+ $clock_in = null;
+ $clock_out = null;
+ }
+ $res_data = array(
+ "id" => $dataPresence->id,
+ "at" => $dateTimeNow,
+ "user_id"=> $id,
+ "clock_in"=> $clock_in,
+ "clock_out"=> $clock_out,
+ "last_clock_in"=> $dataPresence->clock_in,
+ "last_clock_out"=> $dataPresence->clock_out,
+ "in_working_time"=> true
+ );
+ return response()->json(['status'=>'success','data'=>$res_data,'code'=>200], 200);
+ }
+ $res_data = array(
+ "id" => null,
+ "at" => $dateTimeNow,
+ "user_id"=> $id,
+ "clock_in"=> null,
+ "clock_out"=> null,
+ "last_clock_in"=> null,
+ "last_clock_out"=> null,
+ "in_working_time"=> true
+ );
+ return response()->json(['status'=>'success','data'=>$res_data,'code'=>200], 200);
+ }
+
+ private function updateFormAdd($data, $id){
+ $date = date_create($data['clock_out']);
+ $onlyDate = date_format($date,"Y-m-d");
+
+ $dataPresence = Presence::where('user_id',$id)
+ ->where("clock_in", "<=", $data["clock_out"])
+ ->orderByDesc("id")
+ ->first();
+
+ if($dataPresence){
+ $queryUpdate = $dataPresence->update($data);
+ if($queryUpdate){
+ $getDataUpdate = Presence::where('user_id', $id)->where("date_presence", $onlyDate)->first();
+ return $getDataUpdate->id;
+ }else{
+ return false;
+ }
+ }else{
+ return false;
+ }
+ die();
+ }
+
+ public function update(Request $request, $id)
+ {
+ if(!$id || (int) $id < 0 || $id==""){
+ return response()->json(['status'=>'failed','message'=>'id is required!','code'=>400], 400);
+ }
+
+ $data = Presence::find($id);
+
+ if($data){
+ $result = $data->update($request->all());
+ }else{
+ return response()->json(['status'=>'failed','message'=>'data presence not found!','code'=>400], 400);
+ die();
+ }
+
+ if($result){
+ return response()->json(['status'=>'success','message'=>'data presence successfully updated!','code'=>200], 200);
+ }else{
+ return response()->json(['status'=>'failed','message'=>'data presence failed updated!','code'=>400], 400);
+ }
+ }
+
+ public function delete($id)
+ {
+ $data = Presence::find($id);
+
+ if($data){
+ $delete = $data->delete();
+ }else{
+ return response()->json(['status'=>'failed','message'=>'data presence not found!','code'=>400], 400);
+ die();
+ }
+
+ if($delete){
+ return response()->json(['status'=>'success','message'=>'data presence successfully deleted!','code'=>200], 200);
+ }else{
+ return response()->json(['status'=>'failed','message'=>'data presence failed deleted!','code'=>400], 400);
+ }
+ }
+
+ public function search(Request $request)
+ {
+ $payload = $request->all();
+ $dataBuilder = $this->setUpPayload($payload, 't_clock_in_out');
+ $builder = $dataBuilder['builder'];
+ $countBuilder = $dataBuilder['count'];
+ $dataGet = $builder->get();
+ $totalRecord = $countBuilder->count();
+ return response()->json(['status'=>'success','code'=>200,'data'=>$dataGet, 'totalRecord'=>$totalRecord], 200);
+ }
+
+ public function list()
+ {
+ $data = Presence::all();
+ $countData = $data->count();
+
+ if($data){
+ return response()->json(['status'=>'success','code'=>200,'data'=>$data, 'totalRecord'=>$countData], 200);
+ }else{
+ return response()->json(['status'=>'failed','message'=>'failed get list presence, please try again later!','code'=>400], 400);
+ }
+ }
+
+ public function bulkUpdateLocation()
+ {
+ $data = Presence::all();
+ $finalData = [];
+ foreach($data as $objRow) {
+ $presence = Presence::find($objRow->id);
+
+ $clock_in_lat = $objRow->clock_in_lat;
+ $clock_in_lng = $objRow->clock_in_lng;
+ $objRow->clock_in_loc = "";
+ if (isset($clock_in_lat) && isset($clock_in_lng)) {
+ $objRow->clock_in_loc = $this->getLoc($clock_in_lat, $clock_in_lng)->display_name;
+ }
+
+ $clock_out_lat = $objRow->clock_out_lat;
+ $clock_out_lng = $objRow->clock_out_lng;
+ $objRow->clock_out_loc = "";
+ if (isset($clock_out_lat) && isset($clock_out_lng) && $clock_out_lng != null) {
+ $locAddress = $this->getLoc($clock_out_lat, $clock_out_lng);
+ $objRow->clock_out_loc = isset($locAddress->display_name) ? $locAddress->display_name : "-";
+ }
+
+
+ $presence->clock_in_loc = $objRow->clock_in_loc;
+ $presence->clock_out_loc = $objRow->clock_out_loc;
+ $presence->save();
+ }
+ return response()->json(['status'=>'success','message'=>'success update!','code'=>200], 200);
+ }
+}
diff --git a/app/Http/Controllers/ProjectChecklistsController.php b/app/Http/Controllers/ProjectChecklistsController.php
new file mode 100644
index 0000000..c7e0590
--- /dev/null
+++ b/app/Http/Controllers/ProjectChecklistsController.php
@@ -0,0 +1,136 @@
+status_exist==="") {
+ $request->merge(['status_exist' => true]);
+ }
+
+ $this->validate($request, [
+ 'proyek_id' => 'required',
+ 'item' => 'required|string',
+ 'status_exist' => 'boolean'
+ ]);
+
+ $data = $request->all();
+
+ $data['created_by'] = $this->currentName;
+
+ $result = ProjectChecklists::create($data);
+
+ if($result){
+ return response()->json(['status'=>'success','message'=>'add data project participants successfully!','code'=>200], 200);
+ }else{
+ return response()->json(['status'=>'failed','message'=>'add data project participants failed!','code'=>400], 400);
+ }
+ }
+
+ public function edit($id){
+ if(!$id || (int) $id < 0 || $id==""){
+ return response()->json(['status'=>'failed','message'=>'id is required!','code'=>400], 400);
+ die();
+ }
+
+ $result = ProjectChecklists::find($id);
+
+ if($result){
+ return response()->json(['status'=>'success','code'=>200,'data'=>$result], 200);
+ }else{
+ return response()->json(['status'=>'failed','message'=>'failed get data project participants, please try again later!','code'=>400], 400);
+ }
+ }
+
+ public function update(Request $request, $id)
+ {
+ if(!$id || (int) $id < 0 || $id==""){
+ return response()->json(['status'=>'failed','message'=>'id is required!','code'=>400], 400);
+ }
+
+ $data = ProjectChecklists::find($id);
+
+ if($data){
+ $result = $data->update($request->all());
+ }else{
+ return response()->json(['status'=>'failed','message'=>'data project participants not found!','code'=>400], 400);
+ die();
+ }
+
+
+ if($result){
+ return response()->json(['status'=>'success','message'=>'data project participants successfully updated!','code'=>200], 200);
+ }else{
+ return response()->json(['status'=>'failed','message'=>'data project participants failed updated!','code'=>400], 400);
+ }
+ }
+
+ public function delete($id)
+ {
+ $data = ProjectChecklists::find($id);
+
+ if($data){
+ $delete = $data->delete();
+ }else{
+ return response()->json(['status'=>'failed','message'=>'data project participants not found!','code'=>400], 400);
+ die();
+ }
+
+
+ if($delete){
+ return response()->json(['status'=>'success','message'=>'data project participants successfully deleted!','code'=>200], 200);
+ }else{
+ return response()->json(['status'=>'failed','message'=>'data project participants failed deleted!','code'=>400], 400);
+ }
+ }
+
+ public function deleteByProyek($id)
+ {
+ $data = ProjectChecklists::where('proyek_id', $id)->delete();
+
+ if($data){
+ return response()->json(['status'=>'success','message'=>'data project participants successfully deleted!','code'=>200], 200);
+ }else{
+ return response()->json(['status'=>'success','message'=>'data project participants failed deleted, because data not found!','code'=>200], 200);
+ }
+ }
+
+ public function customWhere($where, $val)
+ {
+ $data = ProjectChecklists::where($where, $val)->orderBy('id', 'asc')->get();
+
+ if($data){
+ return response()->json(['status'=>'success','data'=> $data,'code'=>200], 200);
+ }else{
+ return response()->json(['status'=>'success','message'=>'data project participants not found!','code'=>400], 40);
+ }
+ }
+
+ public function search(Request $request)
+ {
+ $payload = $request->all();
+ $dataBuilder = $this->setUpPayload($payload, 'project_charter_checklist');
+ $builder = $dataBuilder['builder'];
+ $countBuilder = $dataBuilder['count'];
+ $dataGet = $builder->get();
+ $totalRecord = $countBuilder->count();
+ return response()->json(['status'=>'success','code'=>200,'data'=>$dataGet, 'totalRecord'=>$totalRecord], 200);
+ }
+
+ public function list()
+ {
+ $data = ProjectChecklists::all();
+ $countData = $data->count();
+
+ if($data){
+ return response()->json(['status'=>'success','code'=>200,'data'=>$data, 'totalRecord'=>$countData], 200);
+ }else{
+ return response()->json(['status'=>'failed','message'=>'failed get list project participants, please try again later!','code'=>400], 400);
+ }
+ }
+}
diff --git a/app/Http/Controllers/ProjectController.php b/app/Http/Controllers/ProjectController.php
index 32b8b38..a535093 100644
--- a/app/Http/Controllers/ProjectController.php
+++ b/app/Http/Controllers/ProjectController.php
@@ -2,33 +2,39 @@
namespace App\Http\Controllers;
-use Illuminate\Http\Request;
+use DateTime;
+use App\Models\Link;
+use App\Models\User;
+use App\Models\Image;
+use App\Models\Holiday;
use App\Models\Project;
-use App\Models\UserToProyek;
use App\Models\Activity;
-use App\Models\UserToActivity;
-use App\Models\User;
+use App\Jobs\ProcessSCurve;
+use App\Models\OfficeHours;
+use App\Models\ProjectType;
+use App\Models\ProjectPhase;
+use App\Models\UserToProyek;
+use App\Models\VersionGantt;
+use Illuminate\Http\Request;
+use App\Models\ProjectIssues;
use App\Models\AssignMaterial;
use App\Models\DokumenProject;
-use App\Models\FolderDocumentProyek;
use App\Models\ProjectCharter;
-use App\Models\ProjectApproval;
-use App\Models\ProjectPhase;
-use App\Models\ProjectType;
-use App\Models\ProjectMileStone;
-use App\Models\ProjectParticipants;
+use App\Models\ReportActivity;
use App\Models\ShowHideColumn;
-use App\Models\VersionGantt;
-use App\Models\Image;
-use App\Models\CommentActivity;
-use App\Models\Link;
+use App\Models\UserToActivity;
use App\Models\ActivityDokumen;
-use App\Models\Holiday;
-use App\Models\ReportActivity;
-use App\Models\OfficeHours;
+use App\Models\CommentActivity;
+use App\Models\ProjectApproval;
+use App\Models\ProjectMileStone;
+use App\Models\ProjectChecklists;
use Illuminate\Support\Facades\DB;
+use App\Models\ProjectParticipants;
+use App\Models\FolderDocumentProyek;
use App\Helpers\MasterFunctionsHelper;
+use App\Models\ProjectRisks;
use App\Models\ReportActivityMaterial;
+use Illuminate\Support\Facades\Artisan;
const API_GEOLOCATION = "https://nominatim.oslogdev.com/search/ADDR?format=json&addressdetails=1&limit=1";
@@ -63,11 +69,22 @@ class ProjectController extends Controller
return response()->json(['status'=>'success','message'=>'Data added!', 'data_result' =>$dataResultInsert, 'code'=> 200], 200);
}
- public function edit($id){
- if(empty($id) || !is_int((int)$id))
- return response()->json(['status'=>'failed','message'=>'id is required!','code'=>400], 400);
+ public function edit($id)
+ {
+ if (empty($id) || !is_int((int)$id))
+ return response()->json(['status' => 'failed', 'message' => 'id is required!', 'code' => 400], 400);
- $result = Project::find($id);
+ $result = Project::query()
+ ->from('m_proyek AS mp')
+ ->where('mp.id', $id)
+ ->selectRaw('value_proyek,scoupe_of_work,kode_sortname,jumlah_stakeholder,nama,mulai_proyek,akhir_proyek,area_kerja,rencana_biaya,biaya_actual,company,pm_id,type_proyek_id,divisi_id,persentase_progress,keterangan,durasi_proyek,progress_by_worklog,currency_symbol,late_consequence,assumtion,currency_code,currency_name,project_objectives,considered_success_when,potential_risk,testing_environment,budget_health,phase_id,calculation_status');
+
+ if (!is_null($result->first()['divisi_id'])) {
+ $result->leftJoin('m_divisi', 'mp.divisi_id', '=', 'm_divisi.id')
+ ->addSelect(DB::raw('m_divisi.name AS nama_divisi'));
+ }
+
+ $result = $result->first();
if(!$result)
return response()->json(['status'=>'failed','message'=> 'Data not found!','code'=> 404], 404);
@@ -143,6 +160,9 @@ class ProjectController extends Controller
ProjectApproval::where('proyek_id', $project_id)->delete();
ProjectMileStone::where('proyek_id', $project_id)->delete();
ProjectParticipants::where('proyek_id', $project_id)->delete();
+ ProjectChecklists::where('proyek_id', $project_id)->delete();
+ ProjectIssues::where('proyek_id', $project_id)->delete();
+ ProjectRisks::where('proyek_id', $project_id)->delete();
$this->deleteVersionGantt($project_id);
$this->deleteDokumenProject($project_id);
}
@@ -217,64 +237,53 @@ class ProjectController extends Controller
public function list()
{
- $data = Project::orderBy('id', 'desc')->get();
+ $data = Project::select(
+ 'id',
+ 'kode_sortname',
+ 'jumlah_stakeholder',
+ 'nama',
+ 'mulai_proyek',
+ 'akhir_proyek',
+ 'area_kerja',
+ 'lokasi_kantor',
+ 'rencana_biaya',
+ 'biaya_actual',
+ 'company',
+ 'pm_id',
+ 'type_proyek_id',
+ 'divisi_id',
+ 'persentase_progress',
+ 'keterangan',
+ 'durasi_proyek',
+ 'progress_by_worklog',
+ 'status',
+ 'currency_symbol',
+ 'currency_code',
+ 'currency_name',
+ 'project_objectives',
+ 'considered_success_when',
+ 'potential_risk',
+ 'testing_environment',
+ 'currency_code',
+ 'currency_symbol',
+ 'currency_name',
+ 'budget_health',
+ 'phase_id',
+ 'calculation_status',
+ 'created_at',
+ 'created_by',
+ 'updated_at',
+ 'updated_by'
+ )->orderBy('id', 'desc')->get();
$countData = $data->count();
if(!$data)
return response()->json(['status'=>'failed','message'=>'Data not found!','code'=> 404], 404);
- $scheduleWarningThreshold = 10;
- $scheduleDangerThreshold = 5;
- foreach($data as $d){
- $progress = $costVariance = $actualCost = 0;
- $lastActivity = null;
- $scheduleHealth = "on-track";
- $rootActivity = Activity::whereNull('parent_id')->where('proyek_id', $d->id)->orderBy('version_gantt_id', 'desc')->first();
- if($rootActivity){
- $costVariance = (int)$d->rencana_biaya - (int)$rootActivity->biaya_actual;
- $actualCost = $rootActivity->biaya_actual ?? 0;
- $progress = $rootActivity->persentase_progress ?? 0;
-
- $timeleft = strtotime($d->mulai_proyek) - strtotime($rootActivity->end_date);
- $date1 = new \DateTime(date("Y-m-d", strtotime($d->mulai_proyek)));
- $date2 = new \DateTime(date("Y-m-d", strtotime($rootActivity->end_date)));
- $daysRemaining = $date2->diff($date1);
- $daysRemaining = $daysRemaining->d;
-
- if($daysRemaining <= $scheduleDangerThreshold) {
- $scheduleHealth = "danger";
- } elseif ($daysRemaining <= $scheduleWarningThreshold) {
- $scheduleHealth = "warning";
- }
- $lastActivity = date("d/m/Y", strtotime($rootActivity->end_date));
- }
- $d->plannedInterval = date("d/m/Y", strtotime($d->mulai_proyek)) . " - " . date("d/m/Y", strtotime($d->akhir_proyek));
- $d->plannedCost = $d->rencana_biaya;
- $d->actualCost = $actualCost;
- $d->lastActivity = $lastActivity ?? "-";
- $d->costVariance = $costVariance;
- $d->costHealth = $d->budget_health;
- $d->scheduleHealth = $scheduleHealth;
- $d->progress = $progress;
- $d->lastGanttId = VersionGantt::where("proyek_id", $d->id)->orderBy('id', 'desc')->first()->id ?? null;
- $d->manpower = UserToProyek::where("proyek_id", $d->id)->count() ?? 0;
- $d->projectManager = DB::table('m_proyek')
- ->join('m_users', 'm_users.id', '=', 'm_proyek.pm_id')
- ->where('m_proyek.id', $d->id)
- ->pluck('m_users.name')
- ->first();
- if($d->area_kerja != ''){
- $d->geolocation = $this->httpReq($d->area_kerja);
- $d->geolocation = [];
- } else {
- $d->geolocation = [];
- }
- }
-
$totalPlannedCost = array_sum(array_map('intval', array_column($data->toArray(), 'plannedCost')));
$totalActualCost = $data->sum('actualCost');
$manpowers = User::count();
- $projectsOnDanger = Project::where('budget_health', 'danger')->count();
+ $projectsOnDanger = Project::where('budget_health', 'overrun')->count();
$projectPhases = ProjectPhase::orderBy('order', 'asc')->pluck('name');
$projectTypes = ProjectType::orderBy('id', 'asc')->pluck('name');
try {
@@ -288,7 +297,7 @@ class ProjectController extends Controller
}
try {
$projectsByType = DB::table('m_proyek')
- ->select('m_type_proyek.name', DB::raw('count(*) as total'))
+ ->select('m_type_proyek.name', DB::raw('count(m_type_proyek.id) as total'))
->join('m_type_proyek', 'm_type_proyek.id', '=', 'm_proyek.type_proyek_id')
->groupBy('m_type_proyek.name')
->get();
@@ -330,6 +339,63 @@ class ProjectController extends Controller
public function getSCurve(Request $request){
$data = MasterFunctionsHelper::getSCurve($request);
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);
+ }
+
+ public function sCurveCommand(Request $request){
+ Artisan::call('calculate:scurve', [
+ 'project_id' => $request->project_id
+ ]);
+ // $project = Project::find($request->project_id);
+
+ // if ($project) {
+ // dispatch(new ProcessSCurve($project));
+
+ // return response()->json(['message' => 'S Curve calculation queued']);
+ // }
+
+ // return response()->json(['message' => 'Project not found'], 404);
+ }
+
+ public function getLinearSCurve(Request $request){
+ $data = MasterFunctionsHelper::getLinearSCurve($request);
+ return response()->json(['status'=>'success','code'=>200, 'data' => $data], 200);
+ }
+
+ public static function setSyncDate($activity_id, $activity, $report) {
+ $status = AssignMaterial::where('activity_id', $activity_id)->first();
+ if (!isset($status)) {
+ $reports = array(
+ 'activity_id' => $activity_id,
+ 'min_date' => new DateTime($activity->start_date),
+ 'max_date' => new DateTime($activity->end_date),
+ 'status' => 'open'
+ );
+ return $reports;
+ }
+ if (!isset($status->status_activity)) {
+ $status->status_activity = 'open';
+ }
+ if ($status->status_activity != 'done') {
+ $minDate = date_create($report->report_date);
+ $maxDate = date_create($report->report_date);
+ date_add($maxDate, date_interval_create_from_date_string($activity->duration . " days"));
+ } else {
+ $material = AssignMaterial::where('activity_id', $activity_id)->first();
+ $minDate = date_create($material->start_activity);
+ $maxDate = date_create($material->finish_activity);
+ }
+ $reports = array(
+ 'activity_id' => $activity_id,
+ 'min_date' => $minDate,
+ 'max_date' => $maxDate,
+ 'status' => $status->status_activity
+ );
+ return $reports;
}
public function synchronizeReport($gantt_id)
@@ -343,31 +409,40 @@ class ProjectController extends Controller
if ($countReports === 1) {
$dataReports = ReportActivityMaterial::where('activity_id', $activity_id)->orderBy('report_date')->get();
foreach($dataReports as $dr) {
- $reports[] = array(
- 'activity_id'=>$activity_id,
- 'min_date'=>$dr->report_date,
- 'max_date'=>date_modify(date_create($dr->report_date), "1 days")
- );
+ $reports[] = ProjectController::setSyncDate($activity_id, $activity, $dr);
}
}
if ($countReports > 1) {
$firstReport = ReportActivityMaterial::where('activity_id', $activity_id)->orderBy('report_date')->first();
- $lastReport = ReportActivityMaterial::where('activity_id', $activity_id)->orderByDesc('report_date')->first();
- $reports[] = array(
- 'activity_id'=>$activity_id,
- 'min_date'=>$firstReport->report_date,
- 'max_date'=>date_modify(date_create($lastReport->report_date), "1 days")
- );
+ $reports[] = ProjectController::setSyncDate($activity_id, $activity, $firstReport);
+ }
+ $successor = Link::where('t_activity_id', $activity->id)->first();
+ if ($successor) {
+ $predecessor = Activity::find($successor->s_activity_id);
+ $activity->start_date = $predecessor->end_date;
+ $end_date = new DateTime($activity->start_date);
+ $end_date->modify("+" . $activity->duration . " days");
+ $activity->end_date = $end_date->format("Y-m-d H:i:sO");
}
- $activity->reports = $reports;
+ $activity->save();
}
/* return response()->json(['status'=>'success','data'=> $reports,'code'=>200], 200); */
/* return response()->json(['status'=>'success','data'=> $activities,'code'=>200], 200); */
for ($i=0; $i < count($reports); $i++) {
$activity = Activity::find($reports[$i]['activity_id']);
- $activity->start_date = $reports[$i]['min_date'];
- $activity->end_date = $reports[$i]['max_date'];
+ if($reports[$i]['status'] != 'done'){
+ $reports[$i]['max_date']->modify('-1 day');
+ }else if($reports[$i]['status'] == 'done'){
+ $activity->actual_end = $reports[$i]['max_date']->setTime(23,59,59);
+ }
+ $activity->start_date = $reports[$i]['min_date']; //same early
+ $activity->end_date = $reports[$i]['max_date']->setTime(23,59,59); // same early
+ $startDate = new DateTime($activity->start_date);
+ $endDate = new DateTime($activity->end_date);
+ $duration = MasterFunctionsHelper::countDays($activity->version_gantt_id, $startDate, $endDate);
+ $activity->duration = $duration;
+ $activity->actual_start = $reports[$i]['min_date'];
$activity->save();
}
@@ -382,6 +457,8 @@ class ProjectController extends Controller
$activity->update([
"planned_start"=>$activity->start_date,
"planned_end"=>$activity->end_date,
+ "early_start"=>$activity->start_date,
+ "early_end"=>$activity->end_date,
]);
}
@@ -389,18 +466,38 @@ class ProjectController extends Controller
}
public function getInvoiceIntegration(Request $request) {
- // $search = urlencode($request->search);
- // 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');
-
- $response = null;
-
+ $ganttCount = VersionGantt::where('proyek_id', $request->id)->count();
+ $search = urlencode($request->search);
+ 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');
+
+ $response = MasterFunctionsHelper::curlReq($url);
+ if (isset($request->gantt_id)) {
+ $response->data->total_cost = $response->data->total_cost / $ganttCount;
+ }
return response()->json(['status'=>'success', 'data'=> $response, 'code'=>200], 200);
}
-
- public function detail($id){
+ public function getByUser($id)
+ {
+ $alias = "utp";
+ $userProyek = UserToProyek::query()
+ ->from('assign_hr_to_proyek AS ' . $alias)
+ ->where([
+ ['is_customer', true],
+ ['user_id', $id]
+ ])
+ ->leftJoin('m_users', $alias.'.user_id', '=', 'm_users.id')
+ ->leftJoin('m_proyek', $alias.'.proyek_id', '=', 'm_proyek.id')
+ ->leftJoin('m_type_proyek', 'm_proyek.type_proyek_id', '=', 'm_type_proyek.id')
+ ->select('m_proyek.*', 'm_type_proyek.name AS join_second_name','m_users.name AS join_first_name')
+ ->get();
+ $totalRecord = $userProyek->count();
+
+ return response()->json(['status' => 'success', 'code' => 200, 'data' => $userProyek, 'totalRecord' => $totalRecord], 200);
+ }
+ public function detail(Request $request, $id, $gantt_id = null, $s_curve = null){
if(empty($id) || !is_int((int)$id))
return response()->json(['status'=>'failed','message'=>'id is required!','code'=>400], 400);
@@ -408,13 +505,51 @@ class ProjectController extends Controller
if(!$result)
return response()->json(['status'=>'failed','message'=> 'Data not found!','code'=> 404], 404);
-
- $gantt = MasterFunctionsHelper::getLatestGantt($id);
+ if (!isset($gantt_id)) {
+ $gantt = MasterFunctionsHelper::getLatestGantt($id);
+ $ganttId = $gantt['last_gantt_id'];
+ } else {
+ $ganttId = $gantt_id;
+ }
$result->projectManager = User::where('id', $result->pm_id)->value('name');
- $result->header = Activity::whereNull('parent_id')->where("proyek_id", $id)->where("version_gantt_id", $gantt['last_gantt_id'])->first();
- return response()->json(['status'=>'success','code'=> 200,'data'=>$result], 200);
+
+ if (isset($s_curve)) {
+ $result->header = Activity::whereNull('parent_id')->where("proyek_id", $id)->first();
+ $actualStartExist = Activity::where('proyek_id', $id)->whereNotNull('actual_start')->exists();
+ $actualEndExist = Activity::where('proyek_id', $id)->whereNotNull('actual_end')->exists();
+ $query = Activity::where('proyek_id', $id);
+ } 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)->whereNotNull('actual_end')->exists();
+ $query = Activity::where('version_gantt_id', $ganttId);
+ }
+
+ if ($actualStartExist) {
+ $startDate = $query->orderBy('actual_start')->value('start_date');
+ } else {
+ $startDate = $query->orderBy('start_date')->value('start_date');
+ }
+
+ if ($actualEndExist) {
+ $endDate = $query->orderByDesc('actual_end')->value('end_date');
+ } else {
+ $endDate = $query->orderByDesc('end_date')->value('end_date');
+ }
+
+ $plannedStart = Activity::where('version_gantt_id', $ganttId)
+ ->orderBy('planned_start')
+ ->value('planned_start');
+ $plannedEnd = Activity::where('version_gantt_id', $ganttId)
+ ->orderByDesc('planned_end')
+ ->value('planned_end');
+ $result->header->start_date = $startDate;
+ $result->header->end_date = $endDate;
+ $result->header->planned_start = $plannedStart;
+ $result->header->planned_end = $plannedEnd;
+ return response()->json(['status'=>'success','code'=> 200,'data'=>$result, 'gantt'=>$ganttId], 200);
}
-
+
public function getOverdueActivities(Request $request){
$payload = $request->all();
if(empty($payload['id']) || !is_int((int)$payload['id']))
@@ -425,11 +560,23 @@ class ProjectController extends Controller
if(!$result)
return response()->json(['status'=>'failed','message'=> 'Project not found!','code'=> 404], 404);
//TODO possible overdue bug
- if(isset($payload['till_date']))
- $overdueActivities = Activity::where('proyek_id', $payload['id'])->whereNotNull('parent_id')->where('persentase_progress', '!=', 100)->whereDate('end_date','<=',$payload['till_date'])->orderBy('end_date', 'asc')->get();
- else
- $overdueActivities = Activity::where('proyek_id', $payload['id'])->whereNotNull('parent_id')->where('persentase_progress', '!=', 100)->orderBy('end_date', 'asc')->get();
-
+ $endDate = Activity::where('proyek_id', $payload['id'])
+ ->orderByDesc('end_date')
+ ->value('end_date');
+ if(isset($payload['till_date'])) {
+ if (isset($payload['scurve'])) {
+ $overdueActivities = Activity::where('proyek_id', $payload['id'])->whereNotNull('parent_id')->where('persentase_progress', '!=', 100)->whereDate('end_date','<=',$endDate)->orderBy('end_date', 'asc')->get();
+ } else {
+ $overdueActivities = Activity::where('version_gantt_id', $payload['gantt'])->whereNotNull('parent_id')->where('persentase_progress', '!=', 100)->whereDate('end_date','<=',$endDate)->orderBy('end_date', 'asc')->get();
+ }
+ }
+ else {
+ if (isset($payload['scurve'])) {
+ $overdueActivities = Activity::where('proyek_id', $payload['id'])->whereNotNull('parent_id')->where('persentase_progress', '!=', 100)->orderBy('end_date', 'asc')->get();
+ } else {
+ $overdueActivities = Activity::where('version_gantt_id', $payload['gantt'])->whereNotNull('parent_id')->where('persentase_progress', '!=', 100)->orderBy('end_date', 'asc')->get();
+ }
+ }
$result->overdueActivities = $overdueActivities;
return response()->json(['status'=>'success','code'=> 200,'data'=>$result], 200);
@@ -451,14 +598,13 @@ class ProjectController extends Controller
->where('ama.proyek_id', '=', $payload['project_id'])
->whereNotNull('ram.lat')
->whereBetween('ram.report_date', [$payload['start_date'], $payload['end_date']]);
-
+
return response()->json(['status'=>'success', 'code'=> 200, 'data'=> $reports], 200);
}
public function getManpower($proyek_id){
- $manPower = UserToProyek::where('proyek_id', $proyek_id)->get();
- $manCount = $manPower->count();
- return response()->json(['data'=>$manPower, 'totalRecord'=>$manCount]);
+ $manCount = UserToProyek::where('proyek_id', $proyek_id)->count();
+ return response()->json(['totalRecord'=>$manCount]);
}
public function getAssignedHR($gantt_id){
diff --git a/app/Http/Controllers/ProjectIssuesController.php b/app/Http/Controllers/ProjectIssuesController.php
new file mode 100644
index 0000000..fc54850
--- /dev/null
+++ b/app/Http/Controllers/ProjectIssuesController.php
@@ -0,0 +1,136 @@
+level_issue === "") {
+ $request->merge(['level_issue' => 0]);
+ }
+
+ $this->validate($request, [
+ 'proyek_id' => 'required',
+ 'description' => 'required|string',
+ 'level_issue' => 'required|integer'
+ ]);
+
+ $data = $request->all();
+
+ $data['created_by'] = $this->currentName;
+
+ $result = ProjectIssues::create($data);
+
+ if($result){
+ return response()->json(['status'=>'success','message'=>'add data project participants successfully!','code'=>200], 200);
+ }else{
+ return response()->json(['status'=>'failed','message'=>'add data project participants failed!','code'=>400], 400);
+ }
+ }
+
+ public function edit($id){
+ if(!$id || (int) $id < 0 || $id==""){
+ return response()->json(['status'=>'failed','message'=>'id is required!','code'=>400], 400);
+ die();
+ }
+
+ $result = ProjectIssues::find($id);
+
+ if($result){
+ return response()->json(['status'=>'success','code'=>200,'data'=>$result], 200);
+ }else{
+ return response()->json(['status'=>'failed','message'=>'failed get data project participants, please try again later!','code'=>400], 400);
+ }
+ }
+
+ public function update(Request $request, $id)
+ {
+ if(!$id || (int) $id < 0 || $id==""){
+ return response()->json(['status'=>'failed','message'=>'id is required!','code'=>400], 400);
+ }
+
+ $data = ProjectIssues::find($id);
+
+ if($data){
+ $result = $data->update($request->all());
+ }else{
+ return response()->json(['status'=>'failed','message'=>'data project participants not found!','code'=>400], 400);
+ die();
+ }
+
+
+ if($result){
+ return response()->json(['status'=>'success','message'=>'data project participants successfully updated!','code'=>200], 200);
+ }else{
+ return response()->json(['status'=>'failed','message'=>'data project participants failed updated!','code'=>400], 400);
+ }
+ }
+
+ public function delete($id)
+ {
+ $data = ProjectIssues::find($id);
+
+ if($data){
+ $delete = $data->delete();
+ }else{
+ return response()->json(['status'=>'failed','message'=>'data project participants not found!','code'=>400], 400);
+ die();
+ }
+
+
+ if($delete){
+ return response()->json(['status'=>'success','message'=>'data project participants successfully deleted!','code'=>200], 200);
+ }else{
+ return response()->json(['status'=>'failed','message'=>'data project participants failed deleted!','code'=>400], 400);
+ }
+ }
+
+ public function deleteByProyek($id)
+ {
+ $data = ProjectIssues::where('proyek_id', $id)->delete();
+
+ if($data){
+ return response()->json(['status'=>'success','message'=>'data project participants successfully deleted!','code'=>200], 200);
+ }else{
+ return response()->json(['status'=>'success','message'=>'data project participants failed deleted, because data not found!','code'=>200], 200);
+ }
+ }
+
+ public function customWhere($where, $val)
+ {
+ $data = ProjectIssues::where($where, $val)->orderBy('id', 'asc')->get();
+
+ if($data){
+ return response()->json(['status'=>'success','data'=> $data,'code'=>200], 200);
+ }else{
+ return response()->json(['status'=>'success','message'=>'data project participants not found!','code'=>400], 40);
+ }
+ }
+
+ public function search(Request $request)
+ {
+ $payload = $request->all();
+ $dataBuilder = $this->setUpPayload($payload, 'project_charter_issue');
+ $builder = $dataBuilder['builder'];
+ $countBuilder = $dataBuilder['count'];
+ $dataGet = $builder->get();
+ $totalRecord = $countBuilder->count();
+ return response()->json(['status'=>'success','code'=>200,'data'=>$dataGet, 'totalRecord'=>$totalRecord], 200);
+ }
+
+ public function list()
+ {
+ $data = ProjectIssues::all();
+ $countData = $data->count();
+
+ if($data){
+ return response()->json(['status'=>'success','code'=>200,'data'=>$data, 'totalRecord'=>$countData], 200);
+ }else{
+ return response()->json(['status'=>'failed','message'=>'failed get list project participants, please try again later!','code'=>400], 400);
+ }
+ }
+}
diff --git a/app/Http/Controllers/ProjectRisksController.php b/app/Http/Controllers/ProjectRisksController.php
new file mode 100644
index 0000000..d5c53df
--- /dev/null
+++ b/app/Http/Controllers/ProjectRisksController.php
@@ -0,0 +1,137 @@
+level_risk === "") {
+ $request->merge(['level_risk' => 0]);
+ }
+
+ $this->validate($request, [
+ 'proyek_id' => 'required',
+ 'level_risk' => 'required|integer',
+ 'description' => 'required|string',
+ 'preventive_risk' => 'required|string'
+ ]);
+
+ $data = $request->all();
+
+ $data['created_by'] = $this->currentName;
+
+ $result = ProjectRisks::create($data);
+
+ if($result){
+ return response()->json(['status'=>'success','message'=>'add data project participants successfully!','code'=>200], 200);
+ }else{
+ return response()->json(['status'=>'failed','message'=>'add data project participants failed!','code'=>400], 400);
+ }
+ }
+
+ public function edit($id){
+ if(!$id || (int) $id < 0 || $id==""){
+ return response()->json(['status'=>'failed','message'=>'id is required!','code'=>400], 400);
+ die();
+ }
+
+ $result = ProjectRisks::find($id);
+
+ if($result){
+ return response()->json(['status'=>'success','code'=>200,'data'=>$result], 200);
+ }else{
+ return response()->json(['status'=>'failed','message'=>'failed get data project participants, please try again later!','code'=>400], 400);
+ }
+ }
+
+ public function update(Request $request, $id)
+ {
+ if(!$id || (int) $id < 0 || $id==""){
+ return response()->json(['status'=>'failed','message'=>'id is required!','code'=>400], 400);
+ }
+
+ $data = ProjectRisks::find($id);
+
+ if($data){
+ $result = $data->update($request->all());
+ }else{
+ return response()->json(['status'=>'failed','message'=>'data project participants not found!','code'=>400], 400);
+ die();
+ }
+
+
+ if($result){
+ return response()->json(['status'=>'success','message'=>'data project participants successfully updated!','code'=>200], 200);
+ }else{
+ return response()->json(['status'=>'failed','message'=>'data project participants failed updated!','code'=>400], 400);
+ }
+ }
+
+ public function delete($id)
+ {
+ $data = ProjectRisks::find($id);
+
+ if($data){
+ $delete = $data->delete();
+ }else{
+ return response()->json(['status'=>'failed','message'=>'data project participants not found!','code'=>400], 400);
+ die();
+ }
+
+
+ if($delete){
+ return response()->json(['status'=>'success','message'=>'data project participants successfully deleted!','code'=>200], 200);
+ }else{
+ return response()->json(['status'=>'failed','message'=>'data project participants failed deleted!','code'=>400], 400);
+ }
+ }
+
+ public function deleteByProyek($id)
+ {
+ $data = ProjectRisks::where('proyek_id', $id)->delete();
+
+ if($data){
+ return response()->json(['status'=>'success','message'=>'data project participants successfully deleted!','code'=>200], 200);
+ }else{
+ return response()->json(['status'=>'success','message'=>'data project participants failed deleted, because data not found!','code'=>200], 200);
+ }
+ }
+
+ public function customWhere($where, $val)
+ {
+ $data = ProjectRisks::where($where, $val)->orderBy('id', 'asc')->get();
+
+ if($data){
+ return response()->json(['status'=>'success','data'=> $data,'code'=>200], 200);
+ }else{
+ return response()->json(['status'=>'success','message'=>'data project participants not found!','code'=>400], 40);
+ }
+ }
+
+ public function search(Request $request)
+ {
+ $payload = $request->all();
+ $dataBuilder = $this->setUpPayload($payload, 'project_charter_risk');
+ $builder = $dataBuilder['builder'];
+ $countBuilder = $dataBuilder['count'];
+ $dataGet = $builder->get();
+ $totalRecord = $countBuilder->count();
+ return response()->json(['status'=>'success','code'=>200,'data'=>$dataGet, 'totalRecord'=>$totalRecord], 200);
+ }
+
+ public function list()
+ {
+ $data = ProjectRisks::all();
+ $countData = $data->count();
+
+ if($data){
+ return response()->json(['status'=>'success','code'=>200,'data'=>$data, 'totalRecord'=>$countData], 200);
+ }else{
+ return response()->json(['status'=>'failed','message'=>'failed get list project participants, please try again later!','code'=>400], 400);
+ }
+ }
+}
diff --git a/app/Http/Controllers/ReportActivityMaterialController.php b/app/Http/Controllers/ReportActivityMaterialController.php
index fd61e5f..e451129 100644
--- a/app/Http/Controllers/ReportActivityMaterialController.php
+++ b/app/Http/Controllers/ReportActivityMaterialController.php
@@ -1,140 +1,187 @@
-validate($request, [
- 'activity_id' => 'required',
- 'qty' => 'required'
- ]);
-
- $activity = Activity::where('id', $request->activity_id)->first();
-
- $start_date = $activity->start_date;
- $start_date = substr($start_date, 0, 19); // remove the timezone offset
- $startDate = new \DateTime(date("Y-m-d", strtotime($start_date)));
- $reportDate = new \DateTime(date("Y-m-d", strtotime($request->report_date)));
-
- $data = $request->all();
- $data['created_by'] = $this->currentName;
- /* $data['assign_material_id'] = AssignMaterial::where('activity_id', $request->activity_id)->pluck('id')->first(); */
- $data['assign_material_id'] = $request->assign_material_id;
- $data['qty'] = $this->sanitizeDecimal($data['qty']);
- if($reportDate > $startDate){
- $created = ReportActivityMaterial::create($data);
- return response()->json(['status'=>'success','message'=>'Input progress report activity created','code'=>200,'data'=>array('report_id'=>$created->id)]);
- } else {
- return response()->json(['status'=>'failed','message'=>'Input progress report activity failed created','code'=>400,'data'=>null], 400);
- }
- }
-
- public function updateStatusStartFinish(Request $request){
-
- $payloadUpdate = array(
- 'start_activity' => $request->start_activity,
- 'finish_activity' => $request->finish_activity,
- 'status_activity' => $request->status_activity
- );
- $updateData = AssignMaterial::where('activity_id',$request->activity_id)
- ->update($payloadUpdate);
- if($updateData){
- if($request->status_activity == 'done'){
- $dataUpdate = array(
- "persentase_progress" => 100,
- "updated_by" => $this->currentName
- );
- Activity::where('id', $request->activity_id)->update($dataUpdate);
- }
-
- return response()->json(['status'=>'success','message'=>'Update data status successfully ', 'code'=>200]);
- }
- else{
- return response()->json(['status'=>'failed','message'=>'Update data status failed', 'code'=>400]);
- }
- }
-
- public function delete($id)
- {
- if(!ReportActivityMaterial::findOrFail($id)->delete())
- return response()->json(['status'=>'failed','message'=>'Failed to deleted the data!','code'=> 500], 500);
-
- return response()->json(['status'=>'success','message'=> 'Data deleted!','code'=>200], 200);
- }
-
- public function search(Request $request)
- {
- $payload = $request->all();
- $dataBuilder = $this->setUpPayload($payload, 'report_activity_material');
- $builder = $dataBuilder['builder'];
- $countBuilder = $dataBuilder['count'];
- $dataGet = $builder->get();
- $totalRecord = $countBuilder->count();
- return response()->json(['status'=>'success','code'=>200,'data'=>$dataGet, 'totalRecord'=>$totalRecord], 200);
- }
-
- public function list()
- {
- $data = ReportActivityMaterial::all();
- $countData = $data->count();
-
- if($data){
- return response()->json(['status'=>'success','code'=>200,'data'=>$data, 'totalRecord'=>$countData], 200);
- }else{
- return response()->json(['status'=>'failed','message'=>'failed get Repport Activity material, please try again later!','code'=>400], 400);
- }
- }
-
- public function datatables(Request $request){
- $id_activity = $request->query('idAct');
- $type = $request->query('type');
- $materialName = $request->query('materialName');
- if($type == 'plan'){
- $data = AssignMaterial::select("assign_material_to_activity.*","m.description as material_name", "m.uom as uom")
- ->join("m_req_material as m", "m.id", "=", "assign_material_to_activity.material_id")
- ->where('assign_material_to_activity.activity_id', $id_activity)
- ->where('m.description', $materialName)
- ->orderBy('assign_material_to_activity.id', 'asc')
- ->get();
- return Datatables::of($data)
- ->addIndexColumn()
- ->addColumn('action', function($row){
- $actionBtn = '';
- $actionBtn .= '';
- return $actionBtn;
- })
- ->rawColumns(['action'])->make(true);
- }else{
- $data = ReportActivityMaterial::select("report_activity_material.*", "u.name as human_resource")
- ->join("assign_material_to_activity as amta", "amta.id", "=", "report_activity_material.assign_material_id")
- ->join("m_req_material as m", "m.id", "=", "amta.material_id")
- ->join("m_users as u", "u.id", "=", "report_activity_material.user_id")
- ->where('report_activity_material.activity_id', $id_activity)
- ->where('m.description', $materialName)
- ->orderBy('report_activity_material.report_date', 'asc')
- ->get();
- return Datatables::of($data)
- ->addIndexColumn()
- ->addColumn('action', function($row){
- $actionBtn = '';
- $actionBtn .= '';
- return $actionBtn;
- })
- ->rawColumns(['action'])->make(true);
- }
- }
-}
+validate($request, [
+ 'activity_id' => 'required',
+ 'qty' => 'required'
+ ]);
+
+ $activity = Activity::where('id', $request->activity_id)->first();
+
+ $start_date = $activity->start_date;
+ $start_date = substr($start_date, 0, 19); // remove the timezone offset
+ $startDate = new \DateTime(date("Y-m-d", strtotime($start_date)));
+ $reportDate = new \DateTime(date("Y-m-d", strtotime($request->report_date)));
+
+ $data = $request->all();
+ $data['created_by'] = $this->currentName;
+ /* $data['assign_material_id'] = AssignMaterial::where('activity_id', $request->activity_id)->pluck('id')->first(); */
+ $data['assign_material_id'] = $request->assign_material_id;
+ $data['qty'] = $this->sanitizeDecimal($data['qty']);
+ if($reportDate >= $startDate || isset($data['force']) && $data['force'] == "true"){
+ $created = ReportActivityMaterial::create($data);
+ return response()->json(['status'=>'success','message'=>'Input progress report activity created','code'=>200,'data'=>array('report_id'=>$created->id)]);
+ } else {
+ return response()->json(['status'=>'failed','message'=>'Report date is before early start, still wanna add data ?','code'=>400,'data'=>$data], 400);
+ }
+ }
+
+ public function updateStatusStartFinish(Request $request){
+
+ $payloadUpdate = array(
+ 'start_activity' => $request->start_activity,
+ 'finish_activity' => $request->finish_activity,
+ 'status_activity' => $request->status_activity
+ );
+ $updateData = AssignMaterial::where('activity_id',$request->activity_id)
+ ->update($payloadUpdate);
+ if($updateData){
+ if($request->status_activity == 'done'){
+ $dataUpdate = array(
+ "persentase_progress" => 100,
+ "updated_by" => $this->currentName
+ );
+ Activity::where('id', $request->activity_id)->update($dataUpdate);
+ } else {
+ $sumAssignMaterial = AssignMaterial::where('activity_id', $request->activity_id)->sum('qty_planning');
+ $sumReportActivityMaterial = ReportActivityMaterial::where('activity_id', $request->activity_id)->sum('qty');
+ $dataUpdate = array(
+ "actual_start" => null,
+ "actual_end" => null,
+ "persentase_progress" => $sumReportActivityMaterial/$sumAssignMaterial*100,
+ "updated_by" => $this->currentName
+ );
+ if ($sumReportActivityMaterial > 0) {
+ $data = [];
+ $reportActivityMaterial = ReportActivityMaterial::where('activity_id', $request->activity_id)->get();
+ foreach ($reportActivityMaterial as $value) {
+ $data[] = $value;
+ }
+ $actualStartValues = array_column(array_filter($data, function($item) {
+ return isset($item['report_date']);
+ }), 'report_date');
+ $dataUpdate["actual_start"] = min($actualStartValues);
+ }
+ Activity::where('id', $request->activity_id)->update($dataUpdate);
+ }
+
+ return response()->json(['status'=>'success','message'=>'Update data status successfully ', 'code'=>200]);
+ }
+ else{
+ return response()->json(['status'=>'failed','message'=>'Update data status failed', 'code'=>400]);
+ }
+ }
+
+ public function delete($id)
+ {
+ if(!ReportActivityMaterial::findOrFail($id)->delete())
+ return response()->json(['status'=>'failed','message'=>'Failed to deleted the data!','code'=> 500], 500);
+
+ return response()->json(['status'=>'success','message'=> 'Data deleted!','code'=>200], 200);
+ }
+
+ public function search(Request $request)
+ {
+ $payload = $request->all();
+ $dataBuilder = $this->setUpPayload($payload, 'report_activity_material');
+ $builder = $dataBuilder['builder'];
+ $countBuilder = $dataBuilder['count'];
+ $dataGet = $builder->get();
+ $totalRecord = $countBuilder->count();
+ return response()->json(['status'=>'success','code'=>200,'data'=>$dataGet, 'totalRecord'=>$totalRecord], 200);
+ }
+
+ public function list()
+ {
+ $data = ReportActivityMaterial::all();
+ $countData = $data->count();
+
+ if($data){
+ return response()->json(['status'=>'success','code'=>200,'data'=>$data, 'totalRecord'=>$countData], 200);
+ }else{
+ return response()->json(['status'=>'failed','message'=>'failed get Repport Activity material, please try again later!','code'=>400], 400);
+ }
+ }
+
+ public function datatables(Request $request){
+ $id_activity = $request->query('idAct');
+ $type = $request->query('type');
+ $materialName = $request->query('materialName');
+ if($type == 'plan'){
+ $activity = Activity::findOrFail($id_activity);
+ $baselineDuration = 0;
+ if (isset($activity->planned_start) && isset($activity->planned_end)) {
+ $baselineDuration = MasterFunctionsHelper::countDays($activity->version_gantt_id, new DateTime($activity->planned_start), new DateTime($activity->planned_end));
+ }
+ $data = AssignMaterial::select("assign_material_to_activity.*","m.description as material_name", "m.uom as uom")
+ ->join("m_req_material as m", "m.id", "=", "assign_material_to_activity.material_id")
+ ->where('assign_material_to_activity.activity_id', $id_activity)
+ ->where('m.description', $materialName)
+ ->orderBy('assign_material_to_activity.id', 'asc')
+ ->get();
+ if ($baselineDuration > 0) {
+ foreach ($data as $key => $value) {
+ $data[$key]->qty_planning = number_format($value->qty_planning / $baselineDuration, 1);
+ }
+ }
+ return Datatables::of($data)
+ ->addIndexColumn()
+ ->addColumn('action', function($row){
+ $actionBtn = '';
+ if ($row->status_activity != 'done') {
+ $actionBtn .= '';
+ }
+ return $actionBtn;
+ })
+ ->rawColumns(['action'])->make(true);
+ }else{
+ $activity = Activity::findOrFail($id_activity);
+ $baselineDuration = 0;
+ if (isset($activity->planned_start) && isset($activity->planned_end)) {
+ $baselineDuration = MasterFunctionsHelper::countDays($activity->version_gantt_id, new DateTime($activity->planned_start), new DateTime($activity->planned_end));
+ }
+ $data = ReportActivityMaterial::select("report_activity_material.*", "u.name as human_resource", "amta.status_activity", "amta.qty_planning")
+ ->join("assign_material_to_activity as amta", "amta.id", "=", "report_activity_material.assign_material_id")
+ ->join("m_req_material as m", "m.id", "=", "amta.material_id")
+ ->join("m_users as u", "u.id", "=", "report_activity_material.user_id")
+ ->where('report_activity_material.activity_id', $id_activity)
+ ->where('m.description', $materialName)
+ ->orderBy('report_activity_material.report_date', 'asc')
+ ->get();
+ if ($baselineDuration > 0) {
+ foreach ($data as $key => $value) {
+ $data[$key]->qty_planning = number_format($value->qty_planning / $baselineDuration, 1);
+ }
+ }
+ return Datatables::of($data)
+ ->addIndexColumn()
+ ->addColumn('action', function($row){
+ $actionBtn = '';
+ if ($row->status_activity != 'done') {
+ $actionBtn .= '';
+ }
+ return $actionBtn;
+ })
+ ->rawColumns(['action'])->make(true);
+ }
+ }
+}
diff --git a/app/Http/Controllers/RequestMaterialController.php b/app/Http/Controllers/RequestMaterialController.php
index 35cb76d..605cf5f 100644
--- a/app/Http/Controllers/RequestMaterialController.php
+++ b/app/Http/Controllers/RequestMaterialController.php
@@ -170,7 +170,7 @@ class RequestMaterialController extends Controller
}
public function getMaterialIntegration(Request $request) {
- $search = null;
+ $search = urlencode($request->name);
if(empty($search))
return response()->json(['status'=>'error', 'message'=>'Empty query string!'], 400);
$url = str_replace("SEARCH", $search, config('api.adw').'/stock_master?name=SEARCH');
diff --git a/app/Http/Controllers/RoleController.php b/app/Http/Controllers/RoleController.php
index b420107..57b8c58 100644
--- a/app/Http/Controllers/RoleController.php
+++ b/app/Http/Controllers/RoleController.php
@@ -1,101 +1,109 @@
-validate($request, [
- 'name' => 'required',
- 'description' => 'required'
- ]);
-
- $data = $request->all();
-
- $data['created_by'] = $this->currentName;
-
- $result = Role::create($data);
-
- if(!$result)
- return response()->json(['status'=>'failed','message'=>'Failed to add data!','code'=>500], 500);
-
- return response()->json(['status'=>'success','message'=>'Data added!','code'=>200], 200);
- }
-
- public function edit( $id){
- if(empty($id) || !is_int((int)$id))
- return response()->json(['status'=>'failed','message'=>'id is required!','code'=>400], 400);
-
- $result = Role::find($id);
-
- if(!$result)
- return response()->json(['status'=>'failed','message'=>'Data not found!','code'=>404], 404);
-
- return response()->json(['status'=>'success','code'=>200,'data'=>$result], 200);
- }
-
- public function update(Request $request, $id)
- {
- if(empty($id) || !is_int((int)$id))
- return response()->json(['status'=>'failed','message'=>'id is required!','code'=>400], 400);
-
- $data = Role::find($id);
-
- if(!$data)
- return response()->json(['status'=>'failed','message'=>'Data not found!','code'=>404], 404);
-
- $result = $data->update($request->all());
-
- if(!$result)
- return response()->json(['status'=>'failed','message'=>'Failed to update the data!','code'=>500], 500);
-
- return response()->json(['status'=>'success','message'=>'Data updated!','code'=>200], 200);
- }
-
- public function delete($id)
- {
- if(empty($id) || !is_int((int)$id))
- return response()->json(['status'=>'failed','message'=>'id is required!','code'=>400], 400);
-
- $data = Role::find($id);
-
- if(!$data)
- return response()->json(['status'=>'failed','message'=>'Data not found!','code'=>404], 404);
-
- $delete = $data->delete();
-
- if(!$delete)
- return response()->json(['status'=>'failed','message'=>'Failed to delete!','code'=>500], 500);
-
- return response()->json(['status'=>'success','message'=>'Data deleted!','code'=>200], 200);
- }
-
- public function search(Request $request)
- {
- $payload = $request->all();
-
- $dataBuilder = $this->setUpPayload($payload, 'm_roles');
- $builder = $dataBuilder['builder'];
- $countBuilder = $dataBuilder['count'];
- $dataGet = $builder->get();
- $totalRecord = $countBuilder->count();
-
- return response()->json(['status'=>'success','code'=>200,'data'=>$dataGet, 'totalRecord'=>$totalRecord], 200);
- }
-
- public function list()
- {
- $data = Role::all();
- $countData = $data->count();
-
- if(!$data)
- return response()->json(['status'=>'failed','message'=>'failed get list role, please try again later!','code'=>400], 400);
-
- return response()->json(['status'=>'success','code'=>200,'data'=>$data, 'totalRecord'=>$countData], 200);
- }
-}
+validate($request, [
+ 'name' => 'string|required|unique:m_roles,name',
+ 'description' => 'required'
+ ]);
+
+ $data = $request->all();
+
+ $data['created_by'] = $this->currentName;
+ if (!isset($data['default_page'])) {
+ $data['default_page'] = 29; // dashboard
+ }
+
+ $result = Role::create($data);
+
+ if(!$result)
+ return response()->json(['status'=>'failed','message'=>'Failed to add data!','code'=>500], 500);
+
+ return response()->json(['status'=>'success','message'=>'Data added!','code'=>200], 200);
+ }
+
+ public function edit( $id){
+ if(empty($id) || !is_int((int)$id))
+ return response()->json(['status'=>'failed','message'=>'id is required!','code'=>400], 400);
+
+ $result = Role::find($id);
+
+ if(!$result)
+ return response()->json(['status'=>'failed','message'=>'Data not found!','code'=>404], 404);
+
+ return response()->json(['status'=>'success','code'=>200,'data'=>$result], 200);
+ }
+
+ public function update(Request $request, $id)
+ {
+ if(empty($id) || !is_int((int)$id))
+ return response()->json(['status'=>'failed','message'=>'id is required!','code'=>400], 400);
+
+ $this->validate($request, [
+ 'name' => 'string|required',
+ 'description' => 'required'
+ ]);
+ $data = Role::find($id);
+ $request->name !== $data['name'] ? $this->validate($request,['name'=>'unique:m_roles,name']) : '';
+
+ if(!$data)
+ return response()->json(['status'=>'failed','message'=>'Data not found!','code'=>404], 404);
+
+ $result = $data->update($request->all());
+
+ if(!$result)
+ return response()->json(['status'=>'failed','message'=>'Failed to update the data!','code'=>500], 500);
+
+ return response()->json(['status'=>'success','message'=>'Data updated!','code'=>200], 200);
+ }
+
+ public function delete($id)
+ {
+ if(empty($id) || !is_int((int)$id))
+ return response()->json(['status'=>'failed','message'=>'id is required!','code'=>400], 400);
+
+ $data = Role::find($id);
+
+ if(!$data)
+ return response()->json(['status'=>'failed','message'=>'Data not found!','code'=>404], 404);
+
+ $delete = $data->delete();
+
+ if(!$delete)
+ return response()->json(['status'=>'failed','message'=>'Failed to delete!','code'=>500], 500);
+
+ return response()->json(['status'=>'success','message'=>'Data deleted!','code'=>200], 200);
+ }
+
+ public function search(Request $request)
+ {
+ $payload = $request->all();
+
+ $dataBuilder = $this->setUpPayload($payload, 'm_roles');
+ $builder = $dataBuilder['builder'];
+ $countBuilder = $dataBuilder['count'];
+ $dataGet = $builder->get();
+ $totalRecord = $countBuilder->count();
+
+ return response()->json(['status'=>'success','code'=>200,'data'=>$dataGet, 'totalRecord'=>$totalRecord], 200);
+ }
+
+ public function list()
+ {
+ $data = Role::all();
+ $countData = $data->count();
+
+ if(!$data)
+ return response()->json(['status'=>'failed','message'=>'failed get list role, please try again later!','code'=>400], 400);
+
+ return response()->json(['status'=>'success','code'=>200,'data'=>$data, 'totalRecord'=>$countData], 200);
+ }
+}
diff --git a/app/Http/Controllers/RoleMenuController.php b/app/Http/Controllers/RoleMenuController.php
index 05942f5..ebd5d0a 100644
--- a/app/Http/Controllers/RoleMenuController.php
+++ b/app/Http/Controllers/RoleMenuController.php
@@ -1,102 +1,102 @@
-validate($request, [
- 'role_id' => 'required',
- 'menu_id' => 'required',
- ]);
-
- $data = $request->all();
-
- $data['created_by'] = $this->currentName;
-
- $result = RoleMenu::create($data);
-
- if($result){
- return response()->json(['status'=>'success','message'=>'add data role menu successfully!','code'=>200], 200);
- }else{
- return response()->json(['status'=>'failed','message'=>'add data role menu failed!','code'=>400], 400);
- }
- }
-
- public function update(Request $request, $id)
- {
- if(!$id || (int) $id < 0 || $id==""){
- return response()->json(['status'=>'failed','message'=>'id is required!','code'=>400], 400);
- }
-
- $data = RoleMenu::find($id);
-
- if($data){
- $result = $data->update($request->all());
- }else{
- return response()->json(['status'=>'failed','message'=>'data role menu not found!','code'=>400], 400);
- die();
- }
-
-
- if($result){
- return response()->json(['status'=>'success','message'=>'data role menu successfully updated!','code'=>200], 200);
- }else{
- return response()->json(['status'=>'failed','message'=>'data role menu failed updated!','code'=>400], 400);
- }
- }
-
- public function delete($id)
- {
- $data = RoleMenu::find($id);
-
- if($data){
- $delete = $data->delete();
- }else{
- return response()->json(['status'=>'failed','message'=>'data role menu not found!','code'=>400], 400);
- die();
- }
-
-
- if($delete){
- return response()->json(['status'=>'success','message'=>'data role menu successfully deleted!','code'=>200], 200);
- }else{
- return response()->json(['status'=>'failed','message'=>'data role menu failed deleted!','code'=>400], 400);
- }
- }
-
- public function deleteByRole($id)
- {
- $data = RoleMenu::where("role_id", $id);
-
- if($data){
- $delete = $data->delete();
- }else{
- return response()->json(['status'=>'failed','message'=>'data role menu not found!','code'=>400], 400);
- die();
- }
-
-
- if($delete){
- return response()->json(['status'=>'success','message'=>'data role menu successfully deleted!','code'=>200], 200);
- }else{
- return response()->json(['status'=>'failed','message'=>'data role menu failed deleted!','code'=>400], 400);
- }
- }
-
- public function search(Request $request)
- {
- $payload = $request->all();
- $dataBuilder = $this->setUpPayload($payload, 't_roles_menu');
- $builder = $dataBuilder['builder'];
- $countBuilder = $dataBuilder['count'];
- $dataGet = $builder->get();
- $totalRecord = $countBuilder->count();
- return response()->json(['status'=>'success','code'=>200,'data'=>$dataGet, 'totalRecord'=>$totalRecord], 200);
- }
-}
+validate($request, [
+ 'role_id' => 'required',
+ 'menu_id' => 'required',
+ ]);
+
+ $data = $request->all();
+
+ $data['created_by'] = $this->currentName;
+
+ $result = RoleMenu::create($data);
+
+ if($result){
+ return response()->json(['status'=>'success','message'=>'add data role menu successfully!','code'=>200], 200);
+ }else{
+ return response()->json(['status'=>'failed','message'=>'add data role menu failed!','code'=>400], 400);
+ }
+ }
+
+ public function update(Request $request, $id)
+ {
+ if(!$id || (int) $id < 0 || $id==""){
+ return response()->json(['status'=>'failed','message'=>'id is required!','code'=>400], 400);
+ }
+
+ $data = RoleMenu::find($id);
+
+ if($data){
+ $result = $data->update($request->all());
+ }else{
+ return response()->json(['status'=>'failed','message'=>'data role menu not found!','code'=>400], 400);
+ die();
+ }
+
+
+ if($result){
+ return response()->json(['status'=>'success','message'=>'data role menu successfully updated!','code'=>200], 200);
+ }else{
+ return response()->json(['status'=>'failed','message'=>'data role menu failed updated!','code'=>400], 400);
+ }
+ }
+
+ public function delete($id)
+ {
+ $data = RoleMenu::find($id);
+
+ if($data){
+ $delete = $data->delete();
+ }else{
+ return response()->json(['status'=>'failed','message'=>'data role menu not found!','code'=>400], 400);
+ die();
+ }
+
+
+ if($delete){
+ return response()->json(['status'=>'success','message'=>'data role menu successfully deleted!','code'=>200], 200);
+ }else{
+ return response()->json(['status'=>'failed','message'=>'data role menu failed deleted!','code'=>400], 400);
+ }
+ }
+
+ public function deleteByRole($id)
+ {
+ $data = RoleMenu::where("role_id", $id);
+
+ if($data){
+ $delete = $data->delete();
+ }else{
+ return response()->json(['status'=>'failed','message'=>'data role menu not found!','code'=>400], 400);
+ die();
+ }
+
+
+ if($delete){
+ return response()->json(['status'=>'success','message'=>'data role menu successfully deleted!','code'=>200], 200);
+ }else{
+ return response()->json(['status'=>'failed','message'=>'data role menu failed deleted!','code'=>400], 400);
+ }
+ }
+
+ public function search(Request $request)
+ {
+ $payload = $request->all();
+ $dataBuilder = $this->setUpPayload($payload, 't_roles_menu');
+ $builder = $dataBuilder['builder'];
+ $countBuilder = $dataBuilder['count'];
+ $dataGet = $builder->get();
+ $totalRecord = $countBuilder->count();
+ return response()->json(['status'=>'success','code'=>200,'data'=>$dataGet, 'totalRecord'=>$totalRecord], 200);
+ }
+}
diff --git a/app/Http/Controllers/ShowHideColumnController.php b/app/Http/Controllers/ShowHideColumnController.php
index a2db693..be5292f 100644
--- a/app/Http/Controllers/ShowHideColumnController.php
+++ b/app/Http/Controllers/ShowHideColumnController.php
@@ -45,12 +45,12 @@ class ShowHideColumnController extends Controller
$success = 0;
- foreach ($columns as $column) {
+ foreach ($columns as $key => $column) {
$dataAdd = array(
'version_gantt_id'=>$request->version_gantt_id,
'user_id'=>$this->currentId,
- 'column_name'=>$column,
- 'show'=>true,
+ 'column_name'=>$key,
+ 'show'=>$column,
'created_by'=>$this->currentName
);
diff --git a/app/Http/Controllers/UserToActivityController.php b/app/Http/Controllers/UserToActivityController.php
index 048825c..2c3a658 100644
--- a/app/Http/Controllers/UserToActivityController.php
+++ b/app/Http/Controllers/UserToActivityController.php
@@ -1,198 +1,234 @@
-validate($request, [
- 'activity_id' => 'required',
- 'user_id' => 'required'
- ]);
-
- $data = $request->all();
- $data['created_by'] = $this->currentName;
-
- if(!UserToActivity::create($data))
- return response()->json(['status'=>'failed','message'=>'Failed to add data!','code'=> 500]);
-
- return response()->json(['status'=>'success','message'=>'Data added!', 'code'=> 200]);
- }
-
- public function addMultiple(Request $request){
- $users_id = $request->user_id;
- $users_role = $request->role_proyek_id;
-
- // $data = UserToActivity::where("activity_id", $request->activity_id);
- // if($data){
- // $data->delete();
- // }
-
- if(is_array($users_id) && count($users_id) > 0){
- $countRes = 0;
- foreach($users_id as $index => $item){
- $dataInsert = array(
- "user_id" => $item,
- "activity_id" => $request->activity_id,
- "role_proyek_id" => $users_role[$index],
- "proyek_id" => $request->proyek_id,
- "created_by" => $this->currentName
- );
- $result = UserToActivity::create($dataInsert);
- if($result){
- $countRes++;
- }else{
- $countRes--;
- }
- }
-
- if($countRes == 0)
- return response()->json(['status'=>'failed' ,'message'=>'Failed to add data!','code'=> 500]);
-
- $allCost = $this->calculateAllCost($request->activity_id, $request->proyek_id);
- $dataUpdateCost = array(
- "rencana_biaya"=>$allCost,
- "updated_by"=> $this->currentName
- );
- $actUpdate = Activity::find($request->activity_id);
- if($actUpdate){
- $actUpdate->update($dataUpdateCost);
- if($actUpdate->parent_id){
- $this->updatedCostPlanning($actUpdate->parent_id);
- }
- }
- return response()->json(['status'=>'success' ,'message'=>'Data added!','code'=>200]);
- }else{
- return response()->json(['status'=>'success' ,'message'=>'Data added!','code'=>200]);
- }
-
- }
-
- private function updatedCostPlanning($parent_id) {
- $sumBiaya = Activity::selectRaw('sum(cast(rencana_biaya as double precision))')
- ->where("parent_id", $parent_id)
- ->first();
- if($parent = Activity::find($parent_id)){
- $parent->update([
- "rencana_biaya" => $sumBiaya->sum,
- ]);
- }
- }
-
- public function update(Request $request, $id){
- if(empty($id) || !is_int((int)$id))
- return response()->json(['status'=>'failed','message'=>'id is required!','code'=>400], 400);
-
- $data = UserToActivity::find($id);
- if(!$data)
- return response()->json(['status'=>'failed','message'=>'Data not found!','code'=> 404], 404);
-
- if(!$data->update($request->all()));
- return response()->json(['status'=>'failed','message'=>'Failed to update!','code'=> 500], 500);
-
- return response()->json(['status'=>'success','message'=>'Data updated!','code'=>200], 200);
- }
-
- public function delete($id)
- {
- $data = UserToActivity::find($id);
- if(!$data)
- return response()->json(['status'=>'failed','message'=>'data user to activity gantt Project not found!','code'=>400], 400);
-
- if($data->delete()){
- return response()->json(['status'=>'success','message'=>'Data deleted!','code'=>200], 200);
- }
-
- return response()->json(['status'=>'failed','message'=>'Failed to delete!','code'=> 500], 500);
- }
-
- public function edit($id){
- if(!$id || (int) $id < 0 || $id==""){
- return response()->json(['status'=>'failed','message'=>'id is required!','code'=>400], 400);
- die();
- }
-
- $result = UserToActivity::find($id);
-
- if(!$result)
- return response()->json(['status'=>'failed','message'=>'failed get data tools resource, please try again later!','code'=>400], 400);
-
- return response()->json(['status'=>'success','code'=>200,'data'=>$result], 200);
- }
-
- public function search(Request $request)
- {
- $payload = $request->all();
- $dataBuilder = $this->setUpPayload($payload, 'assign_hr_to_activity');
- $builder = $dataBuilder['builder'];
- $countBuilder = $dataBuilder['count'];
- $dataGet = $builder->get();
- $totalRecord = $countBuilder->count();
- return response()->json(['status'=>'success','code'=>200,'data'=>$dataGet, 'totalRecord'=>$totalRecord], 200);
- }
-
- public function list()
- {
- $data = UserToActivity::all();
- $countData = $data->count();
-
- if($data){
- return response()->json(['status'=>'success','code'=>200,'data'=>$data, 'totalRecord'=>$countData], 200);
- }else{
- return response()->json(['status'=>'failed','message'=>'failed get list user to activity gantt, please try again later!','code'=>400], 400);
- }
- }
-
- public function listFiltered(Request $request)
- {
- $startDate = $request->start_date;
- $endDate = $request->end_date;
- $userId = $request->user_id;
- $proyekId = $request->proyek_id;
-
- if (isset($proyekId)) {
- $data = UserToActivity::select('assign_hr_to_activity.id', 'assign_hr_to_activity.activity_id', 'm_activity.name', 'm_activity.kode_sortname', 'm_activity.start_date', 'm_activity.end_date')
- ->join('m_activity', 'assign_hr_to_activity.activity_id', '=', 'm_activity.id')
- ->where('m_activity.start_date', '=', $startDate)
- ->where('m_activity.end_date', '=', $endDate)
- ->where('assign_hr_to_activity.user_id', '=', $userId)
- ->where('assign_hr_to_activity.proyek_id', '=', $proyekId)
- ->get();
- }else {
- $data = UserToActivity::select('assign_hr_to_activity.id', 'assign_hr_to_activity.activity_id', 'm_activity.name', 'm_activity.kode_sortname', 'm_activity.start_date', 'm_activity.end_date')
- ->join('m_activity', 'assign_hr_to_activity.activity_id', '=', 'm_activity.id')
- ->where('m_activity.start_date', '=', $startDate)
- ->where('m_activity.end_date', '=', $endDate)
- ->where('assign_hr_to_activity.user_id', '=', $userId)
- ->get();
- }
- $countData = $data->count();
-
- if($data){
- return response()->json(['status'=>'success','code'=>200,'data'=>$data, 'totalRecord'=>$countData], 200);
- }else{
- return response()->json(['status'=>'failed','message'=>'failed get list user to activity gantt, please try again later!','code'=>400], 400);
- }
- }
-
- public function datatables(Request $request){
- $id_activity = $request->query('idact');
- $data = UserToActivity::select("assign_hr_to_activity.id as id", "u.name as user_name", "mrp.name as role_name")
- ->join("m_role_proyek as mrp", "mrp.id", "=", "assign_hr_to_activity.role_proyek_id")
- ->join("m_users as u", "u.id", "=", "assign_hr_to_activity.user_id")
- ->where('assign_hr_to_activity.activity_id', $id_activity)
- ->get();
- return Datatables::of($data)
- ->addIndexColumn()
- ->addColumn('action', function($row){
- $actionBtn = '';
- return $actionBtn;
- })
- ->rawColumns(['action'])->make(true);
- }
-}
+validate($request, [
+ 'activity_id' => 'required',
+ 'user_id' => 'required'
+ ]);
+
+ $data = $request->all();
+ $data['created_by'] = $this->currentName;
+
+ if(!UserToActivity::create($data))
+ return response()->json(['status'=>'failed','message'=>'Failed to add data!','code'=> 500]);
+
+ return response()->json(['status'=>'success','message'=>'Data added!', 'code'=> 200]);
+ }
+
+ public function addMultiple(Request $request){
+ $users_id = $request->user_id;
+ $users_role = $request->role_proyek_id;
+
+ // $data = UserToActivity::where("activity_id", $request->activity_id);
+ // if($data){
+ // $data->delete();
+ // }
+
+ if(is_array($users_id) && count($users_id) > 0){
+ $countRes = 0;
+ foreach($users_id as $index => $item){
+ $dataInsert = array(
+ "user_id" => $item,
+ "activity_id" => $request->activity_id,
+ "role_proyek_id" => $users_role[$index],
+ "proyek_id" => $request->proyek_id,
+ "start_date" => $request->start_date,
+ "end_date" => $request->end_date,
+ "created_by" => $this->currentName,
+ "version_gantt_id" => $request->version_gantt_id
+ );
+ $result = UserToActivity::create($dataInsert);
+ if($result){
+ $countRes++;
+ }else{
+ $countRes--;
+ }
+ }
+
+ if($countRes == 0)
+ return response()->json(['status'=>'failed' ,'message'=>'Failed to add data!','code'=> 500]);
+
+ $allCost = $this->calculateAllCost($request->activity_id, $request->proyek_id);
+ $dataUpdateCost = array(
+ "rencana_biaya"=>$allCost,
+ "updated_by"=> $this->currentName
+ );
+ $actUpdate = Activity::find($request->activity_id);
+ if($actUpdate){
+ $actUpdate->update($dataUpdateCost);
+ if($actUpdate->parent_id){
+ $this->updatedCostPlanning($actUpdate->parent_id);
+ }
+ }
+ return response()->json(['status'=>'success' ,'message'=>'Data added!','code'=>200]);
+ }else{
+ return response()->json(['status'=>'success' ,'message'=>'Data added!','code'=>200]);
+ }
+
+ }
+
+ private function updatedCostPlanning($parent_id) {
+ $sumBiaya = Activity::selectRaw('sum(cast(rencana_biaya as double precision))')
+ ->where("parent_id", $parent_id)
+ ->first();
+ if($parent = Activity::find($parent_id)){
+ $parent->update([
+ "rencana_biaya" => $sumBiaya->sum,
+ ]);
+ }
+ }
+
+ public function update(Request $request, $id){
+ if(empty($id) || !is_int((int)$id))
+ return response()->json(['status'=>'failed','message'=>'id is required!','code'=>400], 400);
+
+ $data = UserToActivity::find($id);
+ if(!$data)
+ return response()->json(['status'=>'failed','message'=>'Data not found!','code'=> 404], 404);
+
+ if(!$data->update($request->all()));
+ return response()->json(['status'=>'failed','message'=>'Failed to update!','code'=> 500], 500);
+
+ return response()->json(['status'=>'success','message'=>'Data updated!','code'=>200], 200);
+ }
+
+ public function delete($id)
+ {
+ $data = UserToActivity::find($id);
+ if(!$data)
+ return response()->json(['status'=>'failed','message'=>'data user to activity gantt Project not found!','code'=>400], 400);
+
+ if($data->delete()){
+ return response()->json(['status'=>'success','message'=>'Data deleted!','code'=>200], 200);
+ }
+
+ return response()->json(['status'=>'failed','message'=>'Failed to delete!','code'=> 500], 500);
+ }
+
+ public function edit($id){
+ if(!$id || (int) $id < 0 || $id==""){
+ return response()->json(['status'=>'failed','message'=>'id is required!','code'=>400], 400);
+ die();
+ }
+
+ $result = UserToActivity::find($id);
+
+ if(!$result)
+ return response()->json(['status'=>'failed','message'=>'failed get data tools resource, please try again later!','code'=>400], 400);
+
+ return response()->json(['status'=>'success','code'=>200,'data'=>$result], 200);
+ }
+
+ public function search(Request $request)
+ {
+ $payload = $request->all();
+ if (isset($payload['join_column'])) {
+ $join_column = $payload['join_column'];
+ unset($payload['join_column']);
+ }
+
+ $dataBuilder = $this->setUpPayload($payload, 'assign_hr_to_activity');
+ $builder = $dataBuilder['builder'];
+ $countBuilder = $dataBuilder['count'];
+ if (isset($join_column)) {
+ $startDate = $join_column['start_date'];
+ $endDate = $join_column['end_date'];
+ $status = $join_column['status'];
+ $startDate = date("Y-m-d H:i:sO", strtotime($startDate));
+ $endDate = date("Y-m-d H:i:sO", strtotime($endDate));
+ $builder->where(function ($query) use ($startDate, $endDate) {
+ $query
+ ->where('m_proyek.mulai_proyek', '>=', $startDate)
+ ->where('m_proyek.akhir_proyek', '<=', $endDate)
+ ->where(function ($query) use ($endDate, $startDate) {
+ $query
+ ->where('m_activity.start_date', '>=', $startDate)
+ ->where('m_activity.end_date', '<=', $endDate);
+ });
+ });
+ }
+ $dataGet = $builder->get();
+ if (isset($status) && $status != "") {
+ $filteredData = [];
+ foreach ($dataGet as $value) {
+ $assignMaterial = AssignMaterial::where('activity_id', $value->activity_id)->first();
+ if ($assignMaterial->status_activity == $status) {
+ $filteredData[] = $value;
+ }
+ }
+ $dataGet = $filteredData;
+ }
+ $totalRecord = $countBuilder->count();
+ return response()->json(['status'=>'success','code'=>200,'data'=>$dataGet, 'totalRecord'=>$totalRecord], 200);
+ }
+
+ public function list()
+ {
+ $data = UserToActivity::all();
+ $countData = $data->count();
+
+ if($data){
+ return response()->json(['status'=>'success','code'=>200,'data'=>$data, 'totalRecord'=>$countData], 200);
+ }else{
+ return response()->json(['status'=>'failed','message'=>'failed get list user to activity gantt, please try again later!','code'=>400], 400);
+ }
+ }
+
+ public function listFiltered(Request $request)
+ {
+ $startDate = $request->start_date;
+ $endDate = $request->end_date;
+ $userId = $request->user_id;
+ $proyekId = $request->proyek_id;
+
+ if (isset($proyekId)) {
+ $data = UserToActivity::select('assign_hr_to_activity.id', 'assign_hr_to_activity.activity_id', 'm_activity.name', 'm_activity.kode_sortname', 'm_activity.start_date', 'm_activity.end_date')
+ ->join('m_activity', 'assign_hr_to_activity.activity_id', '=', 'm_activity.id')
+ ->where('m_activity.start_date', '=', $startDate)
+ ->where('m_activity.end_date', '=', $endDate)
+ ->where('assign_hr_to_activity.user_id', '=', $userId)
+ ->where('assign_hr_to_activity.proyek_id', '=', $proyekId)
+ ->get();
+ }else {
+ $data = UserToActivity::select('assign_hr_to_activity.id', 'assign_hr_to_activity.activity_id', 'm_activity.name', 'm_activity.kode_sortname', 'm_activity.start_date', 'm_activity.end_date')
+ ->join('m_activity', 'assign_hr_to_activity.activity_id', '=', 'm_activity.id')
+ ->where('m_activity.start_date', '=', $startDate)
+ ->where('m_activity.end_date', '=', $endDate)
+ ->where('assign_hr_to_activity.user_id', '=', $userId)
+ ->get();
+ }
+ $countData = $data->count();
+
+ if($data){
+ return response()->json(['status'=>'success','code'=>200,'data'=>$data, 'totalRecord'=>$countData], 200);
+ }else{
+ return response()->json(['status'=>'failed','message'=>'failed get list user to activity gantt, please try again later!','code'=>400], 400);
+ }
+ }
+
+ public function datatables(Request $request){
+ $id_activity = $request->query('idact');
+ $data = UserToActivity::select("assign_hr_to_activity.id as id", "assign_hr_to_activity.start_date", "assign_hr_to_activity.end_date", "u.name as user_name", "mrp.name as role_name")
+ ->join("m_role_proyek as mrp", "mrp.id", "=", "assign_hr_to_activity.role_proyek_id")
+ ->join("m_users as u", "u.id", "=", "assign_hr_to_activity.user_id")
+ ->where('assign_hr_to_activity.activity_id', $id_activity)
+ ->get();
+ return Datatables::of($data)
+ ->addIndexColumn()
+ ->addColumn('action', function($row){
+ $actionBtn = '';
+ return $actionBtn;
+ })
+ ->rawColumns(['action'])->make(true);
+ }
+}
diff --git a/app/Http/Controllers/UserToProyekController.php b/app/Http/Controllers/UserToProyekController.php
index dc944ea..f6fca59 100644
--- a/app/Http/Controllers/UserToProyekController.php
+++ b/app/Http/Controllers/UserToProyekController.php
@@ -1,214 +1,256 @@
-validate($request, [
- 'user_id' => 'required',
- 'proyek_id' => 'required'
- ]);
-
- $data = $request->all();
-
- $data['created_by'] = $this->currentName;
-
- $result = UserToProyek::create($data);
-
- if($result){
- return response()->json(['status'=>'success','message'=>'assign hr to proyek successfully!','code'=>200], 200);
- }else{
- return response()->json(['status'=>'failed','message'=>'assign hr to proyek failed!','code'=>400], 400);
- }
- }
-
- public function edit($id){
- if(!$id || (int) $id < 0 || $id==""){
- return response()->json(['status'=>'failed','message'=>'id is required!','code'=>400], 400);
- die();
- }
-
- $result = UserToProyek::find($id);
-
- if($result){
- return response()->json(['status'=>'success','code'=>200,'data'=>$result], 200);
- }else{
- return response()->json(['status'=>'failed','message'=>'failed get data assign hr to proyek, please try again later!','code'=>400], 400);
- }
- }
-
- public function update(Request $request, $id)
- {
- if(!$id || (int) $id < 0 || $id==""){
- return response()->json(['status'=>'failed','message'=>'id is required!','code'=>400], 400);
- }
-
- $data = UserToProyek::find($id);
-
- if($data){
- $result = $data->update($request->all());
- }else{
- return response()->json(['status'=>'failed','message'=>'data assign hr to proyek not found!','code'=>400], 400);
- die();
- }
-
-
- if($result){
- return response()->json(['status'=>'success','message'=>'data assign hr to proyek successfully updated!','code'=>200], 200);
- }else{
- return response()->json(['status'=>'failed','message'=>'data assign hr to proyek failed updated!','code'=>400], 400);
- }
- }
-
- public function delete($id)
- {
- $data = UserToProyek::find($id);
- if($data){
- $userId = $data->user_id;
- $proyekId = $data->proyek_id;
- $delete = $data->delete();
- if($delete){
- $this->deleteRelative($proyekId, $userId);
- }
- }else{
- return response()->json(['status'=>'failed','message'=>'data assign hr to proyek not found!','code'=>400], 400);
- die();
- }
-
-
- if($delete){
- return response()->json(['status'=>'success','message'=>'data assign hr to proyek successfully deleted!','code'=>200], 200);
- }else{
- return response()->json(['status'=>'failed','message'=>'data assign hr to proyek failed deleted!','code'=>400], 400);
- }
- }
-
- private function deleteRelative($proyekId, $userId)
- {
- $uta = UserToActivity::where("proyek_id", $proyekId)->where("user_id", $userId)->get();
- foreach ($uta as $value) {
- $dataRa = ReportActivity::where("activity_id", $value->activity_id)->where("user_id", $value->user_id)->get();
- foreach ($dataRa as $ra) {
- $images = Image::where("ref_id", $ra->id)->where("category", "report_activity")->get();
- foreach ($images as $image) {
- if(file_exists($this->pathImage.$image->image)){
- unlink($this->pathImage.$image->image);
- }
- }
- Image::where("ref_id", $ra->id)->where("category", "report_activity")->delete();
- }
- ReportActivity::where("activity_id", $value->activity_id)->where("user_id", $value->user_id)->delete();
- }
- UserToActivity::where("proyek_id", $proyekId)->where("user_id", $userId)->delete();
- }
-
- public function search(Request $request)
- {
- $payload = $request->all();
- $dataBuilder = $this->setUpPayload($payload, 'assign_hr_to_proyek');
- $builder = $dataBuilder['builder'];
- $countBuilder = $dataBuilder['count'];
- $dataGet = $builder->get();
- $totalRecord = $countBuilder->count();
- return response()->json(['status'=>'success','code'=>200,'data'=>$dataGet, 'totalRecord'=>$totalRecord], 200);
- }
-
- public function list()
- {
- $data = UserToProyek::all();
- $countData = $data->count();
-
- if($data){
- return response()->json(['status'=>'success','code'=>200,'data'=>$data, 'totalRecord'=>$countData], 200);
- }else{
- return response()->json(['status'=>'failed','message'=>'failed get list assign hr to proyek, please try again later!','code'=>400], 400);
- }
- }
-
- public function select(Request $request){
-
- $search = $request->query('search');
-
- $idProyek = (int)$request->query('idProyek');
- $idActivity = (int)$request->query('idact');
-
- $include = [];
-
- if($idActivity && $idActivity > 0){
- $dataF = UserToActivity::select("user_id")->where("activity_id", $idActivity)->get();
- foreach($dataF as $val){
- $include[] = $val->user_id;
- }
- }
-
- if($search && !empty($search)){
- $data = UserToProyek::select("m_users.id as id", "m_users.name as name")->join('m_users', 'm_users.id', '=', 'assign_hr_to_proyek.user_id')
- ->where("assign_hr_to_proyek.proyek_id", $idProyek)->where("m_users.name", 'like', '%'.$search.'%')->whereIn("m_users.id", $include)->get();
- }else{
- $data = UserToProyek::select("m_users.id as id", "m_users.name as name")->where("assign_hr_to_proyek.proyek_id", $idProyek)->join('m_users', 'm_users.id', '=', 'assign_hr_to_proyek.user_id')->whereIn("m_users.id", $include)->get();
- }
-
- if($data instanceof \Illuminate\Database\Eloquent\Collection){
- $pm = array(
- "id"=>$this->currentId,
- "name"=> "Project Manager"
- );
- $data->push($pm);
- }
-
- return response()->json($data);
- }
-
- private function curlReq($url, $token){
- $ch = curl_init();
- $headers = [
- 'Authorization: '.$token
- ];
- curl_setopt($ch, CURLOPT_URL, $url);
- curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
-
- $response = curl_exec($ch);
- if ($response === false)
- $response = curl_error($ch);
- curl_close($ch);
-
- return json_decode($response);
- }
-
- public function getEmployeeIntegration(Request $request) {
- $search = null;
- if(empty($search))
- return response()->json(['status'=>'error', 'message'=>'Empty query string!'], 400);
- $url = str_replace("SEARCH", $search, config('api.adw').'/employees?emp_name=SEARCH');
- $token = config('api.adw_token');
- $firstResponse = $this->curlReq($url, $token);
-
- if($firstResponse->total == 0)
- return response()->json(['status'=>'error', 'message' => 'Data not found!', 'code'=>404], 404);
-
- $data = $firstResponse->data;
- return response()->json([$data]);
- $currentPage = 1;
-
- if($firstResponse->last_page > 0) {
- do {
- $currentPage++;
- $response = $this->curlReq($url.'&page='.$currentPage, $token);
- foreach($response->data as $d){
- array_push($data, $d);
- }
- } while ($currentPage < $firstResponse->last_page);
- }
-
- return response()->json(['status'=>'success', 'data'=> $data, 'total' => count($data), 'code'=>200], 200);
- }
-}
+validate($request, [
+ 'user_id' => 'required',
+ 'proyek_id' => 'required'
+ ]);
+
+ $data = $request->all();
+
+ $data['created_by'] = $this->currentName;
+
+ $result = UserToProyek::create($data);
+
+ if($result){
+ return response()->json(['status'=>'success','message'=>'assign hr to proyek successfully!','code'=>200], 200);
+ }else{
+ return response()->json(['status'=>'failed','message'=>'assign hr to proyek failed!','code'=>400], 400);
+ }
+ }
+
+ public function addMultiple(Request $request){
+ $user_IDs = $request->user_id;
+
+ $data = UserToProyek::where([
+ ["proyek_id" , $request->proyek_id],
+ ['is_customer',true]
+ ]);
+
+ if($data){
+ $data->delete();
+ }
+
+ if(is_array($user_IDs) && count($user_IDs) > 0){
+ $countRes = 0;
+ foreach($user_IDs as $item){
+
+ $dataInsert = array(
+ "user_id" => $item,
+ "proyek_id" => $request->proyek_id,
+ "created_by" => $this->currentName,
+ 'is_customer'=>true
+ );
+
+ $result = UserToProyek::create($dataInsert);
+
+ if($result){
+ $countRes++;
+ }else{
+ $countRes--;
+ }
+ }
+ if($countRes > 0){
+ return response()->json(['status'=>'success' ,'message'=>'Project customer successfull created','code'=>200]);
+ }else{
+ return response()->json(['status'=>'success' ,'message'=>'Project customer failed created','code'=>400]);
+ }
+ }else{
+ return response()->json(['status'=>'success' ,'message'=>'Project customer successfull created','code'=>200]);
+ }
+
+ }
+
+ public function edit($id){
+ if(!$id || (int) $id < 0 || $id==""){
+ return response()->json(['status'=>'failed','message'=>'id is required!','code'=>400], 400);
+ die();
+ }
+
+ $result = UserToProyek::find($id);
+
+ if($result){
+ return response()->json(['status'=>'success','code'=>200,'data'=>$result], 200);
+ }else{
+ return response()->json(['status'=>'failed','message'=>'failed get data assign hr to proyek, please try again later!','code'=>400], 400);
+ }
+ }
+
+ public function update(Request $request, $id)
+ {
+ if(!$id || (int) $id < 0 || $id==""){
+ return response()->json(['status'=>'failed','message'=>'id is required!','code'=>400], 400);
+ }
+
+ $data = UserToProyek::find($id);
+
+ if($data){
+ $result = $data->update($request->all());
+ }else{
+ return response()->json(['status'=>'failed','message'=>'data assign hr to proyek not found!','code'=>400], 400);
+ die();
+ }
+
+
+ if($result){
+ return response()->json(['status'=>'success','message'=>'data assign hr to proyek successfully updated!','code'=>200], 200);
+ }else{
+ return response()->json(['status'=>'failed','message'=>'data assign hr to proyek failed updated!','code'=>400], 400);
+ }
+ }
+
+ public function delete($id)
+ {
+ $data = UserToProyek::find($id);
+ if($data){
+ $userId = $data->user_id;
+ $proyekId = $data->proyek_id;
+ $delete = $data->delete();
+ if($delete){
+ $this->deleteRelative($proyekId, $userId);
+ }
+ }else{
+ return response()->json(['status'=>'failed','message'=>'data assign hr to proyek not found!','code'=>400], 400);
+ die();
+ }
+
+
+ if($delete){
+ return response()->json(['status'=>'success','message'=>'data assign hr to proyek successfully deleted!','code'=>200], 200);
+ }else{
+ return response()->json(['status'=>'failed','message'=>'data assign hr to proyek failed deleted!','code'=>400], 400);
+ }
+ }
+
+ private function deleteRelative($proyekId, $userId)
+ {
+ $uta = UserToActivity::where("proyek_id", $proyekId)->where("user_id", $userId)->get();
+ foreach ($uta as $value) {
+ $dataRa = ReportActivity::where("activity_id", $value->activity_id)->where("user_id", $value->user_id)->get();
+ foreach ($dataRa as $ra) {
+ $images = Image::where("ref_id", $ra->id)->where("category", "report_activity")->get();
+ foreach ($images as $image) {
+ if(file_exists($this->pathImage.$image->image)){
+ unlink($this->pathImage.$image->image);
+ }
+ }
+ Image::where("ref_id", $ra->id)->where("category", "report_activity")->delete();
+ }
+ ReportActivity::where("activity_id", $value->activity_id)->where("user_id", $value->user_id)->delete();
+ }
+ UserToActivity::where("proyek_id", $proyekId)->where("user_id", $userId)->delete();
+ }
+
+ public function search(Request $request)
+ {
+ $payload = $request->all();
+ $dataBuilder = $this->setUpPayload($payload, 'assign_hr_to_proyek');
+ $builder = $dataBuilder['builder'];
+ $countBuilder = $dataBuilder['count'];
+ $dataGet = $builder->get();
+ $totalRecord = $countBuilder->count();
+ return response()->json(['status'=>'success','code'=>200,'data'=>$dataGet, 'totalRecord'=>$totalRecord], 200);
+ }
+
+ public function list()
+ {
+ $data = UserToProyek::all();
+ $countData = $data->count();
+
+ if($data){
+ return response()->json(['status'=>'success','code'=>200,'data'=>$data, 'totalRecord'=>$countData], 200);
+ }else{
+ return response()->json(['status'=>'failed','message'=>'failed get list assign hr to proyek, please try again later!','code'=>400], 400);
+ }
+ }
+
+ public function select(Request $request){
+
+ $search = $request->query('search');
+
+ $idProyek = (int)$request->query('idProyek');
+ $idActivity = (int)$request->query('idact');
+
+ $include = [];
+
+ if($idActivity && $idActivity > 0){
+ $dataF = UserToActivity::select("user_id")->where("activity_id", $idActivity)->get();
+ foreach($dataF as $val){
+ $include[] = $val->user_id;
+ }
+ }
+
+ if($search && !empty($search)){
+ $data = UserToProyek::select("m_users.id as id", "m_users.name as name")->join('m_users', 'm_users.id', '=', 'assign_hr_to_proyek.user_id')
+ ->where("assign_hr_to_proyek.proyek_id", $idProyek)->where("m_users.name", 'like', '%'.$search.'%')->whereIn("m_users.id", $include)->get();
+ }else{
+ $data = UserToProyek::select("m_users.id as id", "m_users.name as name")->where("assign_hr_to_proyek.proyek_id", $idProyek)->join('m_users', 'm_users.id', '=', 'assign_hr_to_proyek.user_id')->whereIn("m_users.id", $include)->get();
+ }
+
+ if($data instanceof \Illuminate\Database\Eloquent\Collection){
+ $pm = array(
+ "id"=>$this->currentId,
+ "name"=> "Project Manager"
+ );
+ $data->push($pm);
+ }
+
+ return response()->json($data);
+ }
+
+ private function curlReq($url, $token){
+ $ch = curl_init();
+ $headers = [
+ 'Authorization: '.$token
+ ];
+ curl_setopt($ch, CURLOPT_URL, $url);
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+
+ $response = curl_exec($ch);
+ if ($response === false)
+ $response = curl_error($ch);
+ curl_close($ch);
+
+ return json_decode($response);
+ }
+
+ public function getEmployeeIntegration(Request $request) {
+ $search = urlencode($request->name);
+ if(empty($search))
+ return response()->json(['status'=>'error', 'message'=>'Empty query string!'], 400);
+ $url = str_replace("SEARCH", $search, config('api.adw').'/employees?emp_name=SEARCH');
+ $token = config('api.adw_token');
+ $firstResponse = $this->curlReq($url, $token);
+
+ if($firstResponse->total == 0)
+ return response()->json(['status'=>'error', 'message' => 'Data not found!', 'code'=>404], 404);
+
+ $data = $firstResponse->data;
+ return response()->json([$data]);
+ $currentPage = 1;
+
+ if($firstResponse->last_page > 0) {
+ do {
+ $currentPage++;
+ $response = $this->curlReq($url.'&page='.$currentPage, $token);
+ foreach($response->data as $d){
+ array_push($data, $d);
+ }
+ } while ($currentPage < $firstResponse->last_page);
+ }
+
+ return response()->json(['status'=>'success', 'data'=> $data, 'total' => count($data), 'code'=>200], 200);
+ }
+}
diff --git a/app/Http/Controllers/VersionGanttController.php b/app/Http/Controllers/VersionGanttController.php
index b66dc3f..c3fe398 100644
--- a/app/Http/Controllers/VersionGanttController.php
+++ b/app/Http/Controllers/VersionGanttController.php
@@ -1,119 +1,120 @@
-validate($request, [
- 'name_version' => 'required',
- 'proyek_id' => 'required'
- ]);
- $data = $request->all();
- $data['created_by'] = $this->currentName;
-
- $result = VersionGantt::create($data);
- if($result){
- return response()->json(['status'=>'success','message'=>'version gantt Project successfull created','code'=>200]);
- }else{
- return response()->json(['status'=>'failed','message'=>'version gantt Project failed created','code'=>400]);
- }
- }
-
- public function update(Request $request, $id){
-
- if(!$id || (int) $id < 0 || $id==""){
- return response()->json(['status'=>'failed','message'=>'id is required!','code'=>400], 400);
- }
- $data = VersionGantt::find($id);
- if($data){
- $result = $data->update($request->all());
- }else{
- return response()->json(['status'=>'failed','message'=>'data version gantt Project not found!','code'=>400], 400);
- die();
- }
-
- if($result){
- return response()->json(['status'=>'success','message'=>'version gantt Project successfully updated!','code'=>200], 200);
- }else{
- return response()->json(['status'=>'failed','message'=>'version gantt Project failed updated!','code'=>400], 400);
- }
- }
-
- public function delete($id)
- {
- $data = VersionGantt::find($id);
-
- if($data){
- $delete = $data->delete();
- }else{
- return response()->json(['status'=>'failed','message'=>'data version gantt Project not found!','code'=>400], 400);
- die();
- }
-
-
- if($delete){
- return response()->json(['status'=>'success','message'=>'version gantt Project successfully deleted!','code'=>200], 200);
- }else{
- return response()->json(['status'=>'failed','message'=>'version gantt Project failed deleted!','code'=>400], 400);
- }
- }
-
- public function edit($id){
- if(!$id || (int) $id < 0 || $id==""){
- return response()->json(['status'=>'failed','message'=>'id is required!','code'=>400], 400);
- die();
- }
-
- $result = VersionGantt::find($id);
-
- if($result){
- return response()->json(['status'=>'success','code'=>200,'data'=>$result], 200);
- }else{
- return response()->json(['status'=>'failed','message'=>'failed get data version gantt, please try again later!','code'=>400], 400);
- }
- }
-
- public function search(Request $request)
- {
- $payload = $request->all();
- $dataBuilder = $this->setUpPayload($payload, 'm_version_gantt');
- $builder = $dataBuilder['builder'];
- // $countBuilder = $dataBuilder['count'];
- $this->ganttProgress($request->columns[0]["name"], $request->columns[0]["value"]);
- $dataGet = $builder->get();
-
- // $totalRecord = $countBuilder->count();
- return response()->json(['status'=>'success','code'=>200,'data'=>$dataGet], 200);
- }
-
- public function ganttProgress($column, $value){
- $progress = VersionGantt::select('m_version_gantt.id','m_activity.persentase_progress')
- ->join('m_activity', 'm_version_gantt.id', '=', 'm_activity.version_gantt_id')
- ->where("m_version_gantt.".$column, $value)
- // ->where('m_activity.type_activity', "project")
- ->where('m_activity.parent_id', null)
- ->get();
- foreach($progress as $item) {
- if($item->persentase_progress){
- $item->progress = $item->persentase_progress;
- $item->save();
- }
- }
- }
-
- public function list()
- {
- $data = VersionGantt::all();
- $countData = $data->count();
-
- if($data){
- return response()->json(['status'=>'success','code'=>200,'data'=>$data, 'totalRecord'=>$countData], 200);
- }else{
- return response()->json(['status'=>'failed','message'=>'failed get list version gantt, please try again later!','code'=>400], 400);
- }
- }
-}
+validate($request, [
+ 'name_version' => 'required',
+ 'proyek_id' => 'required'
+ ]);
+ $data = $request->all();
+ $data['created_by'] = $this->currentName;
+
+ $result = VersionGantt::create($data);
+ if($result){
+ return response()->json(['status'=>'success','message'=>'version gantt Project successfull created','code'=>200]);
+ }else{
+ return response()->json(['status'=>'failed','message'=>'version gantt Project failed created','code'=>400]);
+ }
+ }
+
+ public function update(Request $request, $id){
+
+ if(!$id || (int) $id < 0 || $id==""){
+ return response()->json(['status'=>'failed','message'=>'id is required!','code'=>400], 400);
+ }
+ $data = VersionGantt::find($id);
+ if($data){
+ $result = $data->update($request->all());
+ }else{
+ return response()->json(['status'=>'failed','message'=>'data version gantt Project not found!','code'=>400], 400);
+ die();
+ }
+
+ if($result){
+ return response()->json(['status'=>'success','message'=>'version gantt Project successfully updated!','code'=>200], 200);
+ }else{
+ return response()->json(['status'=>'failed','message'=>'version gantt Project failed updated!','code'=>400], 400);
+ }
+ }
+
+ public function delete($id)
+ {
+ $data = VersionGantt::find($id);
+
+ if($data){
+ $delete = $data->delete();
+ }else{
+ return response()->json(['status'=>'failed','message'=>'data version gantt Project not found!','code'=>400], 400);
+ die();
+ }
+
+
+ if($delete){
+ return response()->json(['status'=>'success','message'=>'version gantt Project successfully deleted!','code'=>200], 200);
+ }else{
+ return response()->json(['status'=>'failed','message'=>'version gantt Project failed deleted!','code'=>400], 400);
+ }
+ }
+
+ public function edit($id){
+ if(!$id || (int) $id < 0 || $id==""){
+ return response()->json(['status'=>'failed','message'=>'id is required!','code'=>400], 400);
+ die();
+ }
+
+ $result = VersionGantt::find($id);
+
+ if($result){
+ return response()->json(['status'=>'success','code'=>200,'data'=>$result], 200);
+ }else{
+ return response()->json(['status'=>'failed','message'=>'failed get data version gantt, please try again later!','code'=>400], 400);
+ }
+ }
+
+ public function search(Request $request)
+ {
+ $payload = $request->all();
+ $dataBuilder = $this->setUpPayload($payload, 'm_version_gantt');
+ $builder = $dataBuilder['builder'];
+ // $countBuilder = $dataBuilder['count'];
+ $this->ganttProgress($request->columns[0]["name"], $request->columns[0]["value"]);
+ $dataGet = $builder->get();
+
+ // $totalRecord = $countBuilder->count();
+ return response()->json(['status'=>'success','code'=>200,'data'=>$dataGet], 200);
+ }
+
+ public function ganttProgress($column, $value){
+ $progress = VersionGantt::select('m_version_gantt.id','m_activity.persentase_progress', 'm_activity.bobot_planning')
+ ->join('m_activity', 'm_version_gantt.id', '=', 'm_activity.version_gantt_id')
+ ->where("m_version_gantt.".$column, $value)
+ // ->where('m_activity.type_activity', "project")
+ ->where('m_activity.parent_id', null)
+ ->get();
+ foreach($progress as $item) {
+ if($item->persentase_progress){
+ $item->progress = $item->persentase_progress;
+ $item->bobot = $item->bobot_planning;
+ $item->save();
+ }
+ }
+ }
+
+ public function list()
+ {
+ $data = VersionGantt::all();
+ $countData = $data->count();
+
+ if($data){
+ return response()->json(['status'=>'success','code'=>200,'data'=>$data, 'totalRecord'=>$countData], 200);
+ }else{
+ return response()->json(['status'=>'failed','message'=>'failed get list version gantt, please try again later!','code'=>400], 400);
+ }
+ }
+}
diff --git a/app/Jobs/ProcessSCurve.php b/app/Jobs/ProcessSCurve.php
new file mode 100644
index 0000000..fe07ab9
--- /dev/null
+++ b/app/Jobs/ProcessSCurve.php
@@ -0,0 +1,36 @@
+project = $project;
+ }
+
+ /**
+ * Execute the job.
+ *
+ * @return void
+ */
+ public function handle()
+ {
+ $data = MasterFunctionsHelper::CalculateSCurve($this->project->id);
+
+ $this->project->scurve = json_encode($data);
+ $this->project->calculation_status = true;
+ $this->project->save();
+ }
+}
diff --git a/app/Models/Activity.php b/app/Models/Activity.php
index ce49289..3a8e54c 100644
--- a/app/Models/Activity.php
+++ b/app/Models/Activity.php
@@ -1,234 +1,246 @@
-timezone(env('APP_TIMEZONE'))
- ->toDateTimeString();
- }
-
- public function getEndDateAttribute($value)
- {
- return Carbon::createFromTimestamp(strtotime($value))
- ->timezone(env('APP_TIMEZONE'))
- ->toDateTimeString();
- }
-
-
- public static function boot() {
- parent::boot();
-
- static::updating(function($data) {
- $data->logPersentaseProgress();
- });
-
- static::updated(function($data) {
- $data->updateBobot();
- $data->updateCostPlanning();
- if($data->bobot_planning){
- $data->updatePersentaseProgress();
- $data->updateCostActual();
- }
- // if($data->start_date != request()->start_date || $data->end_date != request()->end_date) {
- // $data->updateStartEndDateHeader();
- // }
- });
-
- static::deleted(function($data) {
- if(Activity::where("parent_id", $data->parent_id)->count() == 0)
- Activity::find($data->parent_id)->update(["type_activity"=>"task"]);
-
- $data->updateBobot(true);
- $data->updateCostPlanning();
- if($data->bobot_planning){
- $data->updatePersentaseProgress();
- $data->updateCostActual();
- }
- $data->updateStartEndDateHeader();
- });
-
- }
-
- private function updateBobot($isDelete = false)
- {
- $root = Activity::where('version_gantt_id', $this->version_gantt_id)
- ->where("proyek_id", $this->proyek_id)
- ->whereNull('parent_id')
- ->first();
-
- if($root->rencana_biaya > 0){
- $activities = Activity::where("proyek_id", $this->proyek_id)->where("version_gantt_id", $this->version_gantt_id)->get();
- foreach ($activities as $activity) {
- if($isDelete && $activity->id == $this->id)
- continue;
-
- $activity->bobot_planning = ( (int)$activity->rencana_biaya / $root->rencana_biaya) * 100;
- $activity->updated_by = auth()->user() ? auth()->user()->name : "system";
- $activity->saveQuietly();
-
- }
- } else {
- if($parent = Activity::find($this->parent_id)){
- $totalChildWeight = Activity::where("parent_id", $this->parent_id)->sum('bobot_planning');
- $parent->update([
- "bobot_planning" => $totalChildWeight
- ]);
- }
- }
- }
-
- private function updateCostActual()
- {
- $actualCost = Activity::where("parent_id", $this->parent_id)->sum("biaya_actual");
- $this->biaya_actual = $actualCost;
- if($parent = Activity::find($this->parent_id)){
- $parent->update([
- "biaya_actual" => $actualCost
- ]);
- }
- }
-
- private function updatePersentaseProgress()
- {
- if($parent = Activity::find($this->parent_id)){
- $parentActWeight = $parent->bobot_planning;
-
- if ($parentActWeight == 0) {
- $parent->update([
- "persentase_progress" => 0
- ]);
- return;
- }
-
- $totalChildProportionalProgress = 0;
- $childs = Activity::where("parent_id", $parent->id)->get();
- foreach($childs as $child){
- $currentActWeight = $child->bobot_planning;
- $currentActProportionalProgress = ($currentActWeight / $parentActWeight) * $child->persentase_progress;
- $totalChildProportionalProgress += $currentActProportionalProgress;
- }
- $parent->update([
- "persentase_progress" => $totalChildProportionalProgress
- ]);
- }
- }
-
- private function updateCostPlanning() {
- $sumBiaya = Activity::select(DB::raw('sum(cast(rencana_biaya as double precision))'))
- ->where("parent_id", $this->parent_id)
- ->first();
- $this->rencana_biaya = $sumBiaya->sum;
- if($parent = Activity::find($this->parent_id)){
- $parent->update([
- "rencana_biaya" => $sumBiaya->sum,
- ]);
- }
- }
-
- private function logPersentaseProgress()
- {
- ActivityProgressLog::create([
- 'version_gantt_id' => $this->version_gantt_id,
- 'activity_id' => request()->id,
- 'old_percentage' => $this->persentase_progress,
- 'new_percentage' => request()->persentase_progress,
- 'variance' => $this->persentase_progress - request()->persentase_progress,
- 'created_by'=> "system"
- ]);
- }
-
- private function updateStartEndDateHeader()
- {
- $earliestStartDate = Activity::where('version_gantt_id', $this->version_gantt_id)->whereNotNull('parent_id')->oldest('start_date')->pluck('start_date')->first();
- $latestEndDate = Activity::where('version_gantt_id', $this->version_gantt_id)->whereNotNull('parent_id')->latest('end_date')->pluck('end_date')->first();
- if($header = Activity::where('version_gantt_id', $this->version_gantt_id)->whereNull('parent_id')->first()) {
- $header->start_date = $earliestStartDate;
- $header->end_date = $latestEndDate;
- $header->saveQuietly();
- }
- }
-
- public function getJobsDoneAttribute()
- {
- if(!ReportActivityMaterial::where('activity_id', $this->id)->first())
- return 0;
- if(!$dataPlan = AssignMaterial::where('activity_id', $this->id)->get())
- return 0;
- if($dataPlan[0]->status_activity == 'done')
- return 100;
- return $this->persentase_progress;
- }
-
- public function getAssignHrAttribute()
- {
- return Arr::flatten(UserToActivity::select("u.name as name")
- ->join("m_users as u", "u.id", "=", "assign_hr_to_activity.user_id")
- ->where('assign_hr_to_activity.activity_id', $this->id)
- ->get()
- ->toArray());
- }
-
- public function getAssignMaterialAttribute()
- {
- return Arr::flatten(AssignMaterial::select("m.description as name")
- ->join("m_req_material as m", "m.id", "=", "assign_material_to_activity.material_id")
- ->where('assign_material_to_activity.activity_id', $this->id)
- ->where('assign_material_to_activity.type', "material")
- ->get()
- ->toArray());
- }
-
- public function getAssignExpenseAttribute()
- {
- return Arr::flatten(AssignMaterial::select("m.description as name")
- ->join("m_req_material as m", "m.id", "=", "assign_material_to_activity.material_id")
- ->where('assign_material_to_activity.activity_id', $this->id)
- ->where('assign_material_to_activity.type', "expense")
- ->get()
- ->toArray());
- }
-
- public function getAssignToolsAttribute()
- {
- return Arr::flatten(AssignTools::select("m.name as name")
- ->join("m_tools_resource as m", "m.id", "=", "assign_tools_to_activity.tools_id")
- ->where('assign_tools_to_activity.activity_id', $this->id)
- ->get()
- ->toArray());
- }
-
-}
+timezone(env('APP_TIMEZONE'))
+ ->toDateTimeString();
+ }
+ return Carbon::createFromTimestamp(strtotime($value))
+ ->timezone(env('APP_TIMEZONE'))
+ ->toDateTimeString();
+ }
+
+ public function getEndDateAttribute($value)
+ {
+ if ($value instanceof \DateTime) {
+ return Carbon::instance($value)
+ ->timezone(env('APP_TIMEZONE'))
+ ->toDateTimeString();
+ }
+ return Carbon::createFromTimestamp(strtotime($value))
+ ->timezone(env('APP_TIMEZONE'))
+ ->toDateTimeString();
+ }
+
+
+ public static function boot() {
+ parent::boot();
+
+ static::updating(function($data) {
+ $data->logPersentaseProgress();
+ });
+
+ static::updated(function($data) {
+ $data->updateBobot();
+ $data->updateCostPlanning();
+ if($data->bobot_planning){
+ $data->updatePersentaseProgress();
+ }
+ $data->updateCostActual();
+ // if($data->start_date != request()->start_date || $data->end_date != request()->end_date) {
+ // $data->updateStartEndDateHeader();
+ // }
+ });
+
+ static::deleted(function($data) {
+ if(Activity::where("parent_id", $data->parent_id)->count() == 0)
+ Activity::find($data->parent_id)->update(["type_activity"=>"task"]);
+
+ $data->updateBobot(true);
+ $data->updateCostPlanning();
+ if($data->bobot_planning){
+ $data->updatePersentaseProgress();
+ }
+ $data->updateCostActual();
+ $data->updateStartEndDateHeader();
+ });
+
+ }
+
+ private function updateBobot($isDelete = false)
+ {
+ $root = Activity::where('version_gantt_id', $this->version_gantt_id)
+ ->where("proyek_id", $this->proyek_id)
+ ->whereNull('parent_id')
+ ->first();
+
+ if($root->rencana_biaya > 0){
+ $activities = Activity::where("proyek_id", $this->proyek_id)->where("version_gantt_id", $this->version_gantt_id)->get();
+ foreach ($activities as $activity) {
+ if($isDelete && $activity->id == $this->id)
+ continue;
+
+ $activity->bobot_planning = ( (int)$activity->rencana_biaya / $root->rencana_biaya) * 100;
+ $activity->updated_by = auth()->user() ? auth()->user()->name : "system";
+ $activity->saveQuietly();
+
+ }
+ } else {
+ if($parent = Activity::find($this->parent_id)){
+ $totalChildWeight = Activity::where("parent_id", $this->parent_id)->sum('bobot_planning');
+ $parent->update([
+ "bobot_planning" => $totalChildWeight
+ ]);
+ }
+ }
+ }
+
+ private function updateCostActual()
+ {
+ $actualCost = Activity::where("parent_id", $this->parent_id)->sum("biaya_actual");
+ $this->biaya_actual = $actualCost;
+ if($parent = Activity::find($this->parent_id)){
+ $parent->update([
+ "biaya_actual" => $actualCost
+ ]);
+ }
+ }
+
+ private function updatePersentaseProgress()
+ {
+ if($parent = Activity::find($this->parent_id)){
+ $parentActWeight = $parent->bobot_planning;
+
+ if ($parentActWeight == 0) {
+ $parent->update([
+ "persentase_progress" => 0
+ ]);
+ return;
+ }
+
+ $totalChildProportionalProgress = 0;
+ $childs = Activity::where("parent_id", $parent->id)->get();
+ foreach($childs as $child){
+ $currentActWeight = $child->bobot_planning;
+ $currentActProportionalProgress = ($currentActWeight / $parentActWeight) * $child->persentase_progress;
+ $totalChildProportionalProgress += $currentActProportionalProgress;
+ }
+ $parent->update([
+ "persentase_progress" => $totalChildProportionalProgress
+ ]);
+ }
+ }
+
+ private function updateCostPlanning() {
+ $sumBiaya = Activity::select(DB::raw('sum(cast(rencana_biaya as double precision))'))
+ ->where("parent_id", $this->parent_id)
+ ->first();
+ $this->rencana_biaya = $sumBiaya->sum;
+ if($parent = Activity::find($this->parent_id)){
+ $parent->update([
+ "rencana_biaya" => $sumBiaya->sum,
+ ]);
+ }
+ }
+
+ private function logPersentaseProgress()
+ {
+ ActivityProgressLog::create([
+ 'version_gantt_id' => $this->version_gantt_id,
+ 'activity_id' => request()->id,
+ 'old_percentage' => $this->persentase_progress,
+ 'new_percentage' => request()->persentase_progress,
+ 'variance' => $this->persentase_progress - request()->persentase_progress,
+ 'created_by'=> "system"
+ ]);
+ }
+
+ private function updateStartEndDateHeader()
+ {
+ $earliestStartDate = Activity::where('version_gantt_id', $this->version_gantt_id)->whereNotNull('parent_id')->oldest('start_date')->pluck('start_date')->first();
+ $latestEndDate = Activity::where('version_gantt_id', $this->version_gantt_id)->whereNotNull('parent_id')->latest('end_date')->pluck('end_date')->first();
+ if($header = Activity::where('version_gantt_id', $this->version_gantt_id)->whereNull('parent_id')->first()) {
+ $header->start_date = $earliestStartDate;
+ $header->end_date = $latestEndDate;
+ $header->saveQuietly();
+ }
+ }
+
+ public function getJobsDoneAttribute()
+ {
+ if(!ReportActivityMaterial::where('activity_id', $this->id)->first())
+ return 0;
+ if(!$dataPlan = AssignMaterial::where('activity_id', $this->id)->get())
+ return 0;
+ if($dataPlan->isEmpty())
+ return 0;
+ if($dataPlan[0]->status_activity == 'done')
+ return 100;
+ return $this->persentase_progress;
+ }
+
+ public function getAssignHrAttribute()
+ {
+ return Arr::flatten(UserToActivity::select("u.name as name")
+ ->join("m_users as u", "u.id", "=", "assign_hr_to_activity.user_id")
+ ->where('assign_hr_to_activity.activity_id', $this->id)
+ ->get()
+ ->toArray());
+ }
+
+ public function getAssignMaterialAttribute()
+ {
+ return Arr::flatten(AssignMaterial::select("m.description as name")
+ ->join("m_req_material as m", "m.id", "=", "assign_material_to_activity.material_id")
+ ->where('assign_material_to_activity.activity_id', $this->id)
+ ->where('assign_material_to_activity.type', "material")
+ ->get()
+ ->toArray());
+ }
+
+ public function getAssignExpenseAttribute()
+ {
+ return Arr::flatten(AssignMaterial::select("m.description as name")
+ ->join("m_req_material as m", "m.id", "=", "assign_material_to_activity.material_id")
+ ->where('assign_material_to_activity.activity_id', $this->id)
+ ->where('assign_material_to_activity.type', "expense")
+ ->get()
+ ->toArray());
+ }
+
+ public function getAssignToolsAttribute()
+ {
+ return Arr::flatten(AssignTools::select("m.name as name")
+ ->join("m_tools_resource as m", "m.id", "=", "assign_tools_to_activity.tools_id")
+ ->where('assign_tools_to_activity.activity_id', $this->id)
+ ->get()
+ ->toArray());
+ }
+
+}
diff --git a/app/Models/AssignMaterial.php b/app/Models/AssignMaterial.php
index 5cb8bc5..09620ee 100644
--- a/app/Models/AssignMaterial.php
+++ b/app/Models/AssignMaterial.php
@@ -1,44 +1,46 @@
- 'integer',
- 'budget' => 'string',
- ];
-
- public static function boot() {
- parent::boot();
-
- static::created(function($data) {
- $activity = Activity::find($data->activity_id);
- $material = RequestMaterial::where("id", $data->material_id)->first();
- $activity->rencana_biaya += floatval($material->price) * floatval($data->qty_planning);
- $activity->save();
- });
-
- static::deleted(function($data) {
- $activity = Activity::where('id', $data->activity_id)->first();
- $activity->rencana_biaya -= floatval($data->budget) * floatval($data->qty_planning);
- $activity->save();
- });
-
- }
-}
+ 'integer',
+ 'budget' => 'string',
+ ];
+
+ public static function boot() {
+ parent::boot();
+
+ static::created(function($data) {
+ $activity = Activity::find($data->activity_id);
+ $material = RequestMaterial::where("id", $data->material_id)->first();
+ $activity->rencana_biaya += floatval($material->price) * floatval($data->qty_planning);
+ $activity->save();
+ });
+
+ static::deleted(function($data) {
+ $reportActivities = ReportActivityMaterial::where('assign_material_id', $data->id)->delete();
+ $activity = Activity::where('id', $data->activity_id)->first();
+ $activity->rencana_biaya -= floatval($data->budget) * floatval($data->qty_planning);
+ $activity->save();
+ });
+
+ }
+}
diff --git a/app/Models/Broadcast.php b/app/Models/Broadcast.php
index c2767c9..bacbdcd 100644
--- a/app/Models/Broadcast.php
+++ b/app/Models/Broadcast.php
@@ -12,6 +12,6 @@ class Broadcast extends Model
const UPDATED_AT = 'updated_at';
protected $fillable = [
- 'title_notif', 'message_notif', 'description', 'send_to_type', 'created_at', 'created_by', 'updated_at', 'updated_by'
+ 'title_notif', 'message_notif', 'description', 'send_to_type', 'send_to_id', 'status_send', 'created_at', 'created_by', 'updated_at', 'updated_by'
];
}
diff --git a/app/Models/Divisi.php b/app/Models/Divisi.php
index 5a37c85..ac255f4 100644
--- a/app/Models/Divisi.php
+++ b/app/Models/Divisi.php
@@ -1,41 +1,42 @@
-children()->delete();
- });
- }
-
- public function parent()
- {
- return $this->belongsTo('App\Models\Divisi','parent')->where('parent', null)->with('parent');
- }
-
- public function children()
- {
- return $this->hasMany('App\Models\Divisi','parent')->with('children');
- }
-}
+children()->delete();
+ });
+ }
+
+ public function parent()
+ {
+ return $this->belongsTo('App\Models\Divisi','parent')->where('parent', null)->with('parent');
+ }
+
+ public function children()
+ {
+ return $this->hasMany('App\Models\Divisi','parent')->with('children');
+ }
+}
diff --git a/app/Models/HierarchyFtth.php b/app/Models/HierarchyFtth.php
index 9a94bfc..fae503c 100644
--- a/app/Models/HierarchyFtth.php
+++ b/app/Models/HierarchyFtth.php
@@ -12,6 +12,17 @@ class HierarchyFtth extends Model
const UPDATED_AT = 'updated_at';
protected $fillable = [
- 'name', 'parent_id', 'project_id', 'created_at', 'updated_at', 'progress'
+ 'name', 'parent_id', 'project_id', 'created_at', 'updated_at', 'progress', 'bobot_planning'
];
+
+ public static function boot() {
+ parent::boot();
+
+ static::deleted(function($data) {
+ $ftths = HierarchyFtth::where('parent_id', $data->id)->get();
+ foreach ($ftths as $ftth) {
+ $ftth->delete();
+ }
+ });
+ }
}
diff --git a/app/Models/Project.php b/app/Models/Project.php
index 452dd62..cf2d0ad 100644
--- a/app/Models/Project.php
+++ b/app/Models/Project.php
@@ -1,52 +1,54 @@
-timezone(env('APP_TIMEZONE'))
- ->toDateTimeString();
- }
-
- public static function boot() {
- parent::boot();
-
- static::created(function($data) {
- $activity = Activity::find($data->activity_id);
- $assignedMaterial = AssignMaterial::find($data->assign_material_id);
-
- $biayaActual = $activity->biaya_actual + floatval($assignedMaterial->budget) * floatval($data->qty);
-
- $dataPlan = AssignMaterial::where('activity_id', $activity->id)->get();
- if($dataPlan[0]->status_activity == 'done'){
- $percentage = 100;
- } else {
- $totalPlan = $dataPlan->sum('qty_planning');
- $totalVolumeActual = ReportActivityMaterial::where('activity_id', '=', $activity->id)->sum("qty");
- $percentage = ($totalVolumeActual * 100) / $totalPlan;
- $percentage = $percentage >= config('app.max_percentage_not_done') ? config('app.max_percentage_not_done') : $percentage;
- }
-
- $activity->update([
- "persentase_progress" => $percentage,
- "biaya_actual" => $biayaActual,
- ]);
-
- $activity->save();
- });
-
- static::deleted(function($data) {
-
- $activity = Activity::find($data->activity_id);
- $assignedMaterial = AssignMaterial::find($data->assign_material_id);
-
- $activity->biaya_actual -= floatval($assignedMaterial->budget) * floatval($data->qty);
-
- $dataPlan = AssignMaterial::where('activity_id', $activity->id)->get();
- if($dataPlan[0]->status_activity == 'done'){
- $activity->persentase_progress = 100;
- } else {
- $totalPlan = $dataPlan->sum('qty_planning');
- $totalVolumeActual = ReportActivityMaterial::where('activity_id', '=', $activity->id)->sum("qty");
- $percentage = ($totalVolumeActual * 100) / $totalPlan;
- $activity->persentase_progress = $percentage >= config('app.max_percentage_not_done') ? config('app.max_percentage_not_done') : $percentage;
- }
-
- $activity->save();
-
- });
-
- }
-}
+timezone(env('APP_TIMEZONE'))
+ ->toDateTimeString();
+ }
+
+ public static function boot() {
+ parent::boot();
+
+ static::created(function($data) {
+ $activity = Activity::find($data->activity_id);
+ $assignedMaterial = AssignMaterial::find($data->assign_material_id);
+
+ $biayaActual = $activity->biaya_actual + floatval($assignedMaterial->budget) * floatval($data->qty);
+
+ $dataPlan = AssignMaterial::where('activity_id', $activity->id)->get();
+ if($dataPlan[0]->status_activity == 'done'){
+ $percentage = 100;
+ } else {
+ $totalPlan = $dataPlan->sum('qty_planning');
+ $totalVolumeActual = ReportActivityMaterial::where('activity_id', '=', $activity->id)->sum("qty");
+ $percentage = ($totalVolumeActual * 100) / $totalPlan;
+ $percentage = $percentage >= config('app.max_percentage_not_done') ? config('app.max_percentage_not_done') : $percentage;
+ }
+
+ $activity->update([
+ "persentase_progress" => $percentage,
+ "biaya_actual" => $biayaActual,
+ ]);
+
+ $activity->save();
+ });
+
+ static::deleted(function($data) {
+
+ $activity = Activity::find($data->activity_id);
+ $assignedMaterial = AssignMaterial::find($data->assign_material_id);
+
+ $activity->biaya_actual -= floatval($assignedMaterial->budget) * floatval($data->qty);
+ $activity->actual_start = null;
+ $activity->actual_end = null;
+
+ $dataPlan = AssignMaterial::where('activity_id', $activity->id)->get();
+ $totalPlan = $dataPlan->sum('qty_planning');
+ $totalVolumeActual = ReportActivityMaterial::where('activity_id', '=', $activity->id)->sum("qty");
+ $percentage = ($totalVolumeActual * 100) / $totalPlan;
+ $activity->persentase_progress = $percentage >= config('app.max_percentage_not_done') ? config('app.max_percentage_not_done') : $percentage;
+ $activity->save();
+
+ });
+
+ }
+}
diff --git a/app/Models/Role.php b/app/Models/Role.php
index 3c0f409..73de4a2 100644
--- a/app/Models/Role.php
+++ b/app/Models/Role.php
@@ -1,17 +1,17 @@
-activity_id);
- $getWorkingHours = UserToProyek::where('user_id', $data->user_id)->where('proyek_id', $activity->proyek_id)->first();
-
- $salary = ($getWorkingHours->standart_rate * $activity->duration) * ($getWorkingHours->max_used / 100);
-
- if($getWorkingHours->uom_standart_rate == "Hour")
- $salary = ($getWorkingHours->standart_rate * 8) * $activity->duration * ($getWorkingHours->max_used / 100);
-
- $activity->rencana_biaya += $salary;
- $activity->save();
- });
-
- static::deleted(function($data) {
- $activity = Activity::find($data->activity_id);
-
- $getWorkingHours = UserToProyek::where('user_id', $data->user_id)->where('proyek_id', $activity->proyek_id)->first();
- $salary = ($getWorkingHours->standart_rate * $activity->duration) * ($getWorkingHours->max_used / 100);
- if($getWorkingHours->uom_standart_rate == "Hour"){
- $salary = ($getWorkingHours->standart_rate * 8) * $activity->duration * ($getWorkingHours->max_used / 100);
- }
-
- $activity->rencana_biaya -= $salary;
- if ($activity->rencana_biaya < 0) {
- $activity->rencana_biaya = 0;
- }
- $activity->save();
- });
-
- }
-
-}
+activity_id);
+ $getWorkingHours = UserToProyek::where('user_id', $data->user_id)->where('proyek_id', $activity->proyek_id)->first();
+
+ $salary = ($getWorkingHours->standart_rate * $activity->duration) * ($getWorkingHours->max_used / 100);
+
+ if($getWorkingHours->uom_standart_rate == "Hour")
+ $salary = ($getWorkingHours->standart_rate * 8) * $activity->duration * ($getWorkingHours->max_used / 100);
+
+ $activity->rencana_biaya += $salary;
+ $activity->save();
+ });
+
+ static::deleted(function($data) {
+ $activity = Activity::find($data->activity_id);
+
+ $getWorkingHours = UserToProyek::where('user_id', $data->user_id)->where('proyek_id', $activity->proyek_id)->first();
+ $salary = ($getWorkingHours->standart_rate * $activity->duration) * ($getWorkingHours->max_used / 100);
+ if($getWorkingHours->uom_standart_rate == "Hour"){
+ $salary = ($getWorkingHours->standart_rate * 8) * $activity->duration * ($getWorkingHours->max_used / 100);
+ }
+
+ $activity->rencana_biaya -= $salary;
+ if ($activity->rencana_biaya < 0) {
+ $activity->rencana_biaya = 0;
+ }
+ $activity->save();
+ });
+
+ }
+
+}
diff --git a/app/Models/UserToProyek.php b/app/Models/UserToProyek.php
index eb80c9b..8076ff9 100644
--- a/app/Models/UserToProyek.php
+++ b/app/Models/UserToProyek.php
@@ -1,19 +1,19 @@
-updateActDuration();
+ });
+ }
+
+ public function updateActDuration(){
+ $daysOff = explode(',', $this->config_dayoff);
+ if (in_array('0', $daysOff)) {
+ $key = array_search('0', $daysOff, false);
+ $daysOff[$key] = '7';
+ }
+ $activities = Activity::where('version_gantt_id', $this->id)->get();
+ foreach ($activities as $value) {
+ $exist = Link::where('t_activity_id', $value->id)->exists();
+ $startDate = new DateTime($value->start_date);
+ $endDate = new DateTime($value->end_date);
+ $duration = $endDate->diff($startDate)->days + 1;
+ if ($exist) {
+ $duration--;
+ }
+
+ // Iterate through each day and subtract the days off
+ for ($i = 0; $i < $duration; $i++) {
+ $currentDate = clone $startDate;
+ $currentDate->modify("+$i day");
+
+ $currentDayOfWeek = $currentDate->format('N'); // Get the day of the week (1 - Monday, 7 - Sunday)
+
+ if (in_array($currentDayOfWeek, $daysOff)) {
+ $duration--; // Subtract one day from the duration for each day off
+ }
+ }
+
+ // Update the activity duration
+ $value->duration = $duration;
+ $value->save();
+ }
+ }
}
diff --git a/app/Services/FCMService.php b/app/Services/FCMService.php
new file mode 100644
index 0000000..3fdf971
--- /dev/null
+++ b/app/Services/FCMService.php
@@ -0,0 +1,49 @@
+ [$fcm_token],
+ "notification" => [
+ "title" => $notification['title'],
+ "body" => $notification['body'],
+ ]
+ ];
+ $encodedData = json_encode($data);
+
+ $headers = [
+ 'Authorization:key=' . $serverKey,
+ 'Content-Type: application/json',
+ ];
+
+ $ch = curl_init();
+
+ curl_setopt($ch, CURLOPT_URL, $url);
+ curl_setopt($ch, CURLOPT_POST, true);
+ curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
+ curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
+ // Disabling SSL Certificate support temporarly
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $encodedData);
+
+ $result = curl_exec($ch);
+ if ($result === FALSE) {
+ return array("success"=> false, "message"=> curl_error($ch));
+ }
+ // Close connection
+ curl_close($ch);
+ return array("success"=> true, "message"=> $result);
+ }
+}
\ No newline at end of file
diff --git a/bootstrap/app.php b/bootstrap/app.php
index af68fb8..13cdeb8 100644
--- a/bootstrap/app.php
+++ b/bootstrap/app.php
@@ -63,6 +63,7 @@ $app->configure('auth');
$app->configure('api');
$app->configure('assets');
$app->configure('app');
+$app->configure('fcm');
/*
|--------------------------------------------------------------------------
diff --git a/config/api.php b/config/api.php
index 4a6fad5..bb3c62a 100644
--- a/config/api.php
+++ b/config/api.php
@@ -2,6 +2,6 @@
return [
'nominatim' => env('API_NOMINATIM', 'https://nominatim.oslogdev.com'),
'adw' => env('API_ADW', 'http://ospro-api.adyawinsa.com:9083/api'),
- 'adw_token' => env('API_ADW_TOKEN', 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiIxMjAyIiwiZXhwIjoxNjkxODMwNDkzfQ.DvBQIOZsdFndWsliPCZT65Y6G5Xx4vWBKz8Rhe7rvRA')
+ 'adw_token' => env('API_ADW_TOKEN', 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiIxMjAyIiwiZXhwIjoxNzI0Mzk1NTExfQ.z9_Q7vjZbcbr8Mook4EmlOuOByNP12_DEDSabf0zanU')
];
?>
diff --git a/config/fcm.php b/config/fcm.php
new file mode 100644
index 0000000..5c60ec9
--- /dev/null
+++ b/config/fcm.php
@@ -0,0 +1,5 @@
+ "AAAAin2zZmc:APA91bHFIYDzZGyVyXvt2C8I09wC2k8siWPQIo4b1Db0QjxCzQR5SRQU9KY1iNRIUhTL6OoLUs2x6UAiP1BNv-mwOlSR7C_405msoNL2p33JVBxrtqc7hdMc5TEdTBB4ZGRVH7ltQzSe",
+];
\ No newline at end of file
diff --git a/database/migrations/2023_08_29_130624_create_jobs_table.php b/database/migrations/2023_08_29_130624_create_jobs_table.php
new file mode 100644
index 0000000..1be9e8a
--- /dev/null
+++ b/database/migrations/2023_08_29_130624_create_jobs_table.php
@@ -0,0 +1,36 @@
+bigIncrements('id');
+ $table->string('queue')->index();
+ $table->longText('payload');
+ $table->unsignedTinyInteger('attempts');
+ $table->unsignedInteger('reserved_at')->nullable();
+ $table->unsignedInteger('available_at');
+ $table->unsignedInteger('created_at');
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ *
+ * @return void
+ */
+ public function down()
+ {
+ Schema::dropIfExists('jobs');
+ }
+}
diff --git a/docker/nginx/conf.d/default.conf b/docker/nginx/conf.d/default.conf
index e3e292a..f311b54 100644
--- a/docker/nginx/conf.d/default.conf
+++ b/docker/nginx/conf.d/default.conf
@@ -15,6 +15,15 @@ server {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
+
+ client_max_body_size 100M;
+ client_body_buffer_size 5M;
+ fastcgi_read_timeout 900;
+ keepalive_timeout 900;
+ send_timeout 300;
+ proxy_read_timeout 900;
+ proxy_connect_timeout 900;
+ proxy_send_timeout 900;
}
location / {
diff --git a/docker/php/php.ini b/docker/php/php.ini
new file mode 100644
index 0000000..efc483f
--- /dev/null
+++ b/docker/php/php.ini
@@ -0,0 +1,1947 @@
+[PHP]
+
+;;;;;;;;;;;;;;;;;;;
+; About php.ini ;
+;;;;;;;;;;;;;;;;;;;
+; PHP's initialization file, generally called php.ini, is responsible for
+; configuring many of the aspects of PHP's behavior.
+
+; PHP attempts to find and load this configuration from a number of locations.
+; The following is a summary of its search order:
+; 1. SAPI module specific location.
+; 2. The PHPRC environment variable. (As of PHP 5.2.0)
+; 3. A number of predefined registry keys on Windows (As of PHP 5.2.0)
+; 4. Current working directory (except CLI)
+; 5. The web server's directory (for SAPI modules), or directory of PHP
+; (otherwise in Windows)
+; 6. The directory from the --with-config-file-path compile time option, or the
+; Windows directory (usually C:\windows)
+; See the PHP docs for more specific information.
+; http://php.net/configuration.file
+
+; The syntax of the file is extremely simple. Whitespace and lines
+; beginning with a semicolon are silently ignored (as you probably guessed).
+; Section headers (e.g. [Foo]) are also silently ignored, even though
+; they might mean something in the future.
+
+; Directives following the section heading [PATH=/www/mysite] only
+; apply to PHP files in the /www/mysite directory. Directives
+; following the section heading [HOST=www.example.com] only apply to
+; PHP files served from www.example.com. Directives set in these
+; special sections cannot be overridden by user-defined INI files or
+; at runtime. Currently, [PATH=] and [HOST=] sections only work under
+; CGI/FastCGI.
+; http://php.net/ini.sections
+
+; Directives are specified using the following syntax:
+; directive = value
+; Directive names are *case sensitive* - foo=bar is different from FOO=bar.
+; Directives are variables used to configure PHP or PHP extensions.
+; There is no name validation. If PHP can't find an expected
+; directive because it is not set or is mistyped, a default value will be used.
+
+; The value can be a string, a number, a PHP constant (e.g. E_ALL or M_PI), one
+; of the INI constants (On, Off, True, False, Yes, No and None) or an expression
+; (e.g. E_ALL & ~E_NOTICE), a quoted string ("bar"), or a reference to a
+; previously set variable or directive (e.g. ${foo})
+
+; Expressions in the INI file are limited to bitwise operators and parentheses:
+; | bitwise OR
+; ^ bitwise XOR
+; & bitwise AND
+; ~ bitwise NOT
+; ! boolean NOT
+
+; Boolean flags can be turned on using the values 1, On, True or Yes.
+; They can be turned off using the values 0, Off, False or No.
+
+; An empty string can be denoted by simply not writing anything after the equal
+; sign, or by using the None keyword:
+
+; foo = ; sets foo to an empty string
+; foo = None ; sets foo to an empty string
+; foo = "None" ; sets foo to the string 'None'
+
+; If you use constants in your value, and these constants belong to a
+; dynamically loaded extension (either a PHP extension or a Zend extension),
+; you may only use these constants *after* the line that loads the extension.
+
+;;;;;;;;;;;;;;;;;;;
+; About this file ;
+;;;;;;;;;;;;;;;;;;;
+; PHP comes packaged with two INI files. One that is recommended to be used
+; in production environments and one that is recommended to be used in
+; development environments.
+
+; php.ini-production contains settings which hold security, performance and
+; best practices at its core. But please be aware, these settings may break
+; compatibility with older or less security conscience applications. We
+; recommending using the production ini in production and testing environments.
+
+; php.ini-development is very similar to its production variant, except it is
+; much more verbose when it comes to errors. We recommend using the
+; development version only in development environments, as errors shown to
+; application users can inadvertently leak otherwise secure information.
+
+; This is the php.ini-production INI file.
+
+;;;;;;;;;;;;;;;;;;;
+; Quick Reference ;
+;;;;;;;;;;;;;;;;;;;
+; The following are all the settings which are different in either the production
+; or development versions of the INIs with respect to PHP's default behavior.
+; Please see the actual settings later in the document for more details as to why
+; we recommend these changes in PHP's behavior.
+
+; display_errors
+; Default Value: On
+; Development Value: On
+; Production Value: Off
+
+; display_startup_errors
+; Default Value: Off
+; Development Value: On
+; Production Value: Off
+
+; error_reporting
+; Default Value: E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED
+; Development Value: E_ALL
+; Production Value: E_ALL & ~E_DEPRECATED & ~E_STRICT
+
+; log_errors
+; Default Value: Off
+; Development Value: On
+; Production Value: On
+
+; max_input_time
+; Default Value: -1 (Unlimited)
+; Development Value: 60 (60 seconds)
+; Production Value: 60 (60 seconds)
+
+; output_buffering
+; Default Value: Off
+; Development Value: 4096
+; Production Value: 4096
+
+; register_argc_argv
+; Default Value: On
+; Development Value: Off
+; Production Value: Off
+
+; request_order
+; Default Value: None
+; Development Value: "GP"
+; Production Value: "GP"
+
+; session.gc_divisor
+; Default Value: 100
+; Development Value: 1000
+; Production Value: 1000
+
+; session.sid_bits_per_character
+; Default Value: 4
+; Development Value: 5
+; Production Value: 5
+
+; short_open_tag
+; Default Value: On
+; Development Value: Off
+; Production Value: Off
+
+; variables_order
+; Default Value: "EGPCS"
+; Development Value: "GPCS"
+; Production Value: "GPCS"
+
+;;;;;;;;;;;;;;;;;;;;
+; php.ini Options ;
+;;;;;;;;;;;;;;;;;;;;
+; Name for user-defined php.ini (.htaccess) files. Default is ".user.ini"
+;user_ini.filename = ".user.ini"
+
+; To disable this feature set this option to an empty value
+;user_ini.filename =
+
+; TTL for user-defined php.ini files (time-to-live) in seconds. Default is 300 seconds (5 minutes)
+;user_ini.cache_ttl = 300
+
+;;;;;;;;;;;;;;;;;;;;
+; Language Options ;
+;;;;;;;;;;;;;;;;;;;;
+
+; Enable the PHP scripting language engine under Apache.
+; http://php.net/engine
+engine = On
+
+; This directive determines whether or not PHP will recognize code between
+; and ?> tags as PHP source which should be processed as such. It is
+; generally recommended that should be used and that this feature
+; should be disabled, as enabling it may result in issues when generating XML
+; documents, however this remains supported for backward compatibility reasons.
+; Note that this directive does not control the = shorthand tag, which can be
+; used regardless of this directive.
+; Default Value: On
+; Development Value: Off
+; Production Value: Off
+; http://php.net/short-open-tag
+short_open_tag = Off
+
+; The number of significant digits displayed in floating point numbers.
+; http://php.net/precision
+precision = 14
+
+; Output buffering is a mechanism for controlling how much output data
+; (excluding headers and cookies) PHP should keep internally before pushing that
+; data to the client. If your application's output exceeds this setting, PHP
+; will send that data in chunks of roughly the size you specify.
+; Turning on this setting and managing its maximum buffer size can yield some
+; interesting side-effects depending on your application and web server.
+; You may be able to send headers and cookies after you've already sent output
+; through print or echo. You also may see performance benefits if your server is
+; emitting less packets due to buffered output versus PHP streaming the output
+; as it gets it. On production servers, 4096 bytes is a good setting for performance
+; reasons.
+; Note: Output buffering can also be controlled via Output Buffering Control
+; functions.
+; Possible Values:
+; On = Enabled and buffer is unlimited. (Use with caution)
+; Off = Disabled
+; Integer = Enables the buffer and sets its maximum size in bytes.
+; Note: This directive is hardcoded to Off for the CLI SAPI
+; Default Value: Off
+; Development Value: 4096
+; Production Value: 4096
+; http://php.net/output-buffering
+output_buffering = 4096
+
+; You can redirect all of the output of your scripts to a function. For
+; example, if you set output_handler to "mb_output_handler", character
+; encoding will be transparently converted to the specified encoding.
+; Setting any output handler automatically turns on output buffering.
+; Note: People who wrote portable scripts should not depend on this ini
+; directive. Instead, explicitly set the output handler using ob_start().
+; Using this ini directive may cause problems unless you know what script
+; is doing.
+; Note: You cannot use both "mb_output_handler" with "ob_iconv_handler"
+; and you cannot use both "ob_gzhandler" and "zlib.output_compression".
+; Note: output_handler must be empty if this is set 'On' !!!!
+; Instead you must use zlib.output_handler.
+; http://php.net/output-handler
+;output_handler =
+
+; URL rewriter function rewrites URL on the fly by using
+; output buffer. You can set target tags by this configuration.
+; "form" tag is special tag. It will add hidden input tag to pass values.
+; Refer to session.trans_sid_tags for usage.
+; Default Value: "form="
+; Development Value: "form="
+; Production Value: "form="
+;url_rewriter.tags
+
+; URL rewriter will not rewrite absolute URL nor form by default. To enable
+; absolute URL rewrite, allowed hosts must be defined at RUNTIME.
+; Refer to session.trans_sid_hosts for more details.
+; Default Value: ""
+; Development Value: ""
+; Production Value: ""
+;url_rewriter.hosts
+
+; Transparent output compression using the zlib library
+; Valid values for this option are 'off', 'on', or a specific buffer size
+; to be used for compression (default is 4KB)
+; Note: Resulting chunk size may vary due to nature of compression. PHP
+; outputs chunks that are few hundreds bytes each as a result of
+; compression. If you prefer a larger chunk size for better
+; performance, enable output_buffering in addition.
+; Note: You need to use zlib.output_handler instead of the standard
+; output_handler, or otherwise the output will be corrupted.
+; http://php.net/zlib.output-compression
+zlib.output_compression = Off
+
+; http://php.net/zlib.output-compression-level
+;zlib.output_compression_level = -1
+
+; You cannot specify additional output handlers if zlib.output_compression
+; is activated here. This setting does the same as output_handler but in
+; a different order.
+; http://php.net/zlib.output-handler
+;zlib.output_handler =
+
+; Implicit flush tells PHP to tell the output layer to flush itself
+; automatically after every output block. This is equivalent to calling the
+; PHP function flush() after each and every call to print() or echo() and each
+; and every HTML block. Turning this option on has serious performance
+; implications and is generally recommended for debugging purposes only.
+; http://php.net/implicit-flush
+; Note: This directive is hardcoded to On for the CLI SAPI
+implicit_flush = Off
+
+; The unserialize callback function will be called (with the undefined class'
+; name as parameter), if the unserializer finds an undefined class
+; which should be instantiated. A warning appears if the specified function is
+; not defined, or if the function doesn't include/implement the missing class.
+; So only set this entry, if you really want to implement such a
+; callback-function.
+unserialize_callback_func =
+
+; The unserialize_max_depth specifies the default depth limit for unserialized
+; structures. Setting the depth limit too high may result in stack overflows
+; during unserialization. The unserialize_max_depth ini setting can be
+; overridden by the max_depth option on individual unserialize() calls.
+; A value of 0 disables the depth limit.
+;unserialize_max_depth = 4096
+
+; When floats & doubles are serialized, store serialize_precision significant
+; digits after the floating point. The default value ensures that when floats
+; are decoded with unserialize, the data will remain the same.
+; The value is also used for json_encode when encoding double values.
+; If -1 is used, then dtoa mode 0 is used which automatically select the best
+; precision.
+serialize_precision = -1
+
+; open_basedir, if set, limits all file operations to the defined directory
+; and below. This directive makes most sense if used in a per-directory
+; or per-virtualhost web server configuration file.
+; Note: disables the realpath cache
+; http://php.net/open-basedir
+;open_basedir =
+
+; This directive allows you to disable certain functions.
+; It receives a comma-delimited list of function names.
+; http://php.net/disable-functions
+disable_functions =
+
+; This directive allows you to disable certain classes.
+; It receives a comma-delimited list of class names.
+; http://php.net/disable-classes
+disable_classes =
+
+; Colors for Syntax Highlighting mode. Anything that's acceptable in
+; would work.
+; http://php.net/syntax-highlighting
+;highlight.string = #DD0000
+;highlight.comment = #FF9900
+;highlight.keyword = #007700
+;highlight.default = #0000BB
+;highlight.html = #000000
+
+; If enabled, the request will be allowed to complete even if the user aborts
+; the request. Consider enabling it if executing long requests, which may end up
+; being interrupted by the user or a browser timing out. PHP's default behavior
+; is to disable this feature.
+; http://php.net/ignore-user-abort
+;ignore_user_abort = On
+
+; Determines the size of the realpath cache to be used by PHP. This value should
+; be increased on systems where PHP opens many files to reflect the quantity of
+; the file operations performed.
+; Note: if open_basedir is set, the cache is disabled
+; http://php.net/realpath-cache-size
+;realpath_cache_size = 4096k
+
+; Duration of time, in seconds for which to cache realpath information for a given
+; file or directory. For systems with rarely changing files, consider increasing this
+; value.
+; http://php.net/realpath-cache-ttl
+;realpath_cache_ttl = 120
+
+; Enables or disables the circular reference collector.
+; http://php.net/zend.enable-gc
+zend.enable_gc = On
+
+; If enabled, scripts may be written in encodings that are incompatible with
+; the scanner. CP936, Big5, CP949 and Shift_JIS are the examples of such
+; encodings. To use this feature, mbstring extension must be enabled.
+; Default: Off
+;zend.multibyte = Off
+
+; Allows to set the default encoding for the scripts. This value will be used
+; unless "declare(encoding=...)" directive appears at the top of the script.
+; Only affects if zend.multibyte is set.
+; Default: ""
+;zend.script_encoding =
+
+; Allows to include or exclude arguments from stack traces generated for exceptions.
+; In production, it is recommended to turn this setting on to prohibit the output
+; of sensitive information in stack traces
+; Default: Off
+zend.exception_ignore_args = On
+
+;;;;;;;;;;;;;;;;;
+; Miscellaneous ;
+;;;;;;;;;;;;;;;;;
+
+; Decides whether PHP may expose the fact that it is installed on the server
+; (e.g. by adding its signature to the Web server header). It is no security
+; threat in any way, but it makes it possible to determine whether you use PHP
+; on your server or not.
+; http://php.net/expose-php
+expose_php = On
+
+;;;;;;;;;;;;;;;;;;;
+; Resource Limits ;
+;;;;;;;;;;;;;;;;;;;
+
+; Maximum execution time of each script, in seconds
+; http://php.net/max-execution-time
+; Note: This directive is hardcoded to 0 for the CLI SAPI
+max_execution_time = 300
+
+; Maximum amount of time each script may spend parsing request data. It's a good
+; idea to limit this time on productions servers in order to eliminate unexpectedly
+; long running scripts.
+; Note: This directive is hardcoded to -1 for the CLI SAPI
+; Default Value: -1 (Unlimited)
+; Development Value: 60 (60 seconds)
+; Production Value: 60 (60 seconds)
+; http://php.net/max-input-time
+max_input_time = 300
+
+; Maximum input variable nesting level
+; http://php.net/max-input-nesting-level
+;max_input_nesting_level = 64
+
+; How many GET/POST/COOKIE input variables may be accepted
+;max_input_vars = 1000
+
+; Maximum amount of memory a script may consume
+; http://php.net/memory-limit
+memory_limit = 128M
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Error handling and logging ;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+; This directive informs PHP of which errors, warnings and notices you would like
+; it to take action for. The recommended way of setting values for this
+; directive is through the use of the error level constants and bitwise
+; operators. The error level constants are below here for convenience as well as
+; some common settings and their meanings.
+; By default, PHP is set to take action on all errors, notices and warnings EXCEPT
+; those related to E_NOTICE and E_STRICT, which together cover best practices and
+; recommended coding standards in PHP. For performance reasons, this is the
+; recommend error reporting setting. Your production server shouldn't be wasting
+; resources complaining about best practices and coding standards. That's what
+; development servers and development settings are for.
+; Note: The php.ini-development file has this setting as E_ALL. This
+; means it pretty much reports everything which is exactly what you want during
+; development and early testing.
+;
+; Error Level Constants:
+; E_ALL - All errors and warnings (includes E_STRICT as of PHP 5.4.0)
+; E_ERROR - fatal run-time errors
+; E_RECOVERABLE_ERROR - almost fatal run-time errors
+; E_WARNING - run-time warnings (non-fatal errors)
+; E_PARSE - compile-time parse errors
+; E_NOTICE - run-time notices (these are warnings which often result
+; from a bug in your code, but it's possible that it was
+; intentional (e.g., using an uninitialized variable and
+; relying on the fact it is automatically initialized to an
+; empty string)
+; E_STRICT - run-time notices, enable to have PHP suggest changes
+; to your code which will ensure the best interoperability
+; and forward compatibility of your code
+; E_CORE_ERROR - fatal errors that occur during PHP's initial startup
+; E_CORE_WARNING - warnings (non-fatal errors) that occur during PHP's
+; initial startup
+; E_COMPILE_ERROR - fatal compile-time errors
+; E_COMPILE_WARNING - compile-time warnings (non-fatal errors)
+; E_USER_ERROR - user-generated error message
+; E_USER_WARNING - user-generated warning message
+; E_USER_NOTICE - user-generated notice message
+; E_DEPRECATED - warn about code that will not work in future versions
+; of PHP
+; E_USER_DEPRECATED - user-generated deprecation warnings
+;
+; Common Values:
+; E_ALL (Show all errors, warnings and notices including coding standards.)
+; E_ALL & ~E_NOTICE (Show all errors, except for notices)
+; E_ALL & ~E_NOTICE & ~E_STRICT (Show all errors, except for notices and coding standards warnings.)
+; E_COMPILE_ERROR|E_RECOVERABLE_ERROR|E_ERROR|E_CORE_ERROR (Show only errors)
+; Default Value: E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED
+; Development Value: E_ALL
+; Production Value: E_ALL & ~E_DEPRECATED & ~E_STRICT
+; http://php.net/error-reporting
+error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT
+
+; This directive controls whether or not and where PHP will output errors,
+; notices and warnings too. Error output is very useful during development, but
+; it could be very dangerous in production environments. Depending on the code
+; which is triggering the error, sensitive information could potentially leak
+; out of your application such as database usernames and passwords or worse.
+; For production environments, we recommend logging errors rather than
+; sending them to STDOUT.
+; Possible Values:
+; Off = Do not display any errors
+; stderr = Display errors to STDERR (affects only CGI/CLI binaries!)
+; On or stdout = Display errors to STDOUT
+; Default Value: On
+; Development Value: On
+; Production Value: Off
+; http://php.net/display-errors
+display_errors = Off
+
+; The display of errors which occur during PHP's startup sequence are handled
+; separately from display_errors. PHP's default behavior is to suppress those
+; errors from clients. Turning the display of startup errors on can be useful in
+; debugging configuration problems. We strongly recommend you
+; set this to 'off' for production servers.
+; Default Value: Off
+; Development Value: On
+; Production Value: Off
+; http://php.net/display-startup-errors
+display_startup_errors = Off
+
+; Besides displaying errors, PHP can also log errors to locations such as a
+; server-specific log, STDERR, or a location specified by the error_log
+; directive found below. While errors should not be displayed on productions
+; servers they should still be monitored and logging is a great way to do that.
+; Default Value: Off
+; Development Value: On
+; Production Value: On
+; http://php.net/log-errors
+log_errors = On
+
+; Set maximum length of log_errors. In error_log information about the source is
+; added. The default is 1024 and 0 allows to not apply any maximum length at all.
+; http://php.net/log-errors-max-len
+log_errors_max_len = 1024
+
+; Do not log repeated messages. Repeated errors must occur in same file on same
+; line unless ignore_repeated_source is set true.
+; http://php.net/ignore-repeated-errors
+ignore_repeated_errors = Off
+
+; Ignore source of message when ignoring repeated messages. When this setting
+; is On you will not log errors with repeated messages from different files or
+; source lines.
+; http://php.net/ignore-repeated-source
+ignore_repeated_source = Off
+
+; If this parameter is set to Off, then memory leaks will not be shown (on
+; stdout or in the log). This is only effective in a debug compile, and if
+; error reporting includes E_WARNING in the allowed list
+; http://php.net/report-memleaks
+report_memleaks = On
+
+; This setting is on by default.
+;report_zend_debug = 0
+
+; Store the last error/warning message in $php_errormsg (boolean). Setting this value
+; to On can assist in debugging and is appropriate for development servers. It should
+; however be disabled on production servers.
+; This directive is DEPRECATED.
+; Default Value: Off
+; Development Value: Off
+; Production Value: Off
+; http://php.net/track-errors
+;track_errors = Off
+
+; Turn off normal error reporting and emit XML-RPC error XML
+; http://php.net/xmlrpc-errors
+;xmlrpc_errors = 0
+
+; An XML-RPC faultCode
+;xmlrpc_error_number = 0
+
+; When PHP displays or logs an error, it has the capability of formatting the
+; error message as HTML for easier reading. This directive controls whether
+; the error message is formatted as HTML or not.
+; Note: This directive is hardcoded to Off for the CLI SAPI
+; http://php.net/html-errors
+;html_errors = On
+
+; If html_errors is set to On *and* docref_root is not empty, then PHP
+; produces clickable error messages that direct to a page describing the error
+; or function causing the error in detail.
+; You can download a copy of the PHP manual from http://php.net/docs
+; and change docref_root to the base URL of your local copy including the
+; leading '/'. You must also specify the file extension being used including
+; the dot. PHP's default behavior is to leave these settings empty, in which
+; case no links to documentation are generated.
+; Note: Never use this feature for production boxes.
+; http://php.net/docref-root
+; Examples
+;docref_root = "/phpmanual/"
+
+; http://php.net/docref-ext
+;docref_ext = .html
+
+; String to output before an error message. PHP's default behavior is to leave
+; this setting blank.
+; http://php.net/error-prepend-string
+; Example:
+;error_prepend_string = ""
+
+; String to output after an error message. PHP's default behavior is to leave
+; this setting blank.
+; http://php.net/error-append-string
+; Example:
+;error_append_string = ""
+
+; Log errors to specified file. PHP's default behavior is to leave this value
+; empty.
+; http://php.net/error-log
+; Example:
+;error_log = php_errors.log
+; Log errors to syslog (Event Log on Windows).
+;error_log = syslog
+
+; The syslog ident is a string which is prepended to every message logged
+; to syslog. Only used when error_log is set to syslog.
+;syslog.ident = php
+
+; The syslog facility is used to specify what type of program is logging
+; the message. Only used when error_log is set to syslog.
+;syslog.facility = user
+
+; Set this to disable filtering control characters (the default).
+; Some loggers only accept NVT-ASCII, others accept anything that's not
+; control characters. If your logger accepts everything, then no filtering
+; is needed at all.
+; Allowed values are:
+; ascii (all printable ASCII characters and NL)
+; no-ctrl (all characters except control characters)
+; all (all characters)
+; raw (like "all", but messages are not split at newlines)
+; http://php.net/syslog.filter
+;syslog.filter = ascii
+
+;windows.show_crt_warning
+; Default value: 0
+; Development value: 0
+; Production value: 0
+
+;;;;;;;;;;;;;;;;;
+; Data Handling ;
+;;;;;;;;;;;;;;;;;
+
+; The separator used in PHP generated URLs to separate arguments.
+; PHP's default setting is "&".
+; http://php.net/arg-separator.output
+; Example:
+;arg_separator.output = "&"
+
+; List of separator(s) used by PHP to parse input URLs into variables.
+; PHP's default setting is "&".
+; NOTE: Every character in this directive is considered as separator!
+; http://php.net/arg-separator.input
+; Example:
+;arg_separator.input = ";&"
+
+; This directive determines which super global arrays are registered when PHP
+; starts up. G,P,C,E & S are abbreviations for the following respective super
+; globals: GET, POST, COOKIE, ENV and SERVER. There is a performance penalty
+; paid for the registration of these arrays and because ENV is not as commonly
+; used as the others, ENV is not recommended on productions servers. You
+; can still get access to the environment variables through getenv() should you
+; need to.
+; Default Value: "EGPCS"
+; Development Value: "GPCS"
+; Production Value: "GPCS";
+; http://php.net/variables-order
+variables_order = "GPCS"
+
+; This directive determines which super global data (G,P & C) should be
+; registered into the super global array REQUEST. If so, it also determines
+; the order in which that data is registered. The values for this directive
+; are specified in the same manner as the variables_order directive,
+; EXCEPT one. Leaving this value empty will cause PHP to use the value set
+; in the variables_order directive. It does not mean it will leave the super
+; globals array REQUEST empty.
+; Default Value: None
+; Development Value: "GP"
+; Production Value: "GP"
+; http://php.net/request-order
+request_order = "GP"
+
+; This directive determines whether PHP registers $argv & $argc each time it
+; runs. $argv contains an array of all the arguments passed to PHP when a script
+; is invoked. $argc contains an integer representing the number of arguments
+; that were passed when the script was invoked. These arrays are extremely
+; useful when running scripts from the command line. When this directive is
+; enabled, registering these variables consumes CPU cycles and memory each time
+; a script is executed. For performance reasons, this feature should be disabled
+; on production servers.
+; Note: This directive is hardcoded to On for the CLI SAPI
+; Default Value: On
+; Development Value: Off
+; Production Value: Off
+; http://php.net/register-argc-argv
+register_argc_argv = Off
+
+; When enabled, the ENV, REQUEST and SERVER variables are created when they're
+; first used (Just In Time) instead of when the script starts. If these
+; variables are not used within a script, having this directive on will result
+; in a performance gain. The PHP directive register_argc_argv must be disabled
+; for this directive to have any effect.
+; http://php.net/auto-globals-jit
+auto_globals_jit = On
+
+; Whether PHP will read the POST data.
+; This option is enabled by default.
+; Most likely, you won't want to disable this option globally. It causes $_POST
+; and $_FILES to always be empty; the only way you will be able to read the
+; POST data will be through the php://input stream wrapper. This can be useful
+; to proxy requests or to process the POST data in a memory efficient fashion.
+; http://php.net/enable-post-data-reading
+;enable_post_data_reading = Off
+
+; Maximum size of POST data that PHP will accept.
+; Its value may be 0 to disable the limit. It is ignored if POST data reading
+; is disabled through enable_post_data_reading.
+; http://php.net/post-max-size
+post_max_size = 80M
+
+; Automatically add files before PHP document.
+; http://php.net/auto-prepend-file
+auto_prepend_file =
+
+; Automatically add files after PHP document.
+; http://php.net/auto-append-file
+auto_append_file =
+
+; By default, PHP will output a media type using the Content-Type header. To
+; disable this, simply set it to be empty.
+;
+; PHP's built-in default media type is set to text/html.
+; http://php.net/default-mimetype
+default_mimetype = "text/html"
+
+; PHP's default character set is set to UTF-8.
+; http://php.net/default-charset
+default_charset = "UTF-8"
+
+; PHP internal character encoding is set to empty.
+; If empty, default_charset is used.
+; http://php.net/internal-encoding
+;internal_encoding =
+
+; PHP input character encoding is set to empty.
+; If empty, default_charset is used.
+; http://php.net/input-encoding
+;input_encoding =
+
+; PHP output character encoding is set to empty.
+; If empty, default_charset is used.
+; See also output_buffer.
+; http://php.net/output-encoding
+;output_encoding =
+
+;;;;;;;;;;;;;;;;;;;;;;;;;
+; Paths and Directories ;
+;;;;;;;;;;;;;;;;;;;;;;;;;
+
+; UNIX: "/path1:/path2"
+;include_path = ".:/php/includes"
+;
+; Windows: "\path1;\path2"
+;include_path = ".;c:\php\includes"
+;
+; PHP's default setting for include_path is ".;/path/to/php/pear"
+; http://php.net/include-path
+
+; The root of the PHP pages, used only if nonempty.
+; if PHP was not compiled with FORCE_REDIRECT, you SHOULD set doc_root
+; if you are running php as a CGI under any web server (other than IIS)
+; see documentation for security issues. The alternate is to use the
+; cgi.force_redirect configuration below
+; http://php.net/doc-root
+doc_root =
+
+; The directory under which PHP opens the script using /~username used only
+; if nonempty.
+; http://php.net/user-dir
+user_dir =
+
+; Directory in which the loadable extensions (modules) reside.
+; http://php.net/extension-dir
+;extension_dir = "./"
+; On windows:
+;extension_dir = "ext"
+
+; Directory where the temporary files should be placed.
+; Defaults to the system default (see sys_get_temp_dir)
+;sys_temp_dir = "/tmp"
+
+; Whether or not to enable the dl() function. The dl() function does NOT work
+; properly in multithreaded servers, such as IIS or Zeus, and is automatically
+; disabled on them.
+; http://php.net/enable-dl
+enable_dl = Off
+
+; cgi.force_redirect is necessary to provide security running PHP as a CGI under
+; most web servers. Left undefined, PHP turns this on by default. You can
+; turn it off here AT YOUR OWN RISK
+; **You CAN safely turn this off for IIS, in fact, you MUST.**
+; http://php.net/cgi.force-redirect
+;cgi.force_redirect = 1
+
+; if cgi.nph is enabled it will force cgi to always sent Status: 200 with
+; every request. PHP's default behavior is to disable this feature.
+;cgi.nph = 1
+
+; if cgi.force_redirect is turned on, and you are not running under Apache or Netscape
+; (iPlanet) web servers, you MAY need to set an environment variable name that PHP
+; will look for to know it is OK to continue execution. Setting this variable MAY
+; cause security issues, KNOW WHAT YOU ARE DOING FIRST.
+; http://php.net/cgi.redirect-status-env
+;cgi.redirect_status_env =
+
+; cgi.fix_pathinfo provides *real* PATH_INFO/PATH_TRANSLATED support for CGI. PHP's
+; previous behaviour was to set PATH_TRANSLATED to SCRIPT_FILENAME, and to not grok
+; what PATH_INFO is. For more information on PATH_INFO, see the cgi specs. Setting
+; this to 1 will cause PHP CGI to fix its paths to conform to the spec. A setting
+; of zero causes PHP to behave as before. Default is 1. You should fix your scripts
+; to use SCRIPT_FILENAME rather than PATH_TRANSLATED.
+; http://php.net/cgi.fix-pathinfo
+;cgi.fix_pathinfo=1
+
+; if cgi.discard_path is enabled, the PHP CGI binary can safely be placed outside
+; of the web tree and people will not be able to circumvent .htaccess security.
+;cgi.discard_path=1
+
+; FastCGI under IIS supports the ability to impersonate
+; security tokens of the calling client. This allows IIS to define the
+; security context that the request runs under. mod_fastcgi under Apache
+; does not currently support this feature (03/17/2002)
+; Set to 1 if running under IIS. Default is zero.
+; http://php.net/fastcgi.impersonate
+;fastcgi.impersonate = 1
+
+; Disable logging through FastCGI connection. PHP's default behavior is to enable
+; this feature.
+;fastcgi.logging = 0
+
+; cgi.rfc2616_headers configuration option tells PHP what type of headers to
+; use when sending HTTP response code. If set to 0, PHP sends Status: header that
+; is supported by Apache. When this option is set to 1, PHP will send
+; RFC2616 compliant header.
+; Default is zero.
+; http://php.net/cgi.rfc2616-headers
+;cgi.rfc2616_headers = 0
+
+; cgi.check_shebang_line controls whether CGI PHP checks for line starting with #!
+; (shebang) at the top of the running script. This line might be needed if the
+; script support running both as stand-alone script and via PHP CGI<. PHP in CGI
+; mode skips this line and ignores its content if this directive is turned on.
+; http://php.net/cgi.check-shebang-line
+;cgi.check_shebang_line=1
+
+;;;;;;;;;;;;;;;;
+; File Uploads ;
+;;;;;;;;;;;;;;;;
+
+; Whether to allow HTTP file uploads.
+; http://php.net/file-uploads
+file_uploads = On
+
+; Temporary directory for HTTP uploaded files (will use system default if not
+; specified).
+; http://php.net/upload-tmp-dir
+;upload_tmp_dir =
+
+; Maximum allowed size for uploaded files.
+; http://php.net/upload-max-filesize
+upload_max_filesize = 20M
+
+; Maximum number of files that can be uploaded via a single request
+max_file_uploads = 20
+
+;;;;;;;;;;;;;;;;;;
+; Fopen wrappers ;
+;;;;;;;;;;;;;;;;;;
+
+; Whether to allow the treatment of URLs (like http:// or ftp://) as files.
+; http://php.net/allow-url-fopen
+allow_url_fopen = On
+
+; Whether to allow include/require to open URLs (like http:// or ftp://) as files.
+; http://php.net/allow-url-include
+allow_url_include = Off
+
+; Define the anonymous ftp password (your email address). PHP's default setting
+; for this is empty.
+; http://php.net/from
+;from="john@doe.com"
+
+; Define the User-Agent string. PHP's default setting for this is empty.
+; http://php.net/user-agent
+;user_agent="PHP"
+
+; Default timeout for socket based streams (seconds)
+; http://php.net/default-socket-timeout
+default_socket_timeout = 600
+
+; If your scripts have to deal with files from Macintosh systems,
+; or you are running on a Mac and need to deal with files from
+; unix or win32 systems, setting this flag will cause PHP to
+; automatically detect the EOL character in those files so that
+; fgets() and file() will work regardless of the source of the file.
+; http://php.net/auto-detect-line-endings
+;auto_detect_line_endings = Off
+
+;;;;;;;;;;;;;;;;;;;;;;
+; Dynamic Extensions ;
+;;;;;;;;;;;;;;;;;;;;;;
+
+; If you wish to have an extension loaded automatically, use the following
+; syntax:
+;
+; extension=modulename
+;
+; For example:
+;
+; extension=mysqli
+;
+; When the extension library to load is not located in the default extension
+; directory, You may specify an absolute path to the library file:
+;
+; extension=/path/to/extension/mysqli.so
+;
+; Note : The syntax used in previous PHP versions ('extension=.so' and
+; 'extension='php_.dll') is supported for legacy reasons and may be
+; deprecated in a future PHP major version. So, when it is possible, please
+; move to the new ('extension=) syntax.
+;
+; Notes for Windows environments :
+;
+; - Many DLL files are located in the extensions/ (PHP 4) or ext/ (PHP 5+)
+; extension folders as well as the separate PECL DLL download (PHP 5+).
+; Be sure to appropriately set the extension_dir directive.
+;
+;extension=bz2
+;extension=curl
+;extension=ffi
+;extension=ftp
+;extension=fileinfo
+;extension=gd2
+;extension=gettext
+;extension=gmp
+;extension=intl
+;extension=imap
+;extension=ldap
+;extension=mbstring
+;extension=exif ; Must be after mbstring as it depends on it
+;extension=mysqli
+;extension=oci8_12c ; Use with Oracle Database 12c Instant Client
+;extension=odbc
+;extension=openssl
+;extension=pdo_firebird
+;extension=pdo_mysql
+;extension=pdo_oci
+;extension=pdo_odbc
+;extension=pdo_pgsql
+;extension=pdo_sqlite
+;extension=pgsql
+;extension=shmop
+
+; The MIBS data available in the PHP distribution must be installed.
+; See http://www.php.net/manual/en/snmp.installation.php
+;extension=snmp
+
+;extension=soap
+;extension=sockets
+;extension=sodium
+;extension=sqlite3
+;extension=tidy
+;extension=xmlrpc
+;extension=xsl
+
+;;;;;;;;;;;;;;;;;;;
+; Module Settings ;
+;;;;;;;;;;;;;;;;;;;
+
+[CLI Server]
+; Whether the CLI web server uses ANSI color coding in its terminal output.
+cli_server.color = On
+
+[Date]
+; Defines the default timezone used by the date functions
+; http://php.net/date.timezone
+;date.timezone =
+
+; http://php.net/date.default-latitude
+;date.default_latitude = 31.7667
+
+; http://php.net/date.default-longitude
+;date.default_longitude = 35.2333
+
+; http://php.net/date.sunrise-zenith
+;date.sunrise_zenith = 90.583333
+
+; http://php.net/date.sunset-zenith
+;date.sunset_zenith = 90.583333
+
+[filter]
+; http://php.net/filter.default
+;filter.default = unsafe_raw
+
+; http://php.net/filter.default-flags
+;filter.default_flags =
+
+[iconv]
+; Use of this INI entry is deprecated, use global input_encoding instead.
+; If empty, default_charset or input_encoding or iconv.input_encoding is used.
+; The precedence is: default_charset < input_encoding < iconv.input_encoding
+;iconv.input_encoding =
+
+; Use of this INI entry is deprecated, use global internal_encoding instead.
+; If empty, default_charset or internal_encoding or iconv.internal_encoding is used.
+; The precedence is: default_charset < internal_encoding < iconv.internal_encoding
+;iconv.internal_encoding =
+
+; Use of this INI entry is deprecated, use global output_encoding instead.
+; If empty, default_charset or output_encoding or iconv.output_encoding is used.
+; The precedence is: default_charset < output_encoding < iconv.output_encoding
+; To use an output encoding conversion, iconv's output handler must be set
+; otherwise output encoding conversion cannot be performed.
+;iconv.output_encoding =
+
+[imap]
+; rsh/ssh logins are disabled by default. Use this INI entry if you want to
+; enable them. Note that the IMAP library does not filter mailbox names before
+; passing them to rsh/ssh command, thus passing untrusted data to this function
+; with rsh/ssh enabled is insecure.
+;imap.enable_insecure_rsh=0
+
+[intl]
+;intl.default_locale =
+; This directive allows you to produce PHP errors when some error
+; happens within intl functions. The value is the level of the error produced.
+; Default is 0, which does not produce any errors.
+;intl.error_level = E_WARNING
+;intl.use_exceptions = 0
+
+[sqlite3]
+; Directory pointing to SQLite3 extensions
+; http://php.net/sqlite3.extension-dir
+;sqlite3.extension_dir =
+
+; SQLite defensive mode flag (only available from SQLite 3.26+)
+; When the defensive flag is enabled, language features that allow ordinary
+; SQL to deliberately corrupt the database file are disabled. This forbids
+; writing directly to the schema, shadow tables (eg. FTS data tables), or
+; the sqlite_dbpage virtual table.
+; https://www.sqlite.org/c3ref/c_dbconfig_defensive.html
+; (for older SQLite versions, this flag has no use)
+;sqlite3.defensive = 1
+
+[Pcre]
+; PCRE library backtracking limit.
+; http://php.net/pcre.backtrack-limit
+;pcre.backtrack_limit=100000
+
+; PCRE library recursion limit.
+; Please note that if you set this value to a high number you may consume all
+; the available process stack and eventually crash PHP (due to reaching the
+; stack size limit imposed by the Operating System).
+; http://php.net/pcre.recursion-limit
+;pcre.recursion_limit=100000
+
+; Enables or disables JIT compilation of patterns. This requires the PCRE
+; library to be compiled with JIT support.
+;pcre.jit=1
+
+[Pdo]
+; Whether to pool ODBC connections. Can be one of "strict", "relaxed" or "off"
+; http://php.net/pdo-odbc.connection-pooling
+;pdo_odbc.connection_pooling=strict
+
+;pdo_odbc.db2_instance_name
+
+[Pdo_mysql]
+; Default socket name for local MySQL connects. If empty, uses the built-in
+; MySQL defaults.
+pdo_mysql.default_socket=
+
+[Phar]
+; http://php.net/phar.readonly
+;phar.readonly = On
+
+; http://php.net/phar.require-hash
+;phar.require_hash = On
+
+;phar.cache_list =
+
+[mail function]
+; For Win32 only.
+; http://php.net/smtp
+SMTP = localhost
+; http://php.net/smtp-port
+smtp_port = 25
+
+; For Win32 only.
+; http://php.net/sendmail-from
+;sendmail_from = me@example.com
+
+; For Unix only. You may supply arguments as well (default: "sendmail -t -i").
+; http://php.net/sendmail-path
+;sendmail_path =
+
+; Force the addition of the specified parameters to be passed as extra parameters
+; to the sendmail binary. These parameters will always replace the value of
+; the 5th parameter to mail().
+;mail.force_extra_parameters =
+
+; Add X-PHP-Originating-Script: that will include uid of the script followed by the filename
+mail.add_x_header = Off
+
+; The path to a log file that will log all mail() calls. Log entries include
+; the full path of the script, line number, To address and headers.
+;mail.log =
+; Log mail to syslog (Event Log on Windows).
+;mail.log = syslog
+
+[ODBC]
+; http://php.net/odbc.default-db
+;odbc.default_db = Not yet implemented
+
+; http://php.net/odbc.default-user
+;odbc.default_user = Not yet implemented
+
+; http://php.net/odbc.default-pw
+;odbc.default_pw = Not yet implemented
+
+; Controls the ODBC cursor model.
+; Default: SQL_CURSOR_STATIC (default).
+;odbc.default_cursortype
+
+; Allow or prevent persistent links.
+; http://php.net/odbc.allow-persistent
+odbc.allow_persistent = On
+
+; Check that a connection is still valid before reuse.
+; http://php.net/odbc.check-persistent
+odbc.check_persistent = On
+
+; Maximum number of persistent links. -1 means no limit.
+; http://php.net/odbc.max-persistent
+odbc.max_persistent = -1
+
+; Maximum number of links (persistent + non-persistent). -1 means no limit.
+; http://php.net/odbc.max-links
+odbc.max_links = -1
+
+; Handling of LONG fields. Returns number of bytes to variables. 0 means
+; passthru.
+; http://php.net/odbc.defaultlrl
+odbc.defaultlrl = 4096
+
+; Handling of binary data. 0 means passthru, 1 return as is, 2 convert to char.
+; See the documentation on odbc_binmode and odbc_longreadlen for an explanation
+; of odbc.defaultlrl and odbc.defaultbinmode
+; http://php.net/odbc.defaultbinmode
+odbc.defaultbinmode = 1
+
+[MySQLi]
+
+; Maximum number of persistent links. -1 means no limit.
+; http://php.net/mysqli.max-persistent
+mysqli.max_persistent = -1
+
+; Allow accessing, from PHP's perspective, local files with LOAD DATA statements
+; http://php.net/mysqli.allow_local_infile
+;mysqli.allow_local_infile = On
+
+; Allow or prevent persistent links.
+; http://php.net/mysqli.allow-persistent
+mysqli.allow_persistent = On
+
+; Maximum number of links. -1 means no limit.
+; http://php.net/mysqli.max-links
+mysqli.max_links = -1
+
+; Default port number for mysqli_connect(). If unset, mysqli_connect() will use
+; the $MYSQL_TCP_PORT or the mysql-tcp entry in /etc/services or the
+; compile-time value defined MYSQL_PORT (in that order). Win32 will only look
+; at MYSQL_PORT.
+; http://php.net/mysqli.default-port
+mysqli.default_port = 3306
+
+; Default socket name for local MySQL connects. If empty, uses the built-in
+; MySQL defaults.
+; http://php.net/mysqli.default-socket
+mysqli.default_socket =
+
+; Default host for mysqli_connect() (doesn't apply in safe mode).
+; http://php.net/mysqli.default-host
+mysqli.default_host =
+
+; Default user for mysqli_connect() (doesn't apply in safe mode).
+; http://php.net/mysqli.default-user
+mysqli.default_user =
+
+; Default password for mysqli_connect() (doesn't apply in safe mode).
+; Note that this is generally a *bad* idea to store passwords in this file.
+; *Any* user with PHP access can run 'echo get_cfg_var("mysqli.default_pw")
+; and reveal this password! And of course, any users with read access to this
+; file will be able to reveal the password as well.
+; http://php.net/mysqli.default-pw
+mysqli.default_pw =
+
+; Allow or prevent reconnect
+mysqli.reconnect = Off
+
+[mysqlnd]
+; Enable / Disable collection of general statistics by mysqlnd which can be
+; used to tune and monitor MySQL operations.
+mysqlnd.collect_statistics = On
+
+; Enable / Disable collection of memory usage statistics by mysqlnd which can be
+; used to tune and monitor MySQL operations.
+mysqlnd.collect_memory_statistics = Off
+
+; Records communication from all extensions using mysqlnd to the specified log
+; file.
+; http://php.net/mysqlnd.debug
+;mysqlnd.debug =
+
+; Defines which queries will be logged.
+;mysqlnd.log_mask = 0
+
+; Default size of the mysqlnd memory pool, which is used by result sets.
+;mysqlnd.mempool_default_size = 16000
+
+; Size of a pre-allocated buffer used when sending commands to MySQL in bytes.
+;mysqlnd.net_cmd_buffer_size = 2048
+
+; Size of a pre-allocated buffer used for reading data sent by the server in
+; bytes.
+;mysqlnd.net_read_buffer_size = 32768
+
+; Timeout for network requests in seconds.
+;mysqlnd.net_read_timeout = 31536000
+
+; SHA-256 Authentication Plugin related. File with the MySQL server public RSA
+; key.
+;mysqlnd.sha256_server_public_key =
+
+[OCI8]
+
+; Connection: Enables privileged connections using external
+; credentials (OCI_SYSOPER, OCI_SYSDBA)
+; http://php.net/oci8.privileged-connect
+;oci8.privileged_connect = Off
+
+; Connection: The maximum number of persistent OCI8 connections per
+; process. Using -1 means no limit.
+; http://php.net/oci8.max-persistent
+;oci8.max_persistent = -1
+
+; Connection: The maximum number of seconds a process is allowed to
+; maintain an idle persistent connection. Using -1 means idle
+; persistent connections will be maintained forever.
+; http://php.net/oci8.persistent-timeout
+;oci8.persistent_timeout = -1
+
+; Connection: The number of seconds that must pass before issuing a
+; ping during oci_pconnect() to check the connection validity. When
+; set to 0, each oci_pconnect() will cause a ping. Using -1 disables
+; pings completely.
+; http://php.net/oci8.ping-interval
+;oci8.ping_interval = 60
+
+; Connection: Set this to a user chosen connection class to be used
+; for all pooled server requests with Oracle 11g Database Resident
+; Connection Pooling (DRCP). To use DRCP, this value should be set to
+; the same string for all web servers running the same application,
+; the database pool must be configured, and the connection string must
+; specify to use a pooled server.
+;oci8.connection_class =
+
+; High Availability: Using On lets PHP receive Fast Application
+; Notification (FAN) events generated when a database node fails. The
+; database must also be configured to post FAN events.
+;oci8.events = Off
+
+; Tuning: This option enables statement caching, and specifies how
+; many statements to cache. Using 0 disables statement caching.
+; http://php.net/oci8.statement-cache-size
+;oci8.statement_cache_size = 20
+
+; Tuning: Enables statement prefetching and sets the default number of
+; rows that will be fetched automatically after statement execution.
+; http://php.net/oci8.default-prefetch
+;oci8.default_prefetch = 100
+
+; Compatibility. Using On means oci_close() will not close
+; oci_connect() and oci_new_connect() connections.
+; http://php.net/oci8.old-oci-close-semantics
+;oci8.old_oci_close_semantics = Off
+
+[PostgreSQL]
+; Allow or prevent persistent links.
+; http://php.net/pgsql.allow-persistent
+pgsql.allow_persistent = On
+
+; Detect broken persistent links always with pg_pconnect().
+; Auto reset feature requires a little overheads.
+; http://php.net/pgsql.auto-reset-persistent
+pgsql.auto_reset_persistent = Off
+
+; Maximum number of persistent links. -1 means no limit.
+; http://php.net/pgsql.max-persistent
+pgsql.max_persistent = -1
+
+; Maximum number of links (persistent+non persistent). -1 means no limit.
+; http://php.net/pgsql.max-links
+pgsql.max_links = -1
+
+; Ignore PostgreSQL backends Notice message or not.
+; Notice message logging require a little overheads.
+; http://php.net/pgsql.ignore-notice
+pgsql.ignore_notice = 0
+
+; Log PostgreSQL backends Notice message or not.
+; Unless pgsql.ignore_notice=0, module cannot log notice message.
+; http://php.net/pgsql.log-notice
+pgsql.log_notice = 0
+
+[bcmath]
+; Number of decimal digits for all bcmath functions.
+; http://php.net/bcmath.scale
+bcmath.scale = 0
+
+[browscap]
+; http://php.net/browscap
+;browscap = extra/browscap.ini
+
+[Session]
+; Handler used to store/retrieve data.
+; http://php.net/session.save-handler
+session.save_handler = files
+
+; Argument passed to save_handler. In the case of files, this is the path
+; where data files are stored. Note: Windows users have to change this
+; variable in order to use PHP's session functions.
+;
+; The path can be defined as:
+;
+; session.save_path = "N;/path"
+;
+; where N is an integer. Instead of storing all the session files in
+; /path, what this will do is use subdirectories N-levels deep, and
+; store the session data in those directories. This is useful if
+; your OS has problems with many files in one directory, and is
+; a more efficient layout for servers that handle many sessions.
+;
+; NOTE 1: PHP will not create this directory structure automatically.
+; You can use the script in the ext/session dir for that purpose.
+; NOTE 2: See the section on garbage collection below if you choose to
+; use subdirectories for session storage
+;
+; The file storage module creates files using mode 600 by default.
+; You can change that by using
+;
+; session.save_path = "N;MODE;/path"
+;
+; where MODE is the octal representation of the mode. Note that this
+; does not overwrite the process's umask.
+; http://php.net/session.save-path
+;session.save_path = "/tmp"
+
+; Whether to use strict session mode.
+; Strict session mode does not accept an uninitialized session ID, and
+; regenerates the session ID if the browser sends an uninitialized session ID.
+; Strict mode protects applications from session fixation via a session adoption
+; vulnerability. It is disabled by default for maximum compatibility, but
+; enabling it is encouraged.
+; https://wiki.php.net/rfc/strict_sessions
+session.use_strict_mode = 0
+
+; Whether to use cookies.
+; http://php.net/session.use-cookies
+session.use_cookies = 1
+
+; http://php.net/session.cookie-secure
+;session.cookie_secure =
+
+; This option forces PHP to fetch and use a cookie for storing and maintaining
+; the session id. We encourage this operation as it's very helpful in combating
+; session hijacking when not specifying and managing your own session id. It is
+; not the be-all and end-all of session hijacking defense, but it's a good start.
+; http://php.net/session.use-only-cookies
+session.use_only_cookies = 1
+
+; Name of the session (used as cookie name).
+; http://php.net/session.name
+session.name = PHPSESSID
+
+; Initialize session on request startup.
+; http://php.net/session.auto-start
+session.auto_start = 0
+
+; Lifetime in seconds of cookie or, if 0, until browser is restarted.
+; http://php.net/session.cookie-lifetime
+session.cookie_lifetime = 0
+
+; The path for which the cookie is valid.
+; http://php.net/session.cookie-path
+session.cookie_path = /
+
+; The domain for which the cookie is valid.
+; http://php.net/session.cookie-domain
+session.cookie_domain =
+
+; Whether or not to add the httpOnly flag to the cookie, which makes it
+; inaccessible to browser scripting languages such as JavaScript.
+; http://php.net/session.cookie-httponly
+session.cookie_httponly =
+
+; Add SameSite attribute to cookie to help mitigate Cross-Site Request Forgery (CSRF/XSRF)
+; Current valid values are "Strict", "Lax" or "None". When using "None",
+; make sure to include the quotes, as `none` is interpreted like `false` in ini files.
+; https://tools.ietf.org/html/draft-west-first-party-cookies-07
+session.cookie_samesite =
+
+; Handler used to serialize data. php is the standard serializer of PHP.
+; http://php.net/session.serialize-handler
+session.serialize_handler = php
+
+; Defines the probability that the 'garbage collection' process is started on every
+; session initialization. The probability is calculated by using gc_probability/gc_divisor,
+; e.g. 1/100 means there is a 1% chance that the GC process starts on each request.
+; Default Value: 1
+; Development Value: 1
+; Production Value: 1
+; http://php.net/session.gc-probability
+session.gc_probability = 1
+
+; Defines the probability that the 'garbage collection' process is started on every
+; session initialization. The probability is calculated by using gc_probability/gc_divisor,
+; e.g. 1/100 means there is a 1% chance that the GC process starts on each request.
+; For high volume production servers, using a value of 1000 is a more efficient approach.
+; Default Value: 100
+; Development Value: 1000
+; Production Value: 1000
+; http://php.net/session.gc-divisor
+session.gc_divisor = 1000
+
+; After this number of seconds, stored data will be seen as 'garbage' and
+; cleaned up by the garbage collection process.
+; http://php.net/session.gc-maxlifetime
+session.gc_maxlifetime = 1440
+
+; NOTE: If you are using the subdirectory option for storing session files
+; (see session.save_path above), then garbage collection does *not*
+; happen automatically. You will need to do your own garbage
+; collection through a shell script, cron entry, or some other method.
+; For example, the following script is the equivalent of setting
+; session.gc_maxlifetime to 1440 (1440 seconds = 24 minutes):
+; find /path/to/sessions -cmin +24 -type f | xargs rm
+
+; Check HTTP Referer to invalidate externally stored URLs containing ids.
+; HTTP_REFERER has to contain this substring for the session to be
+; considered as valid.
+; http://php.net/session.referer-check
+session.referer_check =
+
+; Set to {nocache,private,public,} to determine HTTP caching aspects
+; or leave this empty to avoid sending anti-caching headers.
+; http://php.net/session.cache-limiter
+session.cache_limiter = nocache
+
+; Document expires after n minutes.
+; http://php.net/session.cache-expire
+session.cache_expire = 180
+
+; trans sid support is disabled by default.
+; Use of trans sid may risk your users' security.
+; Use this option with caution.
+; - User may send URL contains active session ID
+; to other person via. email/irc/etc.
+; - URL that contains active session ID may be stored
+; in publicly accessible computer.
+; - User may access your site with the same session ID
+; always using URL stored in browser's history or bookmarks.
+; http://php.net/session.use-trans-sid
+session.use_trans_sid = 0
+
+; Set session ID character length. This value could be between 22 to 256.
+; Shorter length than default is supported only for compatibility reason.
+; Users should use 32 or more chars.
+; http://php.net/session.sid-length
+; Default Value: 32
+; Development Value: 26
+; Production Value: 26
+session.sid_length = 26
+
+; The URL rewriter will look for URLs in a defined set of HTML tags.
+;