feat: implement comprehensive project management and client tracking portal with Filament integration
This commit is contained in:
@@ -0,0 +1,92 @@
|
||||
<?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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user