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.

TransactionFactory.php 4.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. <?php
  2. namespace Database\Factories\Accounting;
  3. use App\Enums\Accounting\JournalEntryType;
  4. use App\Enums\Accounting\TransactionType;
  5. use App\Models\Accounting\Account;
  6. use App\Models\Accounting\Transaction;
  7. use App\Models\Banking\BankAccount;
  8. use App\Models\Company;
  9. use Illuminate\Database\Eloquent\Factories\Factory;
  10. /**
  11. * @extends Factory<Transaction>
  12. */
  13. class TransactionFactory extends Factory
  14. {
  15. /**
  16. * The name of the factory's corresponding model.
  17. */
  18. protected $model = Transaction::class;
  19. /**
  20. * Define the model's default state.
  21. *
  22. * @return array<string, mixed>
  23. */
  24. public function definition(): array
  25. {
  26. return [
  27. 'company_id' => 1,
  28. 'bank_account_id' => 1,
  29. 'account_id' => $this->faker->numberBetween(2, 30),
  30. 'type' => $this->faker->randomElement([TransactionType::Deposit, TransactionType::Withdrawal]),
  31. 'description' => $this->faker->sentence,
  32. 'notes' => $this->faker->paragraph,
  33. 'amount' => $this->faker->numberBetween(100, 5000),
  34. 'reviewed' => $this->faker->boolean,
  35. 'posted_at' => $this->faker->dateTimeBetween('-2 years'),
  36. 'created_by' => 1,
  37. 'updated_by' => 1,
  38. ];
  39. }
  40. public function configure(): static
  41. {
  42. return $this->afterCreating(function (Transaction $transaction) {
  43. $chartAccount = $transaction->account;
  44. $bankAccount = $transaction->bankAccount->account;
  45. $debitAccount = $transaction->type->isWithdrawal() ? $chartAccount : $bankAccount;
  46. $creditAccount = $transaction->type->isWithdrawal() ? $bankAccount : $chartAccount;
  47. if ($debitAccount === null || $creditAccount === null) {
  48. return;
  49. }
  50. $debitAccount->journalEntries()->create([
  51. 'company_id' => $transaction->company_id,
  52. 'transaction_id' => $transaction->id,
  53. 'type' => JournalEntryType::Debit,
  54. 'amount' => $transaction->amount,
  55. 'description' => $transaction->description,
  56. 'created_by' => $transaction->created_by,
  57. 'updated_by' => $transaction->updated_by,
  58. ]);
  59. $creditAccount->journalEntries()->create([
  60. 'company_id' => $transaction->company_id,
  61. 'transaction_id' => $transaction->id,
  62. 'type' => JournalEntryType::Credit,
  63. 'amount' => $transaction->amount,
  64. 'description' => $transaction->description,
  65. 'created_by' => $transaction->created_by,
  66. 'updated_by' => $transaction->updated_by,
  67. ]);
  68. });
  69. }
  70. public function forCompanyAndBankAccount(Company $company, BankAccount $bankAccount): static
  71. {
  72. return $this->state(function (array $attributes) use ($bankAccount, $company) {
  73. $type = $this->faker->randomElement([TransactionType::Deposit, TransactionType::Withdrawal]);
  74. $associatedAccountTypes = match ($type) {
  75. TransactionType::Deposit => ['asset', 'liability', 'equity', 'revenue'],
  76. TransactionType::Withdrawal => ['asset', 'liability', 'equity', 'expense'],
  77. };
  78. $accountIdForBankAccount = $bankAccount->account->id;
  79. $account = Account::where('category', $this->faker->randomElement($associatedAccountTypes))
  80. ->where('company_id', $company->id)
  81. ->where('id', '<>', $accountIdForBankAccount)
  82. ->inRandomOrder()
  83. ->first();
  84. // If no matching account is found, use a fallback
  85. if (! $account) {
  86. $account = Account::where('company_id', $company->id)
  87. ->where('id', '<>', $accountIdForBankAccount)
  88. ->inRandomOrder()
  89. ->firstOrFail(); // Ensure there is at least some account
  90. }
  91. return [
  92. 'company_id' => $company->id,
  93. 'bank_account_id' => $bankAccount->id,
  94. 'account_id' => $account->id,
  95. 'type' => $type,
  96. ];
  97. });
  98. }
  99. }