|
|
@@ -41,10 +41,13 @@ public function overview(array $unitIds = [], ?Carbon $startDate = null, ?Carbon
|
|
|
return [
|
|
|
'enrollments' => $this->enrollments($unitIds),
|
|
|
'birthdays' => $this->birthdays($unitIds),
|
|
|
+ 'attendance' => $this->attendance($unitIds, $startDate, $endDate),
|
|
|
'open_tickets' => $this->openTickets($unitIds),
|
|
|
+ 'tickets' => $this->tickets($unitIds),
|
|
|
'pending_tasks' => $this->pendingTasks($unitIds),
|
|
|
'general_revenue' => $this->generalRevenue($unitIds),
|
|
|
'product_stock' => $this->productStock(),
|
|
|
+ 'products' => $this->products(),
|
|
|
'units_summary' => $this->unitsSummary($unitIds, $startDate, $endDate),
|
|
|
];
|
|
|
}
|
|
|
@@ -143,11 +146,81 @@ private function birthdays(array $unitIds): array
|
|
|
|
|
|
private function openTickets(array $unitIds): int
|
|
|
{
|
|
|
- return (int) DB::table('support_tickets')
|
|
|
+ return (int) $this->openTicketsQuery($unitIds)->count();
|
|
|
+ }
|
|
|
+
|
|
|
+ private function tickets(array $unitIds): array
|
|
|
+ {
|
|
|
+ return $this->openTicketsQuery($unitIds)
|
|
|
+ ->orderByDesc('created_at')
|
|
|
+ ->get(['id', 'severity', 'created_at', 'sector', 'status', 'title'])
|
|
|
+ ->map(fn ($ticket) => [
|
|
|
+ 'id' => (int) $ticket->id,
|
|
|
+ 'number' => '#' . $ticket->id,
|
|
|
+ 'title' => $ticket->title,
|
|
|
+ 'priority' => $ticket->severity,
|
|
|
+ 'date' => Carbon::parse($ticket->created_at)->format('d/m/Y'),
|
|
|
+ 'sector' => $ticket->sector ?: 'Não informado',
|
|
|
+ 'status' => $ticket->status,
|
|
|
+ ])
|
|
|
+ ->all();
|
|
|
+ }
|
|
|
+
|
|
|
+ private function openTicketsQuery(array $unitIds)
|
|
|
+ {
|
|
|
+ return DB::table('support_tickets')
|
|
|
->whereNull('deleted_at')
|
|
|
->where('status', 'in_progress')
|
|
|
- ->when(!empty($unitIds), fn ($q) => $q->whereIn('unit_id', $unitIds))
|
|
|
- ->count();
|
|
|
+ ->when(!empty($unitIds), fn ($q) => $q->where(function ($units) use ($unitIds) {
|
|
|
+ $units->whereIn('applicant_unit_id', $unitIds)
|
|
|
+ ->orWhereIn('target_unit_id', $unitIds)
|
|
|
+ ->orWhereIn('unit_id', $unitIds);
|
|
|
+ }));
|
|
|
+ }
|
|
|
+
|
|
|
+ private function attendance(array $unitIds, Carbon $startDate, Carbon $endDate): array
|
|
|
+ {
|
|
|
+ $rows = DB::table('units as u')
|
|
|
+ ->leftJoin('classes as c', function ($join) use ($startDate, $endDate) {
|
|
|
+ $join->on('c.unit_id', '=', 'u.id')
|
|
|
+ ->whereNull('c.deleted_at')
|
|
|
+ ->whereBetween('c.date_time_start', [$startDate, $endDate]);
|
|
|
+ })
|
|
|
+ ->leftJoin('class_attendances as ca', function ($join) {
|
|
|
+ $join->on('ca.class_id', '=', 'c.id')->whereNull('ca.deleted_at');
|
|
|
+ })
|
|
|
+ ->whereNull('u.deleted_at')
|
|
|
+ ->when(!empty($unitIds), fn ($q) => $q->whereIn('u.id', $unitIds))
|
|
|
+ ->groupBy('u.id', 'u.fantasy_name')
|
|
|
+ ->orderBy('u.fantasy_name')
|
|
|
+ ->get([
|
|
|
+ 'u.id',
|
|
|
+ 'u.fantasy_name',
|
|
|
+ DB::raw('COUNT(ca.id) as attendance_count'),
|
|
|
+ DB::raw('SUM(CASE WHEN ca.in_class = 1 THEN 1 ELSE 0 END) as present_count'),
|
|
|
+ ]);
|
|
|
+
|
|
|
+ $total = (int) $rows->sum('attendance_count');
|
|
|
+ $present = (int) $rows->sum('present_count');
|
|
|
+
|
|
|
+ return [
|
|
|
+ 'average' => $total > 0 ? round(($present / $total) * 100, 1) : 0,
|
|
|
+ 'units' => $rows->map(function ($row) {
|
|
|
+ $count = (int) $row->attendance_count;
|
|
|
+ $average = $count > 0
|
|
|
+ ? round(((int) $row->present_count / $count) * 100, 1)
|
|
|
+ : 0;
|
|
|
+
|
|
|
+ return [
|
|
|
+ 'id' => (int) $row->id,
|
|
|
+ 'unit' => $row->fantasy_name,
|
|
|
+ 'frequency' => $average,
|
|
|
+ 'status' => $count === 0
|
|
|
+ ? 'Sem dados'
|
|
|
+ : ($average >= 70 ? 'Alto' : 'Baixa'),
|
|
|
+ ];
|
|
|
+ })->all(),
|
|
|
+ ];
|
|
|
}
|
|
|
|
|
|
private function pendingTasks(array $unitIds): int
|
|
|
@@ -184,4 +257,24 @@ private function productStock(): int
|
|
|
->whereNull('deleted_at')
|
|
|
->sum('quantity');
|
|
|
}
|
|
|
+
|
|
|
+ private function products(): array
|
|
|
+ {
|
|
|
+ return DB::table('products')
|
|
|
+ ->whereNull('deleted_at')
|
|
|
+ ->orderBy('name')
|
|
|
+ ->get(['id', 'name', 'quantity'])
|
|
|
+ ->map(function ($product) {
|
|
|
+ $quantity = (int) $product->quantity;
|
|
|
+
|
|
|
+ return [
|
|
|
+ 'id' => (int) $product->id,
|
|
|
+ 'name' => $product->name,
|
|
|
+ 'quantity' => $quantity,
|
|
|
+ 'status' => $quantity <= 15
|
|
|
+ ? 'Baixo'
|
|
|
+ : ($quantity <= 30 ? 'Limitado' : 'Alto'),
|
|
|
+ ];
|
|
|
+ })->all();
|
|
|
+ }
|
|
|
}
|