WebClient::resolvePickupDate()   A
last analyzed

Complexity

Conditions 3
Paths 2

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 6
dl 0
loc 12
rs 10
c 0
b 0
f 0
cc 3
nc 2
nop 0
1
<?php
2
3
/*
4
 * This file was created by the developers from BitBag.
5
 * Feel free to contact us once you face any issues or want to start
6
 * another great project.
7
 * You can find more information about us on https://bitbag.shop and write us
8
 * an email on [email protected].
9
 */
10
11
declare(strict_types=1);
12
13
namespace BitBag\SyliusDhl24PlShippingExportPlugin\Api;
14
15
use BitBag\SyliusShippingExportPlugin\Entity\ShippingGatewayInterface;
16
use Sylius\Component\Core\Model\AddressInterface;
17
use Sylius\Component\Core\Model\OrderInterface;
18
use Sylius\Component\Core\Model\OrderItemInterface;
19
use Sylius\Component\Core\Model\ShipmentInterface;
20
use Webmozart\Assert\Assert;
21
22
final class WebClient implements WebClientInterface
23
{
24
    public const DATE_FORMAT = 'Y-m-d';
25
26
    /** @var ShippingGatewayInterface */
27
    private $shippingGateway;
28
29
    /** @var ShipmentInterface */
30
    private $shipment;
31
32
    public function setShippingGateway(ShippingGatewayInterface $shippingGateway): void
33
    {
34
        $this->shippingGateway = $shippingGateway;
35
    }
36
37
    public function setShipment(ShipmentInterface $shipment): void
38
    {
39
        $this->shipment = $shipment;
40
    }
41
42
    public function getRequestData(): array
43
    {
44
        return [
45
            'authData' => $this->getAuthData(),
46
            'shipment' => [
47
                'content' => $this->getContent(),
48
                'shipmentInfo' => $this->getShipmentInfo(),
49
                'pieceList' => $this->getPieceList(),
50
                'ship' => $this->getShip(),
51
            ],
52
        ];
53
    }
54
55
    private function getOrder(): OrderInterface
56
    {
57
        return $this->shipment->getOrder();
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->shipment->getOrder() returns the type null which is incompatible with the type-hinted return Sylius\Component\Core\Model\OrderInterface.
Loading history...
58
    }
59
60
    private function getAuthData(): array
61
    {
62
        return [
63
            'username' => $this->shippingGateway->getConfigValue('login'),
64
            'password' => $this->shippingGateway->getConfigValue('password'),
65
        ];
66
    }
67
68
    private function getContent(): string
69
    {
70
        $content = '';
71
72
        /** @var OrderItemInterface $item */
73
        foreach ($this->getOrder()->getItems() as $item) {
74
            $mainTaxon = $item->getProduct()->getMainTaxon();
75
76
            if ($mainTaxon !== null) {
77
                if (stristr($content, $mainTaxon->getName()) === false) {
78
                    $content .= $mainTaxon->getName() . ', ';
79
                }
80
            }
81
        }
82
83
        $content = rtrim($content, ', ');
84
85
        return substr($content, 0, 30);
86
    }
87
88
    private function getShipmentInfo(): array
89
    {
90
        $shipmentInfo = [
91
            'dropOffType' => $this->getShippingGatewayConfig('drop_off_type'),
92
            'serviceType' => $this->getShippingGatewayConfig('service_type'),
93
            'labelType' => $this->getShippingGatewayConfig('label_type'),
94
            'billing' => [
95
                'shippingPaymentType' => $this->getShippingGatewayConfig('shipping_payment_type'),
96
                'billingAccountNumber' => $this->getShippingGatewayConfig('billing_account_number'),
97
                'paymentType' => $this->getShippingGatewayConfig('payment_type'),
98
            ],
99
            'shipmentTime' => [
100
                'shipmentDate' => $this->resolvePickupDate(),
101
                'shipmentStartHour' => $this->getShippingGatewayConfig('shipment_start_hour'),
102
                'shipmentEndHour' => $this->getShippingGatewayConfig('shipment_end_hour'),
103
            ],
104
        ];
105
106
        if (true === $this->isCashOnDelivery()) {
107
            $shipmentInfo['specialServices'] = $this->resolveSpecialServices();
108
        }
109
110
        return $shipmentInfo;
111
    }
112
113
    private function getPieceList(): array
114
    {
115
        $weight = $this->shipment->getShippingWeight();
116
        Assert::greaterThan($weight, 0, sprintf('Shipment weight must be greater than %d.', 0));
117
118
        return [
119
            [
120
                'type' => $this->getShippingGatewayConfig('package_type'),
121
                'weight' => $this->shipment->getShippingWeight(),
122
                'width' => $this->getShippingGatewayConfig('package_width'),
123
                'height' => $this->getShippingGatewayConfig('package_height'),
124
                'length' => $this->getShippingGatewayConfig('package_length'),
125
                'quantity' => 1,
126
            ],
127
        ];
128
    }
129
130
    private function getShip(): array
131
    {
132
        $shippingAddress = $this->getOrder()->getShippingAddress();
133
134
        return [
135
            'shipper' => [
136
                'address' => [
137
                    'country' => 'PL',
138
                    'name' => $this->getShippingGatewayConfig('name'),
139
                    'postalCode' => str_replace('-', '', $this->getShippingGatewayConfig('postal_code')),
140
                    'city' => $this->getShippingGatewayConfig('city'),
141
                    'street' => $this->getShippingGatewayConfig('street'),
142
                    'houseNumber' => $this->getShippingGatewayConfig('house_number'),
143
                    'phoneNumber' => $this->getShippingGatewayConfig('phone_number'),
144
                ],
145
            ],
146
            'receiver' => [
147
                'address' => [
148
                    'country' => 'PL',
149
                    'name' => $shippingAddress->getFullName(),
150
                    'postalCode' => str_replace('-', '', $shippingAddress->getPostcode()),
151
                    'houseNumber' => $this->resolveHouseNumber($shippingAddress),
0 ignored issues
show
Bug introduced by
It seems like $shippingAddress can also be of type null; however, parameter $address of BitBag\SyliusDhl24PlShip...t::resolveHouseNumber() does only seem to accept Sylius\Component\Core\Model\AddressInterface, 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

151
                    'houseNumber' => $this->resolveHouseNumber(/** @scrutinizer ignore-type */ $shippingAddress),
Loading history...
152
                    'city' => $shippingAddress->getCity(),
153
                    'street' => $shippingAddress->getStreet(),
154
                    'phoneNumber' => $shippingAddress->getPhoneNumber(),
155
                ],
156
            ],
157
        ];
158
    }
159
160
    private function resolveHouseNumber(AddressInterface $address): string
161
    {
162
        $street = $address->getStreet();
163
        $streetParts = explode(' ', $street);
0 ignored issues
show
Bug introduced by
It seems like $street can also be of type null; however, parameter $string of explode() 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

163
        $streetParts = explode(' ', /** @scrutinizer ignore-type */ $street);
Loading history...
164
165
        Assert::greaterThan(count($streetParts), 0, sprintf(
166
            'Street "%s" is invalid. The street format must be something like %s, where %d is the house number.',
167
            $street,
168
            '"Opolska 45"',
169
            45
170
        ));
171
172
        return end($streetParts);
173
    }
174
175
    private function isCashOnDelivery(): bool
176
    {
177
        $codPaymentMethodCode = $this->getShippingGatewayConfig('cod_payment_method_code');
178
        $payments = $this->getOrder()->getPayments();
179
180
        foreach ($payments as $payment) {
181
            return $codPaymentMethodCode === $payment->getMethod()->getCode();
182
        }
183
184
        return false;
185
    }
186
187
    private function resolvePickupDate(): string
188
    {
189
        $now = new \DateTime();
190
        $breakingHour = $this->getShippingGatewayConfig('pickup_breaking_hour');
191
192
        if (null !== $breakingHour && $now->format('H') >= (int) $breakingHour) {
193
            $tomorrow = $now->modify('+1 day');
194
195
            return $this->resolveWeekend($tomorrow)->format(self::DATE_FORMAT);
196
        }
197
198
        return $this->resolveWeekend($now)->format(self::DATE_FORMAT);
199
    }
200
201
    private function resolveWeekend(\DateTime $date): \DateTime
202
    {
203
        $dayOfWeek = (int) $date->format('N');
204
205
        if ($dayOfWeek === 6) {
206
            return $date->modify('+2 days');
207
        }
208
209
        if ($dayOfWeek === 7) {
210
            return $date->modify('+1 day');
211
        }
212
213
        return $date;
214
    }
215
216
    private function resolveSpecialServices(): array
217
    {
218
        $collectOnDeliveryValue = number_format($this->getOrder()->getTotal(), 2, '.', '');
219
220
        return [
221
            ['serviceType' => 'COD', 'serviceValue' => $collectOnDeliveryValue],
222
            'collectOnDeliveryForm' => $this->getShippingGatewayConfig('collect_on_delivery_form'),
223
        ];
224
    }
225
226
    private function getShippingGatewayConfig($config)
227
    {
228
        return $this->shippingGateway->getConfigValue($config);
229
    }
230
}
231