Passed
Push — master ( 1231d8...187947 )
by
unknown
10:44
created

ConvertOrder   A

Complexity

Total Complexity 19

Size/Duplication

Total Lines 197
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 105
dl 0
loc 197
rs 10
c 2
b 0
f 0
wmc 19

11 Methods

Rating   Name   Duplication   Size   Complexity  
A convert() 0 15 1
A createShippingAddress() 0 12 1
A __construct() 0 12 1
A createBillingAddress() 0 12 1
A getUnitPriceWithTax() 0 3 1
A getUnitDiscountAmount() 0 3 1
B createLines() 0 43 6
A getTaxRatesShipments() 0 3 1
A getTaxRatesUnitItem() 0 3 1
A createShippingFee() 0 29 4
A createAdjustments() 0 18 1
1
<?php
2
3
/*
4
 * This file has been created by developers from BitBag.
5
 * Feel free to contact us once you face any issues or want to start
6
 * You can find more information about us on https://bitbag.io and write us
7
 * an email on [email protected].
8
 */
9
10
declare(strict_types=1);
11
12
namespace BitBag\SyliusMolliePlugin\Helper;
13
14
use BitBag\SyliusMolliePlugin\Calculator\CalculateTaxAmountInterface;
15
use BitBag\SyliusMolliePlugin\Entity\MollieGatewayConfigInterface;
16
use BitBag\SyliusMolliePlugin\Payments\PaymentTerms\Options;
17
use BitBag\SyliusMolliePlugin\Resolver\MealVoucherResolverInterface;
18
use BitBag\SyliusMolliePlugin\Resolver\TaxShipmentResolverInterface;
19
use BitBag\SyliusMolliePlugin\Resolver\TaxUnitItemResolverInterface;
20
use Sylius\Component\Core\Model\OrderInterface;
21
use Sylius\Component\Core\Model\OrderItem;
22
use Sylius\Component\Core\Model\ShipmentInterface;
23
use Sylius\Component\Customer\Model\CustomerInterface;
24
use Sylius\Component\Order\Model\Adjustment;
25
26
final class ConvertOrder implements ConvertOrderInterface
27
{
28
    /** @var OrderInterface */
29
    private $order;
30
31
    /** @var IntToStringConverter */
32
    private $intToStringConverter;
33
34
    /** @var CalculateTaxAmountInterface */
35
    private $calculateTaxAmount;
36
37
    /** @var TaxUnitItemResolverInterface */
38
    private $taxUnitItemResolver;
39
40
    /** @var TaxShipmentResolverInterface */
41
    private $taxShipmentResolver;
42
43
    /** @var MealVoucherResolverInterface */
44
    private $mealVoucherResolver;
45
46
    public function __construct(
47
        IntToStringConverter $intToStringConverter,
48
        CalculateTaxAmountInterface $calculateTaxAmount,
49
        TaxUnitItemResolverInterface $taxUnitItemResolver,
50
        TaxShipmentResolverInterface $taxShipmentResolver,
51
        MealVoucherResolverInterface $mealVoucherResolver
52
    ) {
53
        $this->intToStringConverter = $intToStringConverter;
54
        $this->calculateTaxAmount = $calculateTaxAmount;
55
        $this->taxUnitItemResolver = $taxUnitItemResolver;
56
        $this->taxShipmentResolver = $taxShipmentResolver;
57
        $this->mealVoucherResolver = $mealVoucherResolver;
58
    }
59
60
    public function convert(OrderInterface $order, array $details, int $divisor, MollieGatewayConfigInterface $method): array
61
    {
62
        $this->order = $order;
63
64
        $customer = $order->getCustomer();
65
        $amount = $this->intToStringConverter->convertIntToString($order->getTotal(), $divisor);
66
67
        $details['amount']['value'] = $amount;
68
        $details['orderNumber'] = (string) $order->getId();
69
        $details['shippingAddress'] = $this->createShippingAddress($customer);
0 ignored issues
show
Bug introduced by
It seems like $customer can also be of type null; however, parameter $customer of BitBag\SyliusMolliePlugi...createShippingAddress() does only seem to accept Sylius\Component\Customer\Model\CustomerInterface, 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

69
        $details['shippingAddress'] = $this->createShippingAddress(/** @scrutinizer ignore-type */ $customer);
Loading history...
70
        $details['billingAddress'] = $this->createBillingAddress($customer);
0 ignored issues
show
Bug introduced by
It seems like $customer can also be of type null; however, parameter $customer of BitBag\SyliusMolliePlugi...:createBillingAddress() does only seem to accept Sylius\Component\Customer\Model\CustomerInterface, 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

70
        $details['billingAddress'] = $this->createBillingAddress(/** @scrutinizer ignore-type */ $customer);
Loading history...
71
        $details['lines'] = $this->createLines($divisor, $method);
72
        $details['lines'] = array_merge($details['lines'], $this->createShippingFee($divisor));
73
74
        return $details;
75
    }
76
77
    private function createShippingAddress(CustomerInterface $customer): array
78
    {
79
        $shippingAddress = $this->order->getShippingAddress();
80
81
        return [
82
            'streetAndNumber' => $shippingAddress->getStreet(),
83
            'postalCode' => $shippingAddress->getPostcode(),
84
            'city' => $shippingAddress->getCity(),
85
            'country' => $shippingAddress->getCountryCode(),
86
            'givenName' => $shippingAddress->getFirstName(),
87
            'familyName' => $shippingAddress->getLastName(),
88
            'email' => $customer->getEmail(),
89
        ];
90
    }
91
92
    private function createBillingAddress(CustomerInterface $customer): array
93
    {
94
        $billingAddress = $this->order->getBillingAddress();
95
96
        return [
97
            'streetAndNumber' => $billingAddress->getStreet(),
98
            'postalCode' => $billingAddress->getPostcode(),
99
            'city' => $billingAddress->getCity(),
100
            'country' => $billingAddress->getCountryCode(),
101
            'givenName' => $billingAddress->getFirstName(),
102
            'familyName' => $billingAddress->getLastName(),
103
            'email' => $customer->getEmail(),
104
        ];
105
    }
106
107
    private function createLines(int $divisor, MollieGatewayConfigInterface $method): array
108
    {
109
        $details = [];
110
        $this->order->getChannel()->getDefaultTaxZone();
0 ignored issues
show
Bug introduced by
The method getDefaultTaxZone() does not exist on Sylius\Component\Channel\Model\ChannelInterface. It seems like you code against a sub-type of said class. However, the method does not exist in Sylius\Component\Channel\Model\Channel. Are you sure you never get one of those? ( Ignorable by Annotation )

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

110
        $this->order->getChannel()->/** @scrutinizer ignore-call */ getDefaultTaxZone();
Loading history...
111
112
        foreach ($this->order->getItems() as $item) {
113
            $details[] = [
114
                'category' => $this->mealVoucherResolver->resolve($method, $item),
115
                'type' => 'physical',
116
                'name' => $item->getProductName(),
117
                'quantity' => $item->getQuantity(),
118
                'vatRate' => null === $this->getTaxRatesUnitItem($item) ? '0.00' : (string) ($this->getTaxRatesUnitItem($item) * 100),
119
                'unitPrice' => [
120
                    'currency' => $this->order->getCurrencyCode(),
121
                    'value' => $this->intToStringConverter->convertIntToString($this->getUnitPriceWithTax($item), $divisor),
122
                ],
123
                'totalAmount' => [
124
                    'currency' => $this->order->getCurrencyCode(),
125
                    'value' => $this->intToStringConverter->convertIntToString($item->getTotal(), $divisor),
126
                ],
127
                'vatAmount' => [
128
                    'currency' => $this->order->getCurrencyCode(),
129
                    'value' => null === $this->getTaxRatesUnitItem($item) ?
130
                        '0.00' :
131
                        $this->calculateTaxAmount->calculate($this->getTaxRatesUnitItem($item), $item->getTotal()),
0 ignored issues
show
Bug introduced by
It seems like $this->getTaxRatesUnitItem($item) can also be of type null; however, parameter $taxRateAmount of BitBag\SyliusMolliePlugi...tInterface::calculate() does only seem to accept double, 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

131
                        $this->calculateTaxAmount->calculate(/** @scrutinizer ignore-type */ $this->getTaxRatesUnitItem($item), $item->getTotal()),
Loading history...
132
                ],
133
                'discountAmount' => [
134
                    'currency' => $this->order->getCurrencyCode(),
135
                    'value' => $this->intToStringConverter->convertIntToString($this->getUnitDiscountAmount($item), $divisor),
136
                ],
137
                'metadata' => [
138
                    'item_id' => $item->getId(),
139
                ],
140
            ];
141
        }
142
143
        foreach ($this->order->getAdjustments() as $adjustment) {
144
            if (array_search($adjustment->getType(), Options::getAvailablePaymentSurchargeFeeType())) {
145
                $details[] = $this->createAdjustments($adjustment, $divisor);
146
            }
147
        }
148
149
        return $details;
150
    }
151
152
    private function createAdjustments(Adjustment $adjustment, int $divisor): array
153
    {
154
        return [
155
            'type' => self::PAYMENT_FEE_TYPE,
156
            'name' => self::PAYMENT_FEE,
157
            'quantity' => 1,
158
            'vatRate' => '0.00',
159
            'unitPrice' => [
160
                'currency' => $this->order->getCurrencyCode(),
161
                'value' => $this->intToStringConverter->convertIntToString($adjustment->getAmount(), $divisor),
162
            ],
163
            'totalAmount' => [
164
                'currency' => $this->order->getCurrencyCode(),
165
                'value' => $this->intToStringConverter->convertIntToString($adjustment->getAmount(), $divisor),
166
            ],
167
            'vatAmount' => [
168
                'currency' => $this->order->getCurrencyCode(),
169
                'value' => '0.00',
170
            ],
171
        ];
172
    }
173
174
    private function createShippingFee(int $divisor): array
175
    {
176
        $details = [];
177
178
        /** @var ShipmentInterface $shipment */
179
        $shipment = $this->order->getShipments()->first();
180
181
        if (false !== $shipment) {
0 ignored issues
show
introduced by
The condition false !== $shipment is always true.
Loading history...
182
            $details[] = [
183
                'type' => self::SHIPPING_TYPE,
184
                'name' => self::SHIPPING_FEE,
185
                'quantity' => 1,
186
                'vatRate' => null === $this->getTaxRatesShipments() ? '0.00' : (string) ($this->getTaxRatesShipments() * 100),
187
                'unitPrice' => [
188
                    'currency' => $this->order->getCurrencyCode(),
189
                    'value' => $this->intToStringConverter->convertIntToString($this->order->getShippingTotal(), $divisor),
190
                ],
191
                'totalAmount' => [
192
                    'currency' => $this->order->getCurrencyCode(),
193
                    'value' => $this->intToStringConverter->convertIntToString($this->order->getShippingTotal(), $divisor),
194
                ],
195
                'vatAmount' => [
196
                    'currency' => $this->order->getCurrencyCode(),
197
                    'value' => null === $this->getTaxRatesShipments() ? '0.00' : $this->calculateTaxAmount->calculate($this->getTaxRatesShipments(), $this->order->getShippingTotal()),
198
                ],
199
            ];
200
        }
201
202
        return $details;
203
    }
204
205
    private function getTaxRatesUnitItem(OrderItem $item): ?float
206
    {
207
        return $this->taxUnitItemResolver->resolve($this->order, $item);
208
    }
209
210
    private function getTaxRatesShipments(): ?float
211
    {
212
        return $this->taxShipmentResolver->resolve($this->order);
213
    }
214
215
    private function getUnitPriceWithTax(OrderItem $item): int
216
    {
217
        return (int) round($item->getUnitPrice() + ($item->getTaxTotal() / $item->getQuantity()));
218
    }
219
220
    private function getUnitDiscountAmount(OrderItem $item): int
221
    {
222
        return ($item->getUnitPrice() - $item->getFullDiscountedUnitPrice()) * $item->getQuantity();
223
    }
224
}
225