*/ class BucketFactory extends Factory { public function definition(): array { // Unlimited excluded — use ->overflow() state modifier $allocationType = $this->faker->randomElement([ BucketAllocationTypeEnum::FIXED_LIMIT, BucketAllocationTypeEnum::PERCENTAGE, ]); return [ 'scenario_id' => Scenario::factory(), // Overflow excluded — use ->overflow() state modifier 'type' => $this->faker->randomElement([ BucketTypeEnum::NEED, BucketTypeEnum::WANT, ]), 'name' => $this->faker->randomElement([ 'Monthly Expenses', 'Emergency Fund', 'Investments', 'Vacation Fund', 'Car Maintenance', 'Home Repairs', 'Health & Medical', 'Education', 'Entertainment', 'Groceries', 'Clothing', 'Gifts', ]), 'priority' => $this->faker->numberBetween(1, 10), 'sort_order' => $this->faker->numberBetween(0, 10), 'allocation_type' => $allocationType, 'allocation_value' => $this->getAllocationValueForType($allocationType), 'buffer_multiplier' => 0, 'starting_amount' => $this->faker->numberBetween(0, 100000), // $0 to $1000 in cents ]; } /** * Create a fixed limit bucket. * * @param int|null $amountInCents Capacity in cents (e.g., 50000 = $500) */ public function fixedLimit(?int $amountInCents = null): Factory { $amountInCents = $amountInCents ?? $this->faker->numberBetween(50000, 500000); return $this->state([ 'allocation_type' => BucketAllocationTypeEnum::FIXED_LIMIT, 'allocation_value' => $amountInCents, ]); } /** * Create a percentage bucket. * * @param int|null $basisPoints Percentage in basis points (e.g., 2500 = 25%) */ public function percentage(?int $basisPoints = null): Factory { $basisPoints = $basisPoints ?? $this->faker->numberBetween(1000, 5000); return $this->state([ 'allocation_type' => BucketAllocationTypeEnum::PERCENTAGE, 'allocation_value' => $basisPoints, ]); } /** * Create an unlimited bucket. */ public function unlimited(): Factory { return $this->state([ 'allocation_type' => BucketAllocationTypeEnum::UNLIMITED, 'allocation_value' => null, ]); } /** * Create a need bucket. */ public function need(): Factory { return $this->state([ 'type' => BucketTypeEnum::NEED, ]); } /** * Create a want bucket. */ public function want(): Factory { return $this->state([ 'type' => BucketTypeEnum::WANT, ]); } /** * Create an overflow bucket. */ public function overflow(): Factory { return $this->state([ 'type' => BucketTypeEnum::OVERFLOW, 'allocation_type' => BucketAllocationTypeEnum::UNLIMITED, 'allocation_value' => null, ]); } /** * Create a bucket with a buffer multiplier. */ public function withBuffer(float $multiplier): Factory { return $this->state([ 'buffer_multiplier' => $multiplier, ]); } /** * Create default buckets set (Monthly Expenses, Emergency Fund, Overflow). */ public function defaultSet(): array { return [ $this->state([ 'name' => 'Monthly Expenses', 'type' => BucketTypeEnum::NEED, 'priority' => 1, 'sort_order' => 1, 'allocation_type' => BucketAllocationTypeEnum::FIXED_LIMIT, 'allocation_value' => 0, 'starting_amount' => 0, ]), $this->state([ 'name' => 'Emergency Fund', 'type' => BucketTypeEnum::NEED, 'priority' => 2, 'sort_order' => 2, 'allocation_type' => BucketAllocationTypeEnum::FIXED_LIMIT, 'allocation_value' => 0, 'starting_amount' => 0, ]), $this->state([ 'name' => 'Overflow', 'type' => BucketTypeEnum::OVERFLOW, 'priority' => 3, 'sort_order' => 3, 'allocation_type' => BucketAllocationTypeEnum::UNLIMITED, 'allocation_value' => null, 'starting_amount' => 0, ]), ]; } /** * Get allocation value based on type. */ private function getAllocationValueForType(BucketAllocationTypeEnum $type): ?int { return match ($type) { BucketAllocationTypeEnum::FIXED_LIMIT => $this->faker->numberBetween(10000, 1000000), BucketAllocationTypeEnum::PERCENTAGE => $this->faker->numberBetween(500, 5000), BucketAllocationTypeEnum::UNLIMITED => null, }; } }