*/ class CashierLedgerEntryFactory extends Factory { protected $model = CashierLedgerEntry::class; /** * Define the model's default state. * * @return array */ public function definition(): array { $entryTypes = ['receipt', 'payment']; $paymentMethods = ['cash', 'bank_transfer', 'check']; $entryType = $this->faker->randomElement($entryTypes); $amount = $this->faker->randomFloat(2, 100, 50000); $balanceBefore = $this->faker->randomFloat(2, 0, 100000); // Calculate balance after based on entry type $balanceAfter = $entryType === 'receipt' ? $balanceBefore + $amount : $balanceBefore - $amount; return [ 'entry_type' => $entryType, 'entry_date' => $this->faker->dateTimeBetween('-30 days', 'now'), 'amount' => $amount, 'payment_method' => $this->faker->randomElement($paymentMethods), 'bank_account' => $this->faker->company() . ' Bank - ' . $this->faker->numerify('##########'), 'balance_before' => $balanceBefore, 'balance_after' => $balanceAfter, 'recorded_by_cashier_id' => User::factory(), 'recorded_at' => now(), ]; } /** * Indicate that the entry is a receipt (incoming money). */ public function receipt(): static { return $this->state(function (array $attributes) { $balanceBefore = $attributes['balance_before'] ?? 0; $amount = $attributes['amount']; return [ 'entry_type' => 'receipt', 'balance_after' => $balanceBefore + $amount, ]; }); } /** * Indicate that the entry is a payment (outgoing money). */ public function payment(): static { return $this->state(function (array $attributes) { $balanceBefore = $attributes['balance_before'] ?? 0; $amount = $attributes['amount']; return [ 'entry_type' => 'payment', 'balance_after' => $balanceBefore - $amount, ]; }); } /** * Indicate that the entry is linked to a finance document. */ public function withFinanceDocument(): static { return $this->state(fn (array $attributes) => [ 'finance_document_id' => FinanceDocument::factory(), ]); } /** * Indicate that the payment method is cash. */ public function cash(): static { return $this->state(fn (array $attributes) => [ 'payment_method' => 'cash', 'bank_account' => null, ]); } /** * Indicate that the payment method is bank transfer. */ public function bankTransfer(): static { return $this->state(fn (array $attributes) => [ 'payment_method' => 'bank_transfer', 'bank_account' => $this->faker->company() . ' Bank - ' . $this->faker->numerify('##########'), ]); } /** * Indicate that the payment method is check. */ public function check(): static { return $this->state(fn (array $attributes) => [ 'payment_method' => 'check', 'transaction_reference' => 'CHK' . $this->faker->numerify('######'), ]); } /** * Create a sequence of entries with running balance for a specific account. */ public function sequence(string $bankAccount, float $initialBalance = 0): static { static $currentBalance; if ($currentBalance === null) { $currentBalance = $initialBalance; } return $this->state(function (array $attributes) use ($bankAccount, &$currentBalance) { $amount = $attributes['amount']; $entryType = $attributes['entry_type']; $balanceBefore = $currentBalance; $balanceAfter = $entryType === 'receipt' ? $balanceBefore + $amount : $balanceBefore - $amount; $currentBalance = $balanceAfter; return [ 'bank_account' => $bankAccount, 'balance_before' => $balanceBefore, 'balance_after' => $balanceAfter, ]; }); } }