您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

TransactionObserver.php 3.4KB

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