OrderService::processAndCalculateOrderItems()   A
last analyzed

Complexity

Conditions 3
Paths 4

Size

Total Lines 15
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 8
nc 4
nop 2
dl 0
loc 15
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * @author Rafał Muszyński <[email protected]>
5
 * @copyright 2015 Sourcefabric z.ú.
6
 * @license http://www.gnu.org/licenses/gpl-3.0.txt
7
 */
8
namespace Newscoop\PaywallBundle\Services;
9
10
use Newscoop\PaywallBundle\Currency\Context\CurrencyContextInterface;
11
use Sylius\Component\Currency\Converter\CurrencyConverterInterface;
12
use Newscoop\PaywallBundle\Entity\Order;
13
use Newscoop\PaywallBundle\Entity\OrderInterface;
14
use Newscoop\PaywallBundle\Entity\Subscription;
15
use Newscoop\PaywallBundle\Subscription\SubscriptionData;
16
use Newscoop\PaywallBundle\Discount\DiscountProcessorInterface;
17
use Newscoop\PaywallBundle\Entity\Duration;
18
use Newscoop\PaywallBundle\Entity\UserSubscription;
19
20
/**
21
 * Order service.
22
 */
23
class OrderService
24
{
25
    protected $context;
26
    protected $converter;
27
    protected $subscriptionService;
28
    protected $processor;
29
30
    public function __construct(
31
        CurrencyContextInterface $context,
32
        CurrencyConverterInterface $converter,
33
        PaywallService $subscriptionService,
34
        DiscountProcessorInterface $processor
35
    ) {
36
        $this->context = $context;
37
        $this->converter = $converter;
38
        $this->subscriptionService = $subscriptionService;
39
        $this->processor = $processor;
40
    }
41
42
    /**
43
     * Processes and calculates order items.
44
     * Calculates prices including all discounts.
45
     *
46
     * @param array  $items    array of subscription identifiers and its periods
47
     * @param string $surrency currency
0 ignored issues
show
Bug introduced by
There is no parameter named $surrency. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
48
     *
49
     * @return OrderInterface
50
     */
51
    public function processAndCalculateOrderItems(array $items = array(), $currency = null)
52
    {
53
        if (null !== $currency) {
54
            $this->context->setCurrency($currency);
55
        }
56
57
        $order = $this->instantiateOrderItems($items);
58
        foreach ($order->getItems() as $item) {
59
            $this->processor->process($item);
60
        }
61
62
        $order->calculateTotal();
63
64
        return $order;
65
    }
66
67
    /**
68
     * Processes and calculates order.
69
     * Calculates prices, including all discounts.
70
     *
71
     * @param OrderInterface $order
72
     *
73
     * @return OrderInterface
74
     */
75
    public function processAndCalculateOrder(OrderInterface $order)
76
    {
77
        $order = $this->processor->process($order);
78
        $order->calculateTotal();
79
80
        return $order;
81
    }
82
83
    private function instantiateOrderItems(array $items = array())
84
    {
85
        try {
86
            $order = new Order();
87
            $order->setCurrency($this->context->getCurrency());
88
            $order->setUser($this->subscriptionService->getCurrentUser());
89
            foreach ($items as $subscriptionId => $periodId) {
90
                if (!$periodId) {
91
                    continue;
92
                }
93
94
                $orderItem = null;
95
                $subscription = $this->subscriptionService
96
                    ->getSubscriptionRepository()
97
                    ->getReference($subscriptionId);
98
99
                $newlySelectedPeriod = $this->subscriptionService->filterRanges($subscription, $periodId);
100
                if (!$newlySelectedPeriod) {
101
                    return new Order();
102
                }
103
104
                $item = $this->subscriptionService->getOrderItemBy(
105
                    $subscription->getId()
106
                );
107
108
                if ($item) {
109
                    if (!$item->isActive()) {
110
                        continue;
111
                    }
112
113
                    $currentItemPeriod = $item->getDuration();
114
                    // e.g month === month
115
                    if ($currentItemPeriod['attribute'] === $newlySelectedPeriod->getAttribute()) {
116
                        $orderItem = $this->instantiateOrderItem($subscription, $newlySelectedPeriod);
117
                        $orderItem->setProlonged(true);
118
                        $orderItem->setParent($item);
119
                        $orderItem->setCreatedAt($item->getCreatedAt());
120
                        $orderItem->setStartsAt($item->getExpireAt());
121
                    } else {
122
                        continue;
123
                    }
124
                }
125
126
                if (!$orderItem) {
127
                    $orderItem = $this->instantiateOrderItem($subscription, $newlySelectedPeriod);
128
                }
129
130
                $orderItem->setOrder($order);
131
                $order->addItem($orderItem);
132
            }
133
134
            return $order;
135
        } catch (\Exception $e) {
136
            throw $e;
137
        }
138
    }
139
140
    private function instantiateOrderItem(Subscription $subscription, $period)
141
    {
142
        $specification = $subscription->getSpecification()->first();
0 ignored issues
show
Bug introduced by
The method first cannot be called on $subscription->getSpecification() (of type array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
143
        $orderItem = $this->subscriptionService->create();
144
        $subscriptionData = new SubscriptionData(array(
145
            'userId' => $this->subscriptionService->getCurrentUser(),
146
            'subscriptionId' => $subscription,
147
            'publicationId' => $specification->getPublication(),
148
            'toPay' => $this->converter->convert($subscription->getPrice(), $this->context->getCurrency()),
149
            'duration' => $this->createPeriodArray($period),
150
            'discount' => $this->createDiscountArray($period),
151
            'currency' => $this->context->getCurrency(),
152
            'type' => 'T',
153
            'active' => false,
154
        ), $orderItem);
155
156
        return $this->subscriptionService->update($orderItem, $subscriptionData);
157
    }
158
159
    private function createDiscountArray(Duration $period)
160
    {
161
        $discount = array();
162
        if ($period->getDiscount()) {
163
            $discount['id'] = $period->getDiscount()->getId();
164
            $discount['value'] = $period->getDiscount()->getValue();
165
            $discount['type'] = $period->getDiscount()->getType();
166
        }
167
168
        return $discount;
169
    }
170
171
    private function createPeriodArray(Duration $period)
172
    {
173
        $periodArray = array(
174
            'id' => $period->getId(),
175
            'value' => $period->getValue(),
176
            'attribute' => $period->getAttribute(),
177
        );
178
179
        return $periodArray;
180
    }
181
182
    /**
183
     * Activate order item.
184
     *
185
     * @param UserSubscription $item
186
     */
187
    public function activateItem(UserSubscription $item)
188
    {
189
        $this->subscriptionService->activateUserSubscription($item);
190
    }
191
}
192