Files
sam-api/app/Services/Stats/ProjectStatService.php

93 lines
3.2 KiB
PHP
Raw Normal View History

<?php
namespace App\Services\Stats;
use App\Models\Stats\Monthly\StatProjectMonthly;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;
class ProjectStatService implements StatDomainServiceInterface
{
public function aggregateDaily(int $tenantId, Carbon $date): int
{
// 건설/프로젝트는 월간 전용 (일간 집계 없음)
return 0;
}
public function aggregateMonthly(int $tenantId, int $year, int $month): int
{
$startDate = Carbon::create($year, $month, 1)->startOfDay();
$endDate = $startDate->copy()->endOfMonth();
// 현장 현황
$activeSites = DB::connection('mysql')
->table('sites')
->where('tenant_id', $tenantId)
->where('status', 'active')
->whereNull('deleted_at')
->count();
$completedSites = DB::connection('mysql')
->table('sites')
->where('tenant_id', $tenantId)
->where('status', 'completed')
->whereNull('deleted_at')
->count();
// 계약 현황 (해당 월 신규 계약)
$contractStats = DB::connection('mysql')
->table('contracts')
->where('tenant_id', $tenantId)
->whereBetween('created_at', [$startDate, $endDate])
->whereNull('deleted_at')
->selectRaw('
COUNT(*) as new_count,
COALESCE(SUM(contract_amount), 0) as total_amount
')
->first();
// 지출예상 (해당 월)
$expenseStats = DB::connection('mysql')
->table('expected_expenses')
->where('tenant_id', $tenantId)
->whereYear('expected_payment_date', $year)
->whereMonth('expected_payment_date', $month)
->whereNull('deleted_at')
->selectRaw('
COALESCE(SUM(amount), 0) as expected_total,
COALESCE(SUM(CASE WHEN payment_status = \'paid\' THEN amount ELSE 0 END), 0) as actual_total
')
->first();
// 수익률 계산
$contractTotal = (float) ($contractStats->total_amount ?? 0);
$actualExpense = (float) ($expenseStats->actual_total ?? 0);
$grossProfit = $contractTotal - $actualExpense;
$grossProfitRate = $contractTotal > 0 ? ($grossProfit / $contractTotal) * 100 : 0;
StatProjectMonthly::updateOrCreate(
[
'tenant_id' => $tenantId,
'stat_year' => $year,
'stat_month' => $month,
],
[
'active_site_count' => $activeSites,
'completed_site_count' => $completedSites,
'new_contract_count' => $contractStats->new_count ?? 0,
'contract_total_amount' => $contractTotal,
'expected_expense_total' => $expenseStats->expected_total ?? 0,
'actual_expense_total' => $actualExpense,
'labor_cost_total' => 0,
'material_cost_total' => 0,
'gross_profit' => $grossProfit,
'gross_profit_rate' => $grossProfitRate,
'handover_report_count' => 0,
'structure_review_count' => 0,
]
);
return 1;
}
}