You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

TransactionObserver.php 3.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. <?php
  2. namespace App\Observers;
  3. use App\Enums\Accounting\TransactionType;
  4. use App\Models\Accounting\Account;
  5. use App\Models\Accounting\JournalEntry;
  6. use App\Models\Accounting\Transaction;
  7. use Illuminate\Support\Facades\DB;
  8. class TransactionObserver
  9. {
  10. /**
  11. * Handle the Transaction "created" event.
  12. */
  13. public function created(Transaction $transaction): void
  14. {
  15. if ($transaction->type === TransactionType::Journal) {
  16. return;
  17. }
  18. $chartAccount = $transaction->account;
  19. $bankAccount = $transaction->bankAccount->account;
  20. $debitAccount = $transaction->type === TransactionType::Withdrawal ? $chartAccount : $bankAccount;
  21. $creditAccount = $transaction->type === TransactionType::Withdrawal ? $bankAccount : $chartAccount;
  22. $this->createJournalEntries($transaction, $debitAccount, $creditAccount);
  23. }
  24. private function createJournalEntries(Transaction $transaction, Account $debitAccount, Account $creditAccount): void
  25. {
  26. $debitAccount->journalEntries()->create([
  27. 'company_id' => $transaction->company_id,
  28. 'transaction_id' => $transaction->id,
  29. 'type' => 'debit',
  30. 'amount' => $transaction->amount,
  31. 'description' => $transaction->description,
  32. ]);
  33. $creditAccount->journalEntries()->create([
  34. 'company_id' => $transaction->company_id,
  35. 'transaction_id' => $transaction->id,
  36. 'type' => 'credit',
  37. 'amount' => $transaction->amount,
  38. 'description' => $transaction->description,
  39. ]);
  40. }
  41. /**
  42. * Handle the Transaction "updated" event.
  43. */
  44. public function updated(Transaction $transaction): void
  45. {
  46. $changes = $transaction->getChanges();
  47. $relevantChanges = array_intersect_key($changes, array_flip(['amount', 'description', 'account_id', 'bank_account_id', 'type']));
  48. if (empty($relevantChanges)) {
  49. return;
  50. }
  51. $chartAccount = $transaction->account;
  52. $bankAccount = $transaction->bankAccount->account;
  53. $journalEntries = $transaction->journalEntries;
  54. $debitEntry = $journalEntries->where('type', 'debit')->first();
  55. $creditEntry = $journalEntries->where('type', 'credit')->first();
  56. $debitAccount = $transaction->type === TransactionType::Withdrawal ? $chartAccount : $bankAccount;
  57. $creditAccount = $transaction->type === TransactionType::Withdrawal ? $bankAccount : $chartAccount;
  58. $debitEntry?->update([
  59. 'account_id' => $debitAccount->id,
  60. 'amount' => $transaction->amount,
  61. 'description' => $transaction->description,
  62. ]);
  63. $creditEntry?->update([
  64. 'account_id' => $creditAccount->id,
  65. 'amount' => $transaction->amount,
  66. 'description' => $transaction->description,
  67. ]);
  68. }
  69. /**
  70. * Handle the Transaction "deleting" event.
  71. */
  72. public function deleting(Transaction $transaction): void
  73. {
  74. DB::transaction(static function () use ($transaction) {
  75. $transaction->journalEntries()->each(fn (JournalEntry $entry) => $entry->delete());
  76. });
  77. }
  78. /**
  79. * Handle the Transaction "deleted" event.
  80. */
  81. public function deleted(Transaction $transaction): void
  82. {
  83. //
  84. }
  85. /**
  86. * Handle the Transaction "restored" event.
  87. */
  88. public function restored(Transaction $transaction): void
  89. {
  90. //
  91. }
  92. /**
  93. * Handle the Transaction "force deleted" event.
  94. */
  95. public function forceDeleted(Transaction $transaction): void
  96. {
  97. //
  98. }
  99. }