*/ class FinanceDocumentFactory extends Factory { protected $model = FinanceDocument::class; /** * Define the model's default state. * * @return array */ public function definition(): array { $requestTypes = ['expense_reimbursement', 'advance_payment', 'purchase_request', 'petty_cash']; $statuses = ['pending', 'approved_cashier', 'approved_accountant', 'approved_chair', 'rejected']; return [ 'title' => $this->faker->sentence(6), 'description' => $this->faker->paragraph(3), 'amount' => $this->faker->randomFloat(2, 100, 100000), 'request_type' => $this->faker->randomElement($requestTypes), 'status' => $this->faker->randomElement($statuses), 'submitted_by_user_id' => User::factory(), 'submitted_at' => now(), 'amount_tier' => null, 'requires_board_meeting' => false, ]; } public function configure() { return $this->afterMaking(function (FinanceDocument $document) { $document->amount_tier = $document->determineAmountTier(); $document->requires_board_meeting = $document->needsBoardMeetingApproval(); })->afterCreating(function (FinanceDocument $document) { $document->amount_tier = $document->determineAmountTier(); $document->requires_board_meeting = $document->needsBoardMeetingApproval(); $document->save(); }); } /** * Indicate that the document is pending approval. */ public function pending(): static { return $this->state(fn (array $attributes) => [ 'status' => 'pending', ]); } /** * Indicate that the document is approved by cashier. */ public function approvedByCashier(): static { return $this->state(fn (array $attributes) => [ 'status' => FinanceDocument::STATUS_APPROVED_CASHIER, 'approved_by_cashier_id' => User::factory(), 'cashier_approved_at' => now(), ]); } /** * Indicate that the document is approved by accountant. */ public function approvedByAccountant(): static { return $this->state(fn (array $attributes) => [ 'status' => FinanceDocument::STATUS_APPROVED_ACCOUNTANT, 'approved_by_cashier_id' => User::factory(), 'cashier_approved_at' => now(), 'approved_by_accountant_id' => User::factory(), 'accountant_approved_at' => now(), ]); } /** * Indicate that the document is approved by chair. */ public function approvedByChair(): static { return $this->state(fn (array $attributes) => [ 'status' => FinanceDocument::STATUS_APPROVED_CHAIR, 'approved_by_cashier_id' => User::factory(), 'cashier_approved_at' => now(), 'approved_by_accountant_id' => User::factory(), 'accountant_approved_at' => now(), 'approved_by_chair_id' => User::factory(), 'chair_approved_at' => now(), ]); } /** * Indicate that the document is rejected. */ public function rejected(): static { return $this->state(fn (array $attributes) => [ 'status' => FinanceDocument::STATUS_REJECTED, 'rejection_reason' => $this->faker->sentence(10), 'rejected_at' => now(), ]); } /** * Indicate that the document is a small amount (< 5000). */ public function smallAmount(): static { return $this->state(fn (array $attributes) => [ 'amount' => $this->faker->randomFloat(2, 100, 4999), 'amount_tier' => 'small', 'requires_board_meeting' => false, ]); } /** * Indicate that the document is a medium amount (5000-50000). */ public function mediumAmount(): static { return $this->state(fn (array $attributes) => [ 'amount' => $this->faker->randomFloat(2, 5000, 50000), 'amount_tier' => null, 'requires_board_meeting' => false, ]); } /** * Indicate that the document is a large amount (> 50000). */ public function largeAmount(): static { return $this->state(fn (array $attributes) => [ 'amount' => $this->faker->randomFloat(2, 50001, 200000), 'amount_tier' => 'large', 'requires_board_meeting' => true, ]); } /** * Indicate that the document is an expense reimbursement. */ public function expenseReimbursement(): static { return $this->state(fn (array $attributes) => [ 'request_type' => 'expense_reimbursement', ]); } /** * Indicate that the document is an advance payment. */ public function advancePayment(): static { return $this->state(fn (array $attributes) => [ 'request_type' => 'advance_payment', ]); } /** * Indicate that the document is a purchase request. */ public function purchaseRequest(): static { return $this->state(fn (array $attributes) => [ 'request_type' => 'purchase_request', ]); } /** * Indicate that the document is petty cash. */ public function pettyCash(): static { return $this->state(fn (array $attributes) => [ 'request_type' => 'petty_cash', ]); } /** * Indicate that payment order has been created. */ public function withPaymentOrder(): static { return $this->state(fn (array $attributes) => [ 'payment_order_created_at' => now(), 'payment_order_created_by_id' => User::factory(), ]); } /** * Indicate that payment has been executed. */ public function paymentExecuted(): static { return $this->state(fn (array $attributes) => [ 'payment_order_created_at' => now(), 'payment_verified_at' => now(), 'payment_executed_at' => now(), ]); } /** * Determine amount tier based on amount. */ protected function determineAmountTier(float $amount): string { if ($amount < 5000) { return 'small'; } elseif ($amount <= 50000) { return 'medium'; } else { return 'large'; } } }