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 3.9KB

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