first(); } public function getAllTransactions(): Collection { $cashAccount = $this->get(); if (! $cashAccount) { return collect(); } return $cashAccount->cashTransactions() ->select('id', 'created_by_id', 'reference_type', 'reference_id', 'amount', 'balance_after', 'type', 'description', 'created_at') ->with('createdBy.userProfile') ->latest() ->get(); } public function deposit(array $data): CashTransaction { return DB::transaction(function () use ($data) { $cashAccount = CashAccount::firstOrFail(); $newBalance = $cashAccount->balance + $data['amount']; $cashAccount->update(['balance' => $newBalance]); return CashTransaction::create([ 'cash_account_id' => $cashAccount->id, 'created_by_id' => auth()->id(), 'amount' => $data['amount'], 'balance_after' => $newBalance, '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']) { throw ValidationException::withMessages([ 'amount' => 'Saldo tidak mencukupi.', ]); } $newBalance = $cashAccount->balance - $data['amount']; $cashAccount->update(['balance' => $newBalance]); return CashTransaction::create([ 'cash_account_id' => $cashAccount->id, 'created_by_id' => auth()->id(), 'amount' => $data['amount'], 'balance_after' => $newBalance, '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.', ]); } $cashAccount = CashAccount::firstOrFail(); $oldAmount = $transaction->amount; $newAmount = $data['amount']; $isDeposit = $transaction->type === CashTransactionType::DEPOSIT; $difference = $isDeposit ? $newAmount - $oldAmount : $oldAmount - $newAmount; if ($difference < 0 && $cashAccount->balance < abs($difference)) { throw ValidationException::withMessages([ 'amount' => 'Saldo tidak mencukupi.', ]); } $newBalance = $cashAccount->balance + $difference; $cashAccount->update(['balance' => $newBalance]); $transaction->update([ 'amount' => $newAmount, 'balance_after' => $newBalance, 'description' => $data['description'], ]); 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.', ]); } $cashAccount = CashAccount::firstOrFail(); $isDeposit = $transaction->type === CashTransactionType::DEPOSIT; $newBalance = $isDeposit ? $cashAccount->balance - $transaction->amount : $cashAccount->balance + $transaction->amount; if ($newBalance < 0) { throw ValidationException::withMessages([ 'amount' => 'Saldo tidak mencukupi untuk menghapus transaksi ini.', ]); } $cashAccount->update(['balance' => $newBalance]); return $transaction->delete(); }); } }