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.

JournalEntryObserver.php 3.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. <?php
  2. namespace App\Observers;
  3. use App\Enums\Accounting\AccountCategory;
  4. use App\Models\Accounting\Account;
  5. use App\Models\Accounting\JournalEntry;
  6. class JournalEntryObserver
  7. {
  8. /**
  9. * Handle the JournalEntry "created" event.
  10. */
  11. public function created(JournalEntry $journalEntry): void
  12. {
  13. $account = $journalEntry->account;
  14. if ($account) {
  15. $this->adjustBalance($account, $journalEntry->type, $journalEntry->amount);
  16. }
  17. }
  18. private function updateEndingBalance(Account $account): void
  19. {
  20. $netMovementStrategy = match ($account->category) {
  21. AccountCategory::Asset, AccountCategory::Expense => $account->debit_balance - $account->credit_balance,
  22. AccountCategory::Liability, AccountCategory::Equity, AccountCategory::Revenue => $account->credit_balance - $account->debit_balance,
  23. };
  24. $account->net_movement = $netMovementStrategy;
  25. if (in_array($account->category, [AccountCategory::Asset, AccountCategory::Liability, AccountCategory::Equity], true)) {
  26. $account->ending_balance = $account->starting_balance + $account->net_movement;
  27. }
  28. $account->save();
  29. }
  30. /**
  31. * Handle the JournalEntry "updated" event.
  32. */
  33. public function updated(JournalEntry $journalEntry): void
  34. {
  35. $accountChanged = $journalEntry->wasChanged('account_id');
  36. $amountChanged = $journalEntry->wasChanged('amount');
  37. $typeChanged = $journalEntry->wasChanged('type');
  38. $originalAccountId = $journalEntry->getOriginal('account_id');
  39. $originalAmount = $journalEntry->getOriginal('amount');
  40. $originalType = $journalEntry->getOriginal('type');
  41. if ($accountChanged || $amountChanged || $typeChanged) {
  42. // Revert the effects of the original journal entry
  43. $originalAccount = Account::find($originalAccountId);
  44. if ($originalAccount) {
  45. $this->adjustBalance($originalAccount, $originalType, -$originalAmount);
  46. }
  47. }
  48. $newAccount = ($accountChanged) ? Account::find($journalEntry->account_id) : $journalEntry->account;
  49. if ($newAccount) {
  50. $this->adjustBalance($newAccount, $journalEntry->type, $journalEntry->amount);
  51. }
  52. }
  53. private function adjustBalance(Account $account, $type, $amount): void
  54. {
  55. if ($type === 'debit') {
  56. $account->debit_balance += $amount;
  57. } elseif ($type === 'credit') {
  58. $account->credit_balance += $amount;
  59. }
  60. $this->updateEndingBalance($account);
  61. }
  62. /**
  63. * Handle the JournalEntry "deleted" event.
  64. */
  65. public function deleted(JournalEntry $journalEntry): void
  66. {
  67. $account = $journalEntry->account;
  68. if ($account) {
  69. $this->adjustBalance($account, $journalEntry->type, -$journalEntry->amount);
  70. }
  71. }
  72. /**
  73. * Handle the JournalEntry "restored" event.
  74. */
  75. public function restored(JournalEntry $journalEntry): void
  76. {
  77. //
  78. }
  79. /**
  80. * Handle the JournalEntry "force deleted" event.
  81. */
  82. public function forceDeleted(JournalEntry $journalEntry): void
  83. {
  84. //
  85. }
  86. }