You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
234 lines
8.1 KiB
234 lines
8.1 KiB
1 year ago
|
<?php
|
||
|
|
||
|
namespace App\Models;
|
||
|
|
||
|
use App\Models\AssignMaterial;
|
||
|
use App\Models\ActivityProgressLog;
|
||
|
use App\Models\AssignTools;
|
||
|
use App\Models\ReportActivityMaterial;
|
||
|
use Illuminate\Database\Eloquent\Model;
|
||
|
use Illuminate\Support\Arr;
|
||
|
use Illuminate\Support\Facades\DB;
|
||
|
use Carbon\Carbon;
|
||
|
|
||
|
class Activity extends Model
|
||
|
{
|
||
|
// persentase bobot gak kepake yg dipakenya bobot_planning
|
||
|
protected $table = 'm_activity', $guarded = ['id'];
|
||
|
|
||
|
const CREATED_AT = 'created_at';
|
||
|
const UPDATED_AT = 'updated_at';
|
||
|
|
||
|
|
||
|
protected $appends = [
|
||
|
'jobs_done', 'assign_hr', 'assign_material', 'assign_tools', 'assign_expense'
|
||
|
];
|
||
|
|
||
|
|
||
|
public function getStartDateAttribute($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 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();
|
||
|
}
|
||
|
});
|
||
|
|
||
|
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());
|
||
|
}
|
||
|
}
|