Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

TransactionFactory.php 6.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. <?php
  2. namespace Database\Factories\Accounting;
  3. use App\Enums\Accounting\AccountType;
  4. use App\Enums\Accounting\TransactionType;
  5. use App\Models\Accounting\Account;
  6. use App\Models\Accounting\AccountSubtype;
  7. use App\Models\Accounting\Transaction;
  8. use App\Models\Banking\BankAccount;
  9. use App\Models\Company;
  10. use App\Models\Setting\CompanyDefault;
  11. use Illuminate\Database\Eloquent\Factories\Factory;
  12. /**
  13. * @extends Factory<Transaction>
  14. */
  15. class TransactionFactory extends Factory
  16. {
  17. /**
  18. * The name of the factory's corresponding model.
  19. */
  20. protected $model = Transaction::class;
  21. /**
  22. * Define the model's default state.
  23. *
  24. * @return array<string, mixed>
  25. */
  26. public function definition(): array
  27. {
  28. return [
  29. 'company_id' => 1,
  30. 'bank_account_id' => 1,
  31. 'account_id' => $this->faker->numberBetween(2, 30),
  32. 'type' => $this->faker->randomElement([TransactionType::Deposit, TransactionType::Withdrawal]),
  33. 'description' => $this->faker->sentence,
  34. 'notes' => $this->faker->paragraph,
  35. 'amount' => $this->faker->numberBetween(100, 5000),
  36. 'reviewed' => $this->faker->boolean,
  37. 'posted_at' => $this->faker->dateTimeBetween('-2 years'),
  38. 'created_by' => 1,
  39. 'updated_by' => 1,
  40. ];
  41. }
  42. public function forCompanyAndBankAccount(Company $company, BankAccount $bankAccount): static
  43. {
  44. return $this->state(function (array $attributes) use ($bankAccount, $company) {
  45. $type = $this->faker->randomElement([TransactionType::Deposit, TransactionType::Withdrawal]);
  46. $associatedAccountTypes = match ($type) {
  47. TransactionType::Deposit => [
  48. AccountType::CurrentLiability,
  49. AccountType::NonCurrentLiability,
  50. AccountType::Equity,
  51. AccountType::OperatingRevenue,
  52. AccountType::NonOperatingRevenue,
  53. AccountType::ContraExpense,
  54. ],
  55. TransactionType::Withdrawal => [
  56. AccountType::OperatingExpense,
  57. AccountType::NonOperatingExpense,
  58. AccountType::CurrentLiability,
  59. AccountType::NonCurrentLiability,
  60. AccountType::Equity,
  61. AccountType::ContraRevenue,
  62. ],
  63. };
  64. $accountIdForBankAccount = $bankAccount->account->id;
  65. $excludedSubtypes = AccountSubtype::where('company_id', $company->id)
  66. ->whereIn('name', ['Sales Taxes', 'Purchase Taxes', 'Sales Discounts', 'Purchase Discounts'])
  67. ->pluck('id');
  68. $account = Account::whereIn('type', $associatedAccountTypes)
  69. ->where('company_id', $company->id)
  70. ->whereNotIn('subtype_id', $excludedSubtypes)
  71. ->whereKeyNot($accountIdForBankAccount)
  72. ->inRandomOrder()
  73. ->first();
  74. if (! $account) {
  75. $account = Account::where('company_id', $company->id)
  76. ->whereKeyNot($accountIdForBankAccount)
  77. ->inRandomOrder()
  78. ->firstOrFail();
  79. }
  80. return [
  81. 'company_id' => $company->id,
  82. 'bank_account_id' => $bankAccount->id,
  83. 'account_id' => $account->id,
  84. 'type' => $type,
  85. ];
  86. });
  87. }
  88. public function forDefaultBankAccount(): static
  89. {
  90. return $this->state(function (array $attributes) {
  91. $defaultBankAccount = CompanyDefault::first()->bankAccount;
  92. return [
  93. 'bank_account_id' => $defaultBankAccount->id,
  94. ];
  95. });
  96. }
  97. public function forBankAccount(?BankAccount $bankAccount = null): static
  98. {
  99. return $this->state(function (array $attributes) use ($bankAccount) {
  100. $bankAccount = $bankAccount ?? BankAccount::factory()->create();
  101. return [
  102. 'bank_account_id' => $bankAccount->id,
  103. ];
  104. });
  105. }
  106. public function forDestinationBankAccount(?Account $account = null): static
  107. {
  108. return $this->state(function (array $attributes) use ($account) {
  109. $destinationBankAccount = $account ?? Account::factory()->withBankAccount('Destination Bank Account')->create();
  110. return [
  111. 'account_id' => $destinationBankAccount->id,
  112. ];
  113. });
  114. }
  115. public function forUncategorizedRevenue(): static
  116. {
  117. return $this->state(function (array $attributes) {
  118. $account = Account::where('type', AccountType::UncategorizedRevenue)->firstOrFail();
  119. return [
  120. 'account_id' => $account->id,
  121. ];
  122. });
  123. }
  124. public function forUncategorizedExpense(): static
  125. {
  126. return $this->state(function (array $attributes) {
  127. $account = Account::where('type', AccountType::UncategorizedExpense)->firstOrFail();
  128. return [
  129. 'account_id' => $account->id,
  130. ];
  131. });
  132. }
  133. public function forAccount(Account $account): static
  134. {
  135. return $this->state([
  136. 'account_id' => $account->id,
  137. ]);
  138. }
  139. public function forType(TransactionType $type, int $amount): static
  140. {
  141. return $this->state(compact('type', 'amount'));
  142. }
  143. public function asDeposit(int $amount): static
  144. {
  145. return $this->state(function () use ($amount) {
  146. return [
  147. 'type' => TransactionType::Deposit,
  148. 'amount' => $amount,
  149. ];
  150. });
  151. }
  152. public function asWithdrawal(int $amount): static
  153. {
  154. return $this->state(function () use ($amount) {
  155. return [
  156. 'type' => TransactionType::Withdrawal,
  157. 'amount' => $amount,
  158. ];
  159. });
  160. }
  161. public function asJournal(int $amount): static
  162. {
  163. return $this->state(function () use ($amount) {
  164. return [
  165. 'type' => TransactionType::Journal,
  166. 'amount' => $amount,
  167. ];
  168. });
  169. }
  170. public function asTransfer(int $amount): static
  171. {
  172. return $this->state(function () use ($amount) {
  173. return [
  174. 'type' => TransactionType::Transfer,
  175. 'amount' => $amount,
  176. ];
  177. });
  178. }
  179. }