54 lines
1.5 KiB
PHP
54 lines
1.5 KiB
PHP
|
|
<?php
|
||
|
|
|
||
|
|
namespace App\Dashboard\Stats;
|
||
|
|
|
||
|
|
use App\Enums\ApprovalStatusEnum;
|
||
|
|
use App\Models\RouteArticle;
|
||
|
|
use App\Support\DateRange;
|
||
|
|
|
||
|
|
class ApprovalRate extends DailySeriesStat
|
||
|
|
{
|
||
|
|
public function key(): string
|
||
|
|
{
|
||
|
|
return 'approval-rate';
|
||
|
|
}
|
||
|
|
|
||
|
|
public function label(): string
|
||
|
|
{
|
||
|
|
return 'Approval Rate';
|
||
|
|
}
|
||
|
|
|
||
|
|
protected function series(DateRange $range, array $days): SeriesResult
|
||
|
|
{
|
||
|
|
$decisions = RouteArticle::query()
|
||
|
|
->toBase()
|
||
|
|
->whereNotNull('decided_at')
|
||
|
|
->whereBetween('decided_at', [$range->from, $range->to])
|
||
|
|
->whereIn('approval_status', ApprovalStatusEnum::decidedValues())
|
||
|
|
->selectRaw(
|
||
|
|
'DATE(decided_at) as bucket, COUNT(*) as total, SUM(CASE WHEN approval_status = ? THEN 1 ELSE 0 END) as approved',
|
||
|
|
[ApprovalStatusEnum::APPROVED->value],
|
||
|
|
)
|
||
|
|
->groupBy('bucket')
|
||
|
|
->get()
|
||
|
|
->keyBy('bucket');
|
||
|
|
|
||
|
|
$values = array_map(
|
||
|
|
function (string $day) use ($decisions): ?float {
|
||
|
|
$decision = $decisions->get($day);
|
||
|
|
|
||
|
|
if ($decision === null || (int) $decision->total === 0) {
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
|
||
|
|
return round(((int) $decision->approved / (int) $decision->total) * 100, 1);
|
||
|
|
},
|
||
|
|
$days,
|
||
|
|
);
|
||
|
|
|
||
|
|
return new SeriesResult($days, [
|
||
|
|
new Series('Approval Rate', $values, zeroIsMeaningful: true),
|
||
|
|
]);
|
||
|
|
}
|
||
|
|
}
|