Passed
Push — main ( 1e6836...3fba09 )
by Iain
05:11
created

SubscriptionManager::startSubscription()   A

Complexity

Conditions 4
Paths 7

Size

Total Lines 35
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
eloc 24
nc 7
nop 2
dl 0
loc 35
rs 9.536
c 1
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * Copyright Iain Cambridge 2020-2023.
7
 *
8
 * Use of this software is governed by the Business Source License included in the LICENSE file and at https://getparthenon.com/docs/next/license.
9
 *
10
 * Change Date: TBD ( 3 years after 2.2.0 release )
11
 *
12
 * On the date above, in accordance with the Business Source License, use of this software will be governed by the open source license specified in the LICENSE file.
13
 */
14
15
namespace Parthenon\Billing\Subscription;
16
17
use Obol\Provider\ProviderInterface;
18
use Parthenon\Billing\Dto\StartSubscriptionDto;
19
use Parthenon\Billing\Entity\CustomerInterface;
20
use Parthenon\Billing\Entity\Subscription;
21
use Parthenon\Billing\Obol\BillingDetailsFactoryInterface;
22
use Parthenon\Billing\Obol\PaymentFactoryInterface;
23
use Parthenon\Billing\Obol\SubscriptionFactoryInterface;
24
use Parthenon\Billing\Plan\PlanManagerInterface;
25
use Parthenon\Billing\Repository\PaymentDetailsRepositoryInterface;
26
use Parthenon\Billing\Repository\PaymentRepositoryInterface;
27
use Parthenon\Billing\Response\StartSubscriptionResponse;
28
use Parthenon\Common\Exception\NoEntityFoundException;
29
use Symfony\Component\HttpFoundation\JsonResponse;
30
31
class SubscriptionManager implements SubscriptionManagerInterface
32
{
33
    public function __construct(
34
        private PaymentDetailsRepositoryInterface $paymentDetailsRepository,
35
        private ProviderInterface $provider,
36
        private BillingDetailsFactoryInterface $billingDetailsFactory,
37
        private PaymentFactoryInterface $paymentFactory,
38
        private SubscriptionFactoryInterface $subscriptionFactory,
39
        private PaymentRepositoryInterface $paymentRepository,
40
        private PlanManagerInterface $planManager,
41
    ) {
42
    }
43
44
    public function startSubscription(CustomerInterface $customer, StartSubscriptionDto $startSubscriptionDto): Subscription
45
    {
46
        try {
47
            if (!$startSubscriptionDto->hasPaymentDetailsId()) {
48
                $paymentDetails = $this->paymentDetailsRepository->getDefaultPaymentDetailsForCustomer($customer);
49
            } else {
50
                $paymentDetails = $this->paymentDetailsRepository->findById($startSubscriptionDto->getPaymentDetailsId());
51
            }
52
        } catch (NoEntityFoundException $e) {
53
            return new JsonResponse(StartSubscriptionResponse::createNoBillingDetails());
0 ignored issues
show
Bug Best Practice introduced by
The expression return new Symfony\Compo...eateNoBillingDetails()) returns the type Symfony\Component\HttpFoundation\JsonResponse which is incompatible with the type-hinted return Parthenon\Billing\Entity\Subscription.
Loading history...
54
        }
55
56
        $billingDetails = $this->billingDetailsFactory->createFromCustomerAndPaymentDetails($customer, $paymentDetails);
57
58
        $plan = $this->planManager->getPlanByName($startSubscriptionDto->getPlanName());
59
        $planPrice = $plan->getPriceForPaymentSchedule($startSubscriptionDto->getSchedule(), $startSubscriptionDto->getCurrency());
60
61
        $obolSubscription = $this->subscriptionFactory->createSubscription($billingDetails, $planPrice, $startSubscriptionDto->getSeatNumbers());
62
63
        $subscriptionCreationResponse = $this->provider->payments()->startSubscription($obolSubscription);
64
        if ($subscriptionCreationResponse->hasCustomerCreation()) {
65
            $customer->setPaymentProviderDetailsUrl($subscriptionCreationResponse->getCustomerCreation()->getDetailsUrl());
66
            $customer->setExternalCustomerReference($subscriptionCreationResponse->getCustomerCreation()->getReference());
67
        }
68
        $payment = $this->paymentFactory->fromSubscriptionCreation($subscriptionCreationResponse);
69
        $this->paymentRepository->save($payment);
70
71
        $subscription = $customer->getSubscription();
72
        $subscription->setPlanName($plan->getName());
73
        $subscription->setPaymentSchedule($startSubscriptionDto->getSchedule());
74
        $subscription->setActive(true);
75
        $subscription->setMoneyAmount($planPrice->getPriceAsMoney());
76
        $subscription->setStatus(\Parthenon\Billing\Entity\Subscription::STATUS_ACTIVE);
77
78
        return $subscription;
79
    }
80
}
81