CluPilotCloud/database/factories/SubscriptionFactory.php

61 lines
2.2 KiB
PHP

<?php
namespace Database\Factories;
use App\Models\Customer;
use App\Models\Subscription;
use App\Services\Billing\WithdrawalRight;
use Illuminate\Database\Eloquent\Factories\Factory;
class SubscriptionFactory extends Factory
{
public function definition(): array
{
$start = now()->startOfMonth();
return array_merge(Subscription::snapshotFrom('team'), [
'customer_id' => Customer::factory(),
'started_at' => $start,
'current_period_start' => $start,
'current_period_end' => $start->copy()->addMonth(),
// Every contract opened for real gets one (OpenSubscription), so a
// factory contract without it would behave differently from the
// thing it stands in for — and every test about the withdrawal
// window would have to remember to set it.
'withdrawal_ends_at' => $start->copy()->addDays(WithdrawalRight::WINDOW_DAYS),
'status' => 'active',
]);
}
/**
* The consumer expressly asked for the service to begin at once, and was
* told they would owe the pro-rata share if they withdrew (FAGG §16).
*
* A state rather than the default, because the absence of this consent is
* what makes a withdrawal refund EVERYTHING — and that is the case a test
* has to be able to reach without fighting the factory.
*/
public function startedImmediately(): static
{
return $this->state(fn (array $attributes) => [
'immediate_start_consent_at' => $attributes['started_at'] ?? now(),
]);
}
public function plan(string $plan, string $term = Subscription::TERM_MONTHLY): static
{
return $this->state(function () use ($plan, $term) {
$start = now()->startOfMonth();
return array_merge(Subscription::snapshotFrom($plan, $term), [
'started_at' => $start,
'current_period_start' => $start,
'current_period_end' => $term === Subscription::TERM_YEARLY
? $start->copy()->addYear()
: $start->copy()->addMonth(),
'withdrawal_ends_at' => $start->copy()->addDays(WithdrawalRight::WINDOW_DAYS),
]);
});
}
}