180 lines
5.2 KiB
PHP
180 lines
5.2 KiB
PHP
|
|
<?php
|
||
|
|
|
||
|
|
namespace App\Services\Stats;
|
||
|
|
|
||
|
|
use App\Models\Stats\Daily\StatFinanceDaily;
|
||
|
|
use App\Models\Stats\Daily\StatHrAttendanceDaily;
|
||
|
|
use App\Models\Stats\Daily\StatInventoryDaily;
|
||
|
|
use App\Models\Stats\Daily\StatProductionDaily;
|
||
|
|
use App\Models\Stats\Daily\StatQuotePipelineDaily;
|
||
|
|
use App\Models\Stats\Daily\StatSalesDaily;
|
||
|
|
use App\Models\Stats\Daily\StatSystemDaily;
|
||
|
|
use App\Models\Stats\Monthly\StatFinanceMonthly;
|
||
|
|
use App\Models\Stats\Monthly\StatProductionMonthly;
|
||
|
|
use App\Models\Stats\Monthly\StatProjectMonthly;
|
||
|
|
use App\Models\Stats\Monthly\StatSalesMonthly;
|
||
|
|
use App\Models\Stats\StatAlert;
|
||
|
|
use App\Services\Service;
|
||
|
|
use Carbon\Carbon;
|
||
|
|
|
||
|
|
class StatQueryService extends Service
|
||
|
|
{
|
||
|
|
/**
|
||
|
|
* 도메인별 일간 통계 조회
|
||
|
|
*/
|
||
|
|
public function getDailyStat(string $domain, array $params): array
|
||
|
|
{
|
||
|
|
$tenantId = $this->tenantId();
|
||
|
|
$startDate = $params['start_date'];
|
||
|
|
$endDate = $params['end_date'];
|
||
|
|
|
||
|
|
$model = $this->getDailyModel($domain);
|
||
|
|
if (! $model) {
|
||
|
|
return [];
|
||
|
|
}
|
||
|
|
|
||
|
|
return $model::where('tenant_id', $tenantId)
|
||
|
|
->whereBetween('stat_date', [$startDate, $endDate])
|
||
|
|
->orderBy('stat_date')
|
||
|
|
->get()
|
||
|
|
->toArray();
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 도메인별 월간 통계 조회
|
||
|
|
*/
|
||
|
|
public function getMonthlyStat(string $domain, array $params): array
|
||
|
|
{
|
||
|
|
$tenantId = $this->tenantId();
|
||
|
|
$year = (int) $params['year'];
|
||
|
|
$month = isset($params['month']) ? (int) $params['month'] : null;
|
||
|
|
|
||
|
|
$model = $this->getMonthlyModel($domain);
|
||
|
|
if (! $model) {
|
||
|
|
return [];
|
||
|
|
}
|
||
|
|
|
||
|
|
$query = $model::where('tenant_id', $tenantId)
|
||
|
|
->where('stat_year', $year);
|
||
|
|
|
||
|
|
if ($month) {
|
||
|
|
$query->where('stat_month', $month);
|
||
|
|
}
|
||
|
|
|
||
|
|
return $query->orderBy('stat_month')
|
||
|
|
->get()
|
||
|
|
->toArray();
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 대시보드 요약 통계 (sam_stat 기반)
|
||
|
|
*/
|
||
|
|
public function getDashboardSummary(): array
|
||
|
|
{
|
||
|
|
$tenantId = $this->tenantId();
|
||
|
|
$today = Carbon::today()->format('Y-m-d');
|
||
|
|
$year = Carbon::now()->year;
|
||
|
|
$month = Carbon::now()->month;
|
||
|
|
|
||
|
|
return [
|
||
|
|
'sales_today' => $this->getTodaySales($tenantId, $today),
|
||
|
|
'finance_today' => $this->getTodayFinance($tenantId, $today),
|
||
|
|
'production_today' => $this->getTodayProduction($tenantId, $today),
|
||
|
|
'sales_monthly' => $this->getMonthlySalesOverview($tenantId, $year, $month),
|
||
|
|
'alerts' => $this->getActiveAlerts($tenantId),
|
||
|
|
];
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 알림 목록 조회
|
||
|
|
*/
|
||
|
|
public function getAlerts(array $params): array
|
||
|
|
{
|
||
|
|
$tenantId = $this->tenantId();
|
||
|
|
$limit = $params['limit'] ?? 20;
|
||
|
|
$unreadOnly = $params['unread_only'] ?? false;
|
||
|
|
|
||
|
|
$query = StatAlert::where('tenant_id', $tenantId)
|
||
|
|
->orderByDesc('created_at');
|
||
|
|
|
||
|
|
if ($unreadOnly) {
|
||
|
|
$query->where('is_read', false);
|
||
|
|
}
|
||
|
|
|
||
|
|
return $query->limit($limit)->get()->toArray();
|
||
|
|
}
|
||
|
|
|
||
|
|
private function getTodaySales(int $tenantId, string $today): ?array
|
||
|
|
{
|
||
|
|
$stat = StatSalesDaily::where('tenant_id', $tenantId)
|
||
|
|
->where('stat_date', $today)
|
||
|
|
->first();
|
||
|
|
|
||
|
|
return $stat?->toArray();
|
||
|
|
}
|
||
|
|
|
||
|
|
private function getTodayFinance(int $tenantId, string $today): ?array
|
||
|
|
{
|
||
|
|
$stat = StatFinanceDaily::where('tenant_id', $tenantId)
|
||
|
|
->where('stat_date', $today)
|
||
|
|
->first();
|
||
|
|
|
||
|
|
return $stat?->toArray();
|
||
|
|
}
|
||
|
|
|
||
|
|
private function getTodayProduction(int $tenantId, string $today): ?array
|
||
|
|
{
|
||
|
|
$stat = StatProductionDaily::where('tenant_id', $tenantId)
|
||
|
|
->where('stat_date', $today)
|
||
|
|
->first();
|
||
|
|
|
||
|
|
return $stat?->toArray();
|
||
|
|
}
|
||
|
|
|
||
|
|
private function getMonthlySalesOverview(int $tenantId, int $year, int $month): ?array
|
||
|
|
{
|
||
|
|
$stat = StatSalesMonthly::where('tenant_id', $tenantId)
|
||
|
|
->where('stat_year', $year)
|
||
|
|
->where('stat_month', $month)
|
||
|
|
->first();
|
||
|
|
|
||
|
|
return $stat?->toArray();
|
||
|
|
}
|
||
|
|
|
||
|
|
private function getActiveAlerts(int $tenantId): array
|
||
|
|
{
|
||
|
|
return StatAlert::where('tenant_id', $tenantId)
|
||
|
|
->where('is_read', false)
|
||
|
|
->where('is_resolved', false)
|
||
|
|
->orderByDesc('created_at')
|
||
|
|
->limit(10)
|
||
|
|
->get()
|
||
|
|
->toArray();
|
||
|
|
}
|
||
|
|
|
||
|
|
private function getDailyModel(string $domain): ?string
|
||
|
|
{
|
||
|
|
return match ($domain) {
|
||
|
|
'sales' => StatSalesDaily::class,
|
||
|
|
'finance' => StatFinanceDaily::class,
|
||
|
|
'production' => StatProductionDaily::class,
|
||
|
|
'inventory' => StatInventoryDaily::class,
|
||
|
|
'quote' => StatQuotePipelineDaily::class,
|
||
|
|
'hr' => StatHrAttendanceDaily::class,
|
||
|
|
'system' => StatSystemDaily::class,
|
||
|
|
default => null,
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
private function getMonthlyModel(string $domain): ?string
|
||
|
|
{
|
||
|
|
return match ($domain) {
|
||
|
|
'sales' => StatSalesMonthly::class,
|
||
|
|
'finance' => StatFinanceMonthly::class,
|
||
|
|
'production' => StatProductionMonthly::class,
|
||
|
|
'project' => StatProjectMonthly::class,
|
||
|
|
default => null,
|
||
|
|
};
|
||
|
|
}
|
||
|
|
}
|