Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 25
0.00% covered (danger)
0.00%
0 / 1
CRAP
0.00% covered (danger)
0.00%
0 / 1
AssignOrganizationPlanAction
0.00% covered (danger)
0.00%
0 / 25
0.00% covered (danger)
0.00%
0 / 1
20
0.00% covered (danger)
0.00%
0 / 1
 execute
0.00% covered (danger)
0.00%
0 / 25
0.00% covered (danger)
0.00%
0 / 1
20
1<?php
2
3declare(strict_types=1);
4
5namespace ImovelZapAi\Organizations\Application\Actions;
6
7use ImovelZapAi\Organizations\Domain\Enums\SubscriptionStatus;
8use ImovelZapAi\Organizations\Infrastructure\Persistence\Eloquent\OrganizationSubscriptionModel;
9use ImovelZapAi\Organizations\Infrastructure\Persistence\Eloquent\SubscriptionPlanModel;
10use ImovelZapAi\Tenancy\Domain\Enums\OrganizationType;
11use ImovelZapAi\Tenancy\Infrastructure\Persistence\Eloquent\TenantModel;
12use RuntimeException;
13
14final class AssignOrganizationPlanAction
15{
16    public function execute(string $tenantId, string $planCode, SubscriptionStatus $status = SubscriptionStatus::Active): OrganizationSubscriptionModel
17    {
18        $plan = SubscriptionPlanModel::query()
19            ->where('code', $planCode)
20            ->where('is_active', true)
21            ->first();
22
23        if ($plan === null) {
24            throw new RuntimeException("Plano [{$planCode}] não encontrado.");
25        }
26
27        $tenant = TenantModel::query()->findOrFail($tenantId);
28        $tenant->forceFill([
29            'type' => (int) $plan->max_users === 1
30                ? OrganizationType::Solo
31                : OrganizationType::Agency,
32        ])->save();
33
34        /** @var OrganizationSubscriptionModel $subscription */
35        $subscription = OrganizationSubscriptionModel::query()->updateOrCreate(
36            ['tenant_id' => $tenantId],
37            [
38                'subscription_plan_id' => $plan->id,
39                'status' => $status,
40                'billing_cycle' => 'monthly',
41                'trial_ends_at' => $status === SubscriptionStatus::Trialing
42                    ? now()->addDays((int) config('organizations.trial_days', 14))
43                    : null,
44                'current_period_ends_at' => now()->addMonth(),
45            ],
46        );
47
48        return $subscription->fresh(['plan']) ?? $subscription;
49    }
50}