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

259 lines
8.5 KiB
PHP
Raw Normal View History

<?php
namespace App\Services;
use App\Models\Tenants\BankAccount;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use Illuminate\Support\Facades\DB;
class BankAccountService extends Service
{
/**
* 계좌 목록 조회
*/
public function index(array $params): LengthAwarePaginator
{
$tenantId = $this->tenantId();
$query = BankAccount::query()
->where('tenant_id', $tenantId);
// 검색 필터
if (! empty($params['search'])) {
$search = $params['search'];
$query->where(function ($q) use ($search) {
$q->where('account_name', 'like', "%{$search}%")
->orWhere('bank_name', 'like', "%{$search}%")
->orWhere('account_holder', 'like', "%{$search}%")
->orWhere('account_number', 'like', "%{$search}%");
});
}
// 상태 필터
if (! empty($params['status'])) {
$query->where('status', $params['status']);
}
// 담당자 필터
if (! empty($params['assigned_user_id'])) {
$query->where('assigned_user_id', $params['assigned_user_id']);
}
// 대표계좌만 필터
if (isset($params['is_primary']) && $params['is_primary']) {
$query->where('is_primary', true);
}
// 정렬: 대표계좌 먼저, 그 다음 생성일순
$query->orderByDesc('is_primary')
->orderBy($params['sort_by'] ?? 'created_at', $params['sort_dir'] ?? 'desc');
// 페이지네이션
$perPage = $params['per_page'] ?? 20;
return $query->paginate($perPage);
}
/**
* 계좌 상세 조회
*/
public function show(int $id): BankAccount
{
$tenantId = $this->tenantId();
return BankAccount::query()
->where('tenant_id', $tenantId)
->with(['assignedUser:id,name'])
->findOrFail($id);
}
/**
* 계좌 등록
*/
public function store(array $data): BankAccount
{
$tenantId = $this->tenantId();
$userId = $this->apiUserId();
return DB::transaction(function () use ($data, $tenantId, $userId) {
// 첫 번째 계좌인 경우 자동으로 대표계좌 설정
$isFirst = BankAccount::where('tenant_id', $tenantId)->count() === 0;
$isPrimary = $data['is_primary'] ?? $isFirst;
// 대표계좌로 설정 시 기존 대표계좌 해제
if ($isPrimary) {
BankAccount::where('tenant_id', $tenantId)
->where('is_primary', true)
->update(['is_primary' => false]);
}
$account = BankAccount::create([
'tenant_id' => $tenantId,
'bank_code' => $data['bank_code'],
'bank_name' => $data['bank_name'],
'account_number' => $data['account_number'],
'account_holder' => $data['account_holder'],
'account_name' => $data['account_name'],
'account_type' => $data['account_type'] ?? null,
'balance' => $data['balance'] ?? 0,
'currency' => $data['currency'] ?? 'KRW',
'opened_at' => $data['opened_at'] ?? null,
'branch_name' => $data['branch_name'] ?? null,
'memo' => $data['memo'] ?? null,
'status' => $data['status'] ?? 'active',
'assigned_user_id' => $data['assigned_user_id'] ?? null,
'is_primary' => $isPrimary,
'sort_order' => $data['sort_order'] ?? 0,
'created_by' => $userId,
'updated_by' => $userId,
]);
return $account;
});
}
/**
* 계좌 수정
*/
public function update(int $id, array $data): BankAccount
{
$tenantId = $this->tenantId();
$userId = $this->apiUserId();
return DB::transaction(function () use ($id, $data, $tenantId, $userId) {
$account = BankAccount::query()
->where('tenant_id', $tenantId)
->findOrFail($id);
$account->fill([
'bank_code' => $data['bank_code'] ?? $account->bank_code,
'bank_name' => $data['bank_name'] ?? $account->bank_name,
'account_number' => $data['account_number'] ?? $account->account_number,
'account_holder' => $data['account_holder'] ?? $account->account_holder,
'account_name' => $data['account_name'] ?? $account->account_name,
'account_type' => $data['account_type'] ?? $account->account_type,
'balance' => $data['balance'] ?? $account->balance,
'currency' => $data['currency'] ?? $account->currency,
'opened_at' => $data['opened_at'] ?? $account->opened_at,
'branch_name' => $data['branch_name'] ?? $account->branch_name,
'memo' => $data['memo'] ?? $account->memo,
'status' => $data['status'] ?? $account->status,
'assigned_user_id' => $data['assigned_user_id'] ?? $account->assigned_user_id,
'sort_order' => $data['sort_order'] ?? $account->sort_order,
'updated_by' => $userId,
]);
$account->save();
return $account->fresh();
});
}
/**
* 계좌 삭제
*/
public function destroy(int $id): bool
{
$tenantId = $this->tenantId();
$userId = $this->apiUserId();
return DB::transaction(function () use ($id, $tenantId, $userId) {
$account = BankAccount::query()
->where('tenant_id', $tenantId)
->findOrFail($id);
// 대표계좌 삭제 시 다른 계좌를 대표로 설정
if ($account->is_primary) {
$nextPrimary = BankAccount::where('tenant_id', $tenantId)
->where('id', '!=', $id)
->where('status', 'active')
->first();
if ($nextPrimary) {
$nextPrimary->is_primary = true;
$nextPrimary->save();
}
}
$account->deleted_by = $userId;
$account->save();
$account->delete();
return true;
});
}
/**
* 계좌 상태 토글 (사용/정지)
*/
public function toggleStatus(int $id): BankAccount
{
$tenantId = $this->tenantId();
$userId = $this->apiUserId();
return DB::transaction(function () use ($id, $tenantId, $userId) {
$account = BankAccount::query()
->where('tenant_id', $tenantId)
->findOrFail($id);
$account->toggleStatus();
$account->updated_by = $userId;
$account->save();
return $account;
});
}
/**
* 대표계좌 설정
*/
public function setPrimary(int $id): BankAccount
{
$tenantId = $this->tenantId();
$userId = $this->apiUserId();
return DB::transaction(function () use ($id, $tenantId, $userId) {
// 기존 대표계좌 해제
BankAccount::where('tenant_id', $tenantId)
->where('is_primary', true)
->update(['is_primary' => false]);
// 새 대표계좌 설정
$account = BankAccount::query()
->where('tenant_id', $tenantId)
->findOrFail($id);
$account->is_primary = true;
$account->updated_by = $userId;
$account->save();
return $account;
});
}
/**
* 활성 계좌 목록 조회 (셀렉트박스용)
*/
public function getActiveAccounts(): array
{
$tenantId = $this->tenantId();
return BankAccount::query()
->where('tenant_id', $tenantId)
->where('status', 'active')
->orderByDesc('is_primary')
->orderBy('account_name')
->get(['id', 'account_name', 'bank_name', 'account_number', 'is_primary'])
->map(function ($account) {
return [
'id' => $account->id,
'account_name' => $account->account_name,
'bank_name' => $account->bank_name,
'display_number' => $account->getMaskedAccountNumber(),
'is_primary' => $account->is_primary,
];
})
->toArray();
}
}