feat: enhance transaction handling with error management and database transactions in CashAccountService and controllers

This commit is contained in:
Yoga Pangestu 2026-07-29 21:07:30 +07:00
parent 912f576c74
commit d1f1d82099
3 changed files with 143 additions and 86 deletions

View File

@ -7,6 +7,7 @@
use App\Models\CashTransaction;
use App\Services\Admin\Finance\CashAccountService;
use Illuminate\Http\RedirectResponse;
use Illuminate\Validation\ValidationException;
use Inertia\Inertia;
use Inertia\Response;
@ -28,36 +29,64 @@ public function index(): Response
public function deposit(CashTransactionRequest $request): RedirectResponse
{
try {
$this->service->deposit($request->validated());
Inertia::flash('toast', ['type' => 'success', 'message' => 'Deposit berhasil ditambahkan.']);
} catch (ValidationException $e) {
$firstError = collect($e->errors())->flatten()->first();
Inertia::flash('toast', ['type' => 'error', 'message' => $firstError ?? 'Terjadi kesalahan.']);
} catch (\Exception $e) {
Inertia::flash('toast', ['type' => 'error', 'message' => $e->getMessage()]);
}
return to_route('admin.finance.cash-accounts.index');
}
public function withdrawal(CashTransactionRequest $request): RedirectResponse
{
try {
$this->service->withdrawal($request->validated());
Inertia::flash('toast', ['type' => 'success', 'message' => 'Withdrawal berhasil ditambahkan.']);
} catch (ValidationException $e) {
$firstError = collect($e->errors())->flatten()->first();
Inertia::flash('toast', ['type' => 'error', 'message' => $firstError ?? 'Terjadi kesalahan.']);
} catch (\Exception $e) {
Inertia::flash('toast', ['type' => 'error', 'message' => $e->getMessage()]);
}
return to_route('admin.finance.cash-accounts.index');
}
public function update(CashTransactionRequest $request, CashTransaction $transaction): RedirectResponse
{
try {
$this->service->updateTransaction($transaction, $request->validated());
Inertia::flash('toast', ['type' => 'success', 'message' => 'Transaksi berhasil diperbarui.']);
} catch (ValidationException $e) {
$firstError = collect($e->errors())->flatten()->first();
Inertia::flash('toast', ['type' => 'error', 'message' => $firstError ?? 'Terjadi kesalahan.']);
} catch (\Exception $e) {
Inertia::flash('toast', ['type' => 'error', 'message' => $e->getMessage()]);
}
return to_route('admin.finance.cash-accounts.index');
}
public function destroy(CashTransaction $transaction): RedirectResponse
{
try {
$this->service->deleteTransaction($transaction);
Inertia::flash('toast', ['type' => 'success', 'message' => 'Transaksi berhasil dihapus.']);
} catch (ValidationException $e) {
$firstError = collect($e->errors())->flatten()->first();
Inertia::flash('toast', ['type' => 'error', 'message' => $firstError ?? 'Terjadi kesalahan.']);
} catch (\Exception $e) {
Inertia::flash('toast', ['type' => 'error', 'message' => $e->getMessage()]);
}
return to_route('admin.finance.cash-accounts.index');
}

View File

@ -7,6 +7,7 @@
use App\Models\Expense;
use App\Services\Admin\Finance\ExpenseService;
use Illuminate\Http\RedirectResponse;
use Illuminate\Validation\ValidationException;
use Inertia\Inertia;
use Inertia\Response;
@ -25,27 +26,45 @@ public function index(): Response
public function store(ExpenseRequest $request): RedirectResponse
{
try {
$this->service->create($request->validated());
Inertia::flash('toast', ['type' => 'success', 'message' => 'Pengeluaran berhasil ditambahkan.']);
} catch (ValidationException $e) {
$firstError = collect($e->errors())->flatten()->first();
Inertia::flash('toast', ['type' => 'error', 'message' => $firstError ?? 'Terjadi kesalahan.']);
} catch (\Exception $e) {
Inertia::flash('toast', ['type' => 'error', 'message' => $e->getMessage()]);
}
return to_route('admin.finance.expenses.index');
}
public function update(ExpenseRequest $request, Expense $expense): RedirectResponse
{
try {
$this->service->update($expense, $request->validated());
Inertia::flash('toast', ['type' => 'success', 'message' => 'Pengeluaran berhasil diperbarui.']);
} catch (ValidationException $e) {
$firstError = collect($e->errors())->flatten()->first();
Inertia::flash('toast', ['type' => 'error', 'message' => $firstError ?? 'Terjadi kesalahan.']);
} catch (\Exception $e) {
Inertia::flash('toast', ['type' => 'error', 'message' => $e->getMessage()]);
}
return to_route('admin.finance.expenses.index');
}
public function destroy(Expense $expense): RedirectResponse
{
try {
$this->service->delete($expense);
Inertia::flash('toast', ['type' => 'success', 'message' => 'Pengeluaran berhasil dihapus.']);
} catch (\Exception $e) {
Inertia::flash('toast', ['type' => 'error', 'message' => $e->getMessage()]);
}
return to_route('admin.finance.expenses.index');
}

View File

@ -6,6 +6,7 @@
use App\Models\CashAccount;
use App\Models\CashTransaction;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;
use Illuminate\Validation\ValidationException;
class CashAccountService
@ -31,6 +32,7 @@ public function getAllTransactions(): Collection
public function deposit(array $data): CashTransaction
{
return DB::transaction(function () use ($data) {
$cashAccount = CashAccount::firstOrFail();
$newBalance = $cashAccount->balance + $data['amount'];
@ -44,10 +46,12 @@ public function deposit(array $data): CashTransaction
'type' => CashTransactionType::DEPOSIT,
'description' => $data['description'],
]);
});
}
public function withdrawal(array $data): CashTransaction
{
return DB::transaction(function () use ($data) {
$cashAccount = CashAccount::firstOrFail();
if ($cashAccount->balance < $data['amount']) {
@ -67,10 +71,12 @@ public function withdrawal(array $data): CashTransaction
'type' => CashTransactionType::WITHDRAWAL,
'description' => $data['description'],
]);
});
}
public function updateTransaction(CashTransaction $transaction, array $data): CashTransaction
{
return DB::transaction(function () use ($transaction, $data) {
if (! in_array($transaction->type, [CashTransactionType::DEPOSIT, CashTransactionType::WITHDRAWAL])) {
throw ValidationException::withMessages([
'amount' => 'Transaksi ini tidak dapat diedit.',
@ -100,10 +106,12 @@ public function updateTransaction(CashTransaction $transaction, array $data): Ca
]);
return $transaction;
});
}
public function deleteTransaction(CashTransaction $transaction): bool
{
return DB::transaction(function () use ($transaction) {
if (! in_array($transaction->type, [CashTransactionType::DEPOSIT, CashTransactionType::WITHDRAWAL])) {
throw ValidationException::withMessages([
'amount' => 'Transaksi ini tidak dapat dihapus.',
@ -126,5 +134,6 @@ public function deleteTransaction(CashTransaction $transaction): bool
$cashAccount->update(['balance' => $newBalance]);
return $transaction->delete();
});
}
}