Files
sam-api/app/Services/CondolenceExpenseService.php

190 lines
7.0 KiB
PHP
Raw Normal View History

<?php
namespace App\Services;
use App\Models\Tenants\CondolenceExpense;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use Illuminate\Support\Facades\DB;
class CondolenceExpenseService extends Service
{
/**
* 목록 조회 (페이지네이션 + 필터)
*/
public function index(array $params): LengthAwarePaginator
{
$query = CondolenceExpense::query();
// 연도 필터
if (! empty($params['year'])) {
$query->inYear((int) $params['year']);
}
// 카테고리 필터
if (! empty($params['category']) && $params['category'] !== 'all') {
$query->byCategory($params['category']);
}
// 통합 검색
if (! empty($params['search'])) {
$search = $params['search'];
$query->where(function ($q) use ($search) {
$q->where('partner_name', 'like', "%{$search}%")
->orWhere('description', 'like', "%{$search}%")
->orWhere('memo', 'like', "%{$search}%");
});
}
// 정렬
$sortBy = $params['sort_by'] ?? 'event_date';
$sortOrder = $params['sort_order'] ?? 'desc';
$query->orderBy($sortBy, $sortOrder)->orderByDesc('id');
$perPage = $params['per_page'] ?? 50;
return $query->paginate($perPage);
}
/**
* 상세 조회
*/
public function show(int $id): CondolenceExpense
{
return CondolenceExpense::with('creator:id,name')->findOrFail($id);
}
/**
* 등록
*/
public function store(array $data): CondolenceExpense
{
$tenantId = $this->tenantId();
$userId = $this->apiUserId();
return DB::transaction(function () use ($data, $tenantId, $userId) {
return CondolenceExpense::create([
'tenant_id' => $tenantId,
'event_date' => $data['event_date'] ?? null,
'expense_date' => $data['expense_date'] ?? null,
'partner_name' => $data['partner_name'],
'description' => $data['description'] ?? null,
'category' => $data['category'],
'has_cash' => $data['has_cash'] ?? false,
'cash_method' => ($data['has_cash'] ?? false) ? ($data['cash_method'] ?? null) : null,
'cash_amount' => ($data['has_cash'] ?? false) ? ($data['cash_amount'] ?? 0) : 0,
'has_gift' => $data['has_gift'] ?? false,
'gift_type' => ($data['has_gift'] ?? false) ? ($data['gift_type'] ?? null) : null,
'gift_amount' => ($data['has_gift'] ?? false) ? ($data['gift_amount'] ?? 0) : 0,
'total_amount' => $this->calculateTotal($data),
'memo' => $data['memo'] ?? null,
'created_by' => $userId,
'updated_by' => $userId,
]);
});
}
/**
* 수정
*/
public function update(int $id, array $data): CondolenceExpense
{
$userId = $this->apiUserId();
return DB::transaction(function () use ($id, $data, $userId) {
$expense = CondolenceExpense::findOrFail($id);
$expense->fill([
'event_date' => $data['event_date'] ?? $expense->event_date,
'expense_date' => $data['expense_date'] ?? $expense->expense_date,
'partner_name' => $data['partner_name'] ?? $expense->partner_name,
'description' => $data['description'] ?? $expense->description,
'category' => $data['category'] ?? $expense->category,
'has_cash' => $data['has_cash'] ?? $expense->has_cash,
'cash_method' => ($data['has_cash'] ?? $expense->has_cash) ? ($data['cash_method'] ?? $expense->cash_method) : null,
'cash_amount' => ($data['has_cash'] ?? $expense->has_cash) ? ($data['cash_amount'] ?? $expense->cash_amount) : 0,
'has_gift' => $data['has_gift'] ?? $expense->has_gift,
'gift_type' => ($data['has_gift'] ?? $expense->has_gift) ? ($data['gift_type'] ?? $expense->gift_type) : null,
'gift_amount' => ($data['has_gift'] ?? $expense->has_gift) ? ($data['gift_amount'] ?? $expense->gift_amount) : 0,
'total_amount' => $this->calculateTotal(array_merge($expense->toArray(), $data)),
'memo' => $data['memo'] ?? $expense->memo,
'updated_by' => $userId,
]);
$expense->save();
return $expense->fresh();
});
}
/**
* 삭제 (소프트)
*/
public function destroy(int $id): bool
{
$userId = $this->apiUserId();
return DB::transaction(function () use ($id, $userId) {
$expense = CondolenceExpense::findOrFail($id);
$expense->deleted_by = $userId;
$expense->save();
$expense->delete();
return true;
});
}
/**
* 통계 조회
*/
public function summary(array $params): array
{
$query = CondolenceExpense::query();
if (! empty($params['year'])) {
$query->inYear((int) $params['year']);
}
if (! empty($params['category']) && $params['category'] !== 'all') {
$query->byCategory($params['category']);
}
$stats = $query->selectRaw('
COUNT(*) as total_count,
COALESCE(SUM(total_amount), 0) as total_amount,
COALESCE(SUM(cash_amount), 0) as cash_total,
COALESCE(SUM(gift_amount), 0) as gift_total,
COALESCE(SUM(CASE WHEN category = ? THEN 1 ELSE 0 END), 0) as congratulation_count,
COALESCE(SUM(CASE WHEN category = ? THEN 1 ELSE 0 END), 0) as condolence_count,
COALESCE(SUM(CASE WHEN category = ? THEN total_amount ELSE 0 END), 0) as congratulation_amount,
COALESCE(SUM(CASE WHEN category = ? THEN total_amount ELSE 0 END), 0) as condolence_amount
', [
CondolenceExpense::CATEGORY_CONGRATULATION,
CondolenceExpense::CATEGORY_CONDOLENCE,
CondolenceExpense::CATEGORY_CONGRATULATION,
CondolenceExpense::CATEGORY_CONDOLENCE,
])->first();
return [
'total_count' => (int) $stats->total_count,
'total_amount' => (int) $stats->total_amount,
'cash_total' => (int) $stats->cash_total,
'gift_total' => (int) $stats->gift_total,
'congratulation_count' => (int) $stats->congratulation_count,
'condolence_count' => (int) $stats->condolence_count,
'congratulation_amount' => (int) $stats->congratulation_amount,
'condolence_amount' => (int) $stats->condolence_amount,
];
}
/**
* 총금액 자동 계산
*/
private function calculateTotal(array $data): int
{
$cash = ($data['has_cash'] ?? false) ? (int) ($data['cash_amount'] ?? 0) : 0;
$gift = ($data['has_gift'] ?? false) ? (int) ($data['gift_amount'] ?? 0) : 0;
return $cash + $gift;
}
}