Files
GSB-Construction/Modules/ProjectProgress/app/Services/ProjectProgressService.php

47 lines
1.5 KiB
PHP

<?php
namespace Modules\ProjectProgress\Services;
use Modules\ProjectManagement\Models\Project;
use Modules\TaskManagement\Models\Task;
class ProjectProgressService
{
/**
* Calculate project progress dynamically using actual material consumed vs BOQ planned quantity.
* Formula: sum((Actual Material Consumed / Planned BOQ) * Task Weight)
*/
public function calculateProjectProgress(Project $project): float
{
$tasks = Task::where('project_id', $project->id)
->with(['materials'])
->get();
if ($tasks->isEmpty()) {
return 0.0;
}
$totalWeightedProgress = 0.0;
$totalWeight = 0.0;
foreach ($tasks as $task) {
$taskWeight = $task->weight ?? 1.0;
$totalWeight += $taskWeight;
$plannedBoq = $task->materials->sum('planned_quantity');
$consumedQty = $task->materials->sum('consumed_quantity');
if ($plannedBoq > 0) {
$materialProgress = min(1.0, $consumedQty / $plannedBoq);
$totalWeightedProgress += ($materialProgress * 100) * $taskWeight;
} else {
// Fallback to task completion percentage if no BOQ material planned
$taskProgress = $task->status === 'completed' ? 100 : ($task->progress_percentage ?? 0);
$totalWeightedProgress += $taskProgress * $taskWeight;
}
}
return $totalWeight > 0 ? round($totalWeightedProgress / $totalWeight, 2) : 0.0;
}
}