Files
sam-manage/app/Http/Controllers/Api/Admin/BankAccountController.php
2026-02-25 11:45:01 +09:00

376 lines
11 KiB
PHP

<?php
namespace App\Http\Controllers\Api\Admin;
use App\Http\Controllers\Controller;
use App\Services\BankAccountService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
class BankAccountController extends Controller
{
public function __construct(
private BankAccountService $bankAccountService
) {}
/**
* 계좌 목록 조회
*/
public function index(Request $request): JsonResponse|Response
{
$accounts = $this->bankAccountService->getAccounts(
$request->all(),
$request->integer('per_page', 15)
);
// HTMX 요청인 경우 HTML 반환
if ($request->header('HX-Request')) {
return response(view('finance.accounts.partials.table', compact('accounts')));
}
return response()->json([
'success' => true,
'data' => $accounts->items(),
'meta' => [
'current_page' => $accounts->currentPage(),
'last_page' => $accounts->lastPage(),
'per_page' => $accounts->perPage(),
'total' => $accounts->total(),
],
]);
}
/**
* 계좌 상세 조회
*/
public function show(int $id): JsonResponse
{
$account = $this->bankAccountService->getAccountById($id);
if (! $account) {
return response()->json([
'success' => false,
'message' => '계좌를 찾을 수 없습니다.',
], 404);
}
return response()->json([
'success' => true,
'data' => $account,
]);
}
/**
* 계좌 생성
*/
public function store(Request $request): JsonResponse
{
$validated = $request->validate([
'bank_code' => 'nullable|string|max:10',
'bank_name' => 'required|string|max:50',
'account_number' => 'required|string|max:30',
'account_holder' => 'required|string|max:50',
'account_name' => 'nullable|string|max:100',
'account_type' => 'nullable|string|max:30',
'balance' => 'nullable|numeric|min:0',
'currency' => 'nullable|string|max:3',
'opened_at' => 'nullable|date',
'branch_name' => 'nullable|string|max:100',
'memo' => 'nullable|string',
'status' => 'nullable|string|in:active,inactive',
'is_primary' => 'nullable|boolean',
'sort_order' => 'nullable|integer|min:0',
]);
// 기본값 설정
$validated['status'] = $validated['status'] ?? 'active';
$validated['account_name'] = $validated['account_name'] ?? $validated['bank_name'].' 계좌';
$account = $this->bankAccountService->createAccount($validated);
return response()->json([
'success' => true,
'message' => '계좌가 등록되었습니다.',
'data' => $account,
], 201);
}
/**
* 계좌 수정
*/
public function update(Request $request, int $id): JsonResponse
{
$account = $this->bankAccountService->getAccountById($id);
if (! $account) {
return response()->json([
'success' => false,
'message' => '계좌를 찾을 수 없습니다.',
], 404);
}
$validated = $request->validate([
'bank_code' => 'nullable|string|max:10',
'bank_name' => 'sometimes|required|string|max:50',
'account_number' => 'sometimes|required|string|max:30',
'account_holder' => 'nullable|string|max:50',
'account_name' => 'nullable|string|max:100',
'account_type' => 'nullable|string|max:30',
'balance' => 'nullable|numeric|min:0',
'currency' => 'nullable|string|max:3',
'opened_at' => 'nullable|date',
'branch_name' => 'nullable|string|max:100',
'memo' => 'nullable|string',
'status' => 'nullable|string|in:active,inactive',
'is_primary' => 'nullable|boolean',
'sort_order' => 'nullable|integer|min:0',
]);
$account = $this->bankAccountService->updateAccount($account, $validated);
return response()->json([
'success' => true,
'message' => '계좌가 수정되었습니다.',
'data' => $account,
]);
}
/**
* 계좌 삭제 (Soft Delete)
*/
public function destroy(Request $request, int $id): JsonResponse|Response
{
$account = $this->bankAccountService->getAccountById($id);
if (! $account) {
return response()->json([
'success' => false,
'message' => '계좌를 찾을 수 없습니다.',
], 404);
}
$this->bankAccountService->deleteAccount($account);
// HTMX 요청인 경우 갱신된 테이블 반환
if ($request->header('HX-Request')) {
$accounts = $this->bankAccountService->getAccounts($request->all(), $request->integer('per_page', 15));
return response(view('finance.accounts.partials.table', compact('accounts')));
}
return response()->json([
'success' => true,
'message' => '계좌가 삭제되었습니다.',
]);
}
/**
* 계좌 복원
*/
public function restore(Request $request, int $id): JsonResponse|Response
{
$account = $this->bankAccountService->getAccountById($id, withTrashed: true);
if (! $account) {
return response()->json([
'success' => false,
'message' => '계좌를 찾을 수 없습니다.',
], 404);
}
$this->bankAccountService->restoreAccount($account);
// HTMX 요청인 경우 갱신된 테이블 반환
if ($request->header('HX-Request')) {
$accounts = $this->bankAccountService->getAccounts($request->all(), $request->integer('per_page', 15));
return response(view('finance.accounts.partials.table', compact('accounts')));
}
return response()->json([
'success' => true,
'message' => '계좌가 복원되었습니다.',
]);
}
/**
* 계좌 영구 삭제
*/
public function forceDelete(Request $request, int $id): JsonResponse|Response
{
$account = $this->bankAccountService->getAccountById($id, withTrashed: true);
if (! $account) {
return response()->json([
'success' => false,
'message' => '계좌를 찾을 수 없습니다.',
], 404);
}
$this->bankAccountService->forceDeleteAccount($account);
// HTMX 요청인 경우 갱신된 테이블 반환
if ($request->header('HX-Request')) {
$accounts = $this->bankAccountService->getAccounts($request->all(), $request->integer('per_page', 15));
return response(view('finance.accounts.partials.table', compact('accounts')));
}
return response()->json([
'success' => true,
'message' => '계좌가 영구 삭제되었습니다.',
]);
}
/**
* 활성/비활성 토글
*/
public function toggleActive(Request $request, int $id): JsonResponse|Response
{
$account = $this->bankAccountService->getAccountById($id);
if (! $account) {
return response()->json([
'success' => false,
'message' => '계좌를 찾을 수 없습니다.',
], 404);
}
$account = $this->bankAccountService->toggleActive($account);
// HTMX 요청인 경우 갱신된 테이블 반환
if ($request->header('HX-Request')) {
$accounts = $this->bankAccountService->getAccounts($request->all(), $request->integer('per_page', 15));
return response(view('finance.accounts.partials.table', compact('accounts')));
}
return response()->json([
'success' => true,
'message' => $account->status === 'active' ? '계좌가 활성화되었습니다.' : '계좌가 비활성화되었습니다.',
'data' => $account,
]);
}
/**
* 일괄 삭제
*/
public function bulkDelete(Request $request): JsonResponse
{
$validated = $request->validate([
'ids' => 'required|array|min:1',
'ids.*' => 'integer|exists:bank_accounts,id',
]);
$count = $this->bankAccountService->bulkDelete($validated['ids']);
return response()->json([
'success' => true,
'message' => "{$count}개의 계좌가 삭제되었습니다.",
]);
}
/**
* 일괄 복원
*/
public function bulkRestore(Request $request): JsonResponse
{
$validated = $request->validate([
'ids' => 'required|array|min:1',
'ids.*' => 'integer',
]);
$count = $this->bankAccountService->bulkRestore($validated['ids']);
return response()->json([
'success' => true,
'message' => "{$count}개의 계좌가 복원되었습니다.",
]);
}
/**
* 일괄 영구 삭제
*/
public function bulkForceDelete(Request $request): JsonResponse
{
$validated = $request->validate([
'ids' => 'required|array|min:1',
'ids.*' => 'integer',
]);
$count = $this->bankAccountService->bulkForceDelete($validated['ids']);
return response()->json([
'success' => true,
'message' => "{$count}개의 계좌가 영구 삭제되었습니다.",
]);
}
/**
* 모든 계좌 목록 (드롭다운용)
*/
public function all(): JsonResponse
{
$accounts = $this->bankAccountService->getAllAccounts();
return response()->json([
'success' => true,
'data' => $accounts,
]);
}
/**
* 요약 통계
*/
public function summary(): JsonResponse
{
$summary = $this->bankAccountService->getSummary();
return response()->json([
'success' => true,
'data' => $summary,
]);
}
/**
* 계좌의 거래내역 조회
*/
public function transactions(Request $request, int $id): JsonResponse|Response
{
$account = $this->bankAccountService->getAccountById($id);
if (! $account) {
return response()->json([
'success' => false,
'message' => '계좌를 찾을 수 없습니다.',
], 404);
}
$transactions = $this->bankAccountService->getTransactions(
$id,
$request->all(),
$request->integer('per_page', 20)
);
// HTMX 요청인 경우 HTML 반환
if ($request->header('HX-Request')) {
return response(view('finance.accounts.partials.transactions-table', compact('account', 'transactions')));
}
return response()->json([
'success' => true,
'data' => [
'account' => $account,
'transactions' => $transactions->items(),
],
'meta' => [
'current_page' => $transactions->currentPage(),
'last_page' => $transactions->lastPage(),
'per_page' => $transactions->perPage(),
'total' => $transactions->total(),
],
]);
}
}