93 lines
2.4 KiB
PHP
93 lines
2.4 KiB
PHP
<?php
|
|
|
|
namespace App\Models;
|
|
|
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|
use Illuminate\Database\Eloquent\Model;
|
|
use Illuminate\Database\Eloquent\SoftDeletes;
|
|
use Illuminate\Support\Str;
|
|
|
|
class Project extends Model
|
|
{
|
|
use HasFactory, SoftDeletes;
|
|
|
|
protected $fillable = [
|
|
'proposal_id',
|
|
'title',
|
|
'slug',
|
|
'client_name',
|
|
'client_email',
|
|
'client_access_code',
|
|
'status',
|
|
'progress_percent',
|
|
'start_date',
|
|
'target_date',
|
|
'completed_at',
|
|
'notes',
|
|
];
|
|
|
|
protected $casts = [
|
|
'start_date' => 'date',
|
|
'target_date' => 'date',
|
|
'completed_at' => 'datetime',
|
|
'progress_percent' => 'integer',
|
|
];
|
|
|
|
protected static function boot()
|
|
{
|
|
parent::boot();
|
|
|
|
static::creating(function ($project) {
|
|
if (empty($project->slug)) {
|
|
$project->slug = Str::slug($project->title) . '-' . Str::random(5);
|
|
}
|
|
if (empty($project->client_access_code)) {
|
|
$project->client_access_code = strtoupper(Str::random(6));
|
|
}
|
|
});
|
|
}
|
|
|
|
public function proposal()
|
|
{
|
|
return $this->belongsTo(Proposal::class);
|
|
}
|
|
|
|
public function modules()
|
|
{
|
|
return $this->hasMany(ProjectModule::class)->orderBy('order', 'asc');
|
|
}
|
|
|
|
public function tasks()
|
|
{
|
|
return $this->hasMany(ProjectTask::class)->orderBy('order_index', 'asc');
|
|
}
|
|
|
|
public function updates()
|
|
{
|
|
return $this->hasMany(ProjectUpdate::class)->latest();
|
|
}
|
|
|
|
/**
|
|
* Recalculate progress percentage based on completed modules weight
|
|
*/
|
|
public function recalculateProgress()
|
|
{
|
|
$totalWeight = $this->modules()->sum('weight_percent');
|
|
if ($totalWeight > 0) {
|
|
$completedWeight = $this->modules()->where('status', 'completed')->sum('weight_percent');
|
|
$progress = (int) round(($completedWeight / $totalWeight) * 100);
|
|
} else {
|
|
$totalTasks = $this->tasks()->count();
|
|
if ($totalTasks > 0) {
|
|
$completedTasks = $this->tasks()->where('status', 'done')->count();
|
|
$progress = (int) round(($completedTasks / $totalTasks) * 100);
|
|
} else {
|
|
$progress = $this->progress_percent;
|
|
}
|
|
}
|
|
|
|
$this->update(['progress_percent' => min(100, max(0, $progress))]);
|
|
return $this->progress_percent;
|
|
}
|
|
}
|