buckets/database/factories/BucketFactory.php

184 lines
5.4 KiB
PHP

<?php
namespace Database\Factories;
use App\Enums\BucketAllocationTypeEnum;
use App\Enums\BucketTypeEnum;
use App\Models\Bucket;
use App\Models\Scenario;
use Illuminate\Database\Eloquent\Factories\Factory;
/**
* @extends Factory<Bucket>
*/
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,
};
}
}