DatabasePlanManager::convertPrices()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 21
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 12
c 1
b 0
f 0
nc 3
nop 1
dl 0
loc 21
rs 9.8666
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * Copyright (C) 2020-2025 Iain Cambridge
7
 *
8
 * This program is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as published by
10
 * the Free Software Foundation, either version 2.1 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU Lesser General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU General Public License
19
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20
 */
21
22
namespace Parthenon\Billing\Plan;
23
24
use Doctrine\Common\Collections\Collection;
25
use Parthenon\Billing\Entity\Price;
26
use Parthenon\Billing\Entity\SubscriptionFeature;
27
use Parthenon\Billing\Entity\SubscriptionPlan;
28
use Parthenon\Billing\Entity\SubscriptionPlanLimit;
29
use Parthenon\Billing\Exception\NoPlanFoundException;
30
use Parthenon\Billing\Repository\SubscriptionPlanRepositoryInterface;
31
32
class DatabasePlanManager implements PlanManagerInterface
33
{
34
    private ?array $plans = null;
35
36
    public function __construct(
37
        private SubscriptionPlanRepositoryInterface $subscriptionPlanRepository,
38
    ) {
39
    }
40
41
    /**
42
     * @return array|Plan[]
43
     */
44
    public function getPlans(): array
45
    {
46
        if (!isset($this->plans)) {
47
            $planEntities = $this->subscriptionPlanRepository->getAll();
48
49
            $output = [];
50
            foreach ($planEntities as $planEntity) {
51
                $output[] = $this->convertPlan($planEntity);
52
            }
53
            $this->plans = $output;
54
        }
55
56
        return $this->plans;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->plans could return the type null which is incompatible with the type-hinted return array. Consider adding an additional type-check to rule them out.
Loading history...
57
    }
58
59
    public function getPlanForUser(LimitedUserInterface $limitedUser): Plan
60
    {
61
        return $this->getPlanByName($limitedUser->getPlanName());
0 ignored issues
show
Bug introduced by
It seems like $limitedUser->getPlanName() can also be of type null; however, parameter $planName of Parthenon\Billing\Plan\D...anager::getPlanByName() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

61
        return $this->getPlanByName(/** @scrutinizer ignore-type */ $limitedUser->getPlanName());
Loading history...
62
    }
63
64
    public function getPlanByName(string $planName): Plan
65
    {
66
        $plans = $this->getPlans();
67
68
        foreach ($plans as $plan) {
69
            if ($plan->getName() === $planName) {
70
                return $plan;
71
            }
72
        }
73
        throw new NoPlanFoundException();
74
    }
75
76
    protected function convertPlan(SubscriptionPlan $subscriptionPlan): Plan
77
    {
78
        $plan = new Plan(
79
            $subscriptionPlan->getName(),
80
            $this->convertLimits($subscriptionPlan->getLimits()),
81
            $this->convertFeatures($subscriptionPlan->getFeatures()),
82
            $this->convertPrices($subscriptionPlan->getPrices()),
83
            $subscriptionPlan->isFree(),
84
            $subscriptionPlan->isPerSeat(),
85
            $subscriptionPlan->getUserCount(),
86
            $subscriptionPlan->isPublic(),
87
            $subscriptionPlan->getHasTrial(),
88
            $subscriptionPlan->getTrialLengthDays(),
89
            $subscriptionPlan->getId()
90
        );
91
92
        return $plan;
93
    }
94
95
    /**
96
     * @param SubscriptionPlanLimit[] $limits
97
     */
98
    protected function convertLimits(array|Collection $limits): array
99
    {
100
        $output = [];
101
102
        foreach ($limits as $limit) {
103
            $output[$limit->getSubscriptionFeature()->getCode()] = [
104
                'name' => $limit->getSubscriptionFeature()->getName(),
105
                'code' => $limit->getSubscriptionFeature()->getCode(),
106
                'limit' => $limit->getLimit(),
107
                'description' => $limit->getSubscriptionFeature()->getDescription(),
108
            ];
109
        }
110
111
        return $output;
112
    }
113
114
    /**
115
     * @param SubscriptionFeature[]|Collection $features
116
     */
117
    protected function convertFeatures(array|Collection $features): array
118
    {
119
        $output = [];
120
121
        foreach ($features as $feature) {
122
            $output[$feature->getCode()] = [
123
                'code' => $feature->getCode(),
124
                'name' => $feature->getName(),
125
                'description' => $feature->getDescription(),
126
            ];
127
        }
128
129
        return $output;
130
    }
131
132
    /**
133
     * @param Price[]|Collection $prices
134
     */
135
    protected function convertPrices(array|Collection $prices): array
136
    {
137
        $output = [];
138
139
        foreach ($prices as $price) {
140
            $schedule = $price->getSchedule();
141
142
            if (!isset($output[$schedule])) {
143
                $output[$schedule] = [];
144
            }
145
146
            $output[$schedule][$price->getCurrency()] = [
147
                'amount' => (string) $price->getAsMoney()->getAmount(),
148
                'currency' => $price->getCurrency(),
149
                'price_id' => $price->getExternalReference(),
150
                'public' => $price->isPublic(),
151
                'entity_id' => $price->getId(),
152
            ];
153
        }
154
155
        return $output;
156
    }
157
}
158