Completed
Push — checkout-consistent-prices ( af49ca )
by Kamil
13:24
created

ShowPage::getPromotionTotal()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 6
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
/*
4
 * This file is part of the Sylius package.
5
 *
6
 * (c) Paweł Jędrzejewski
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
declare(strict_types=1);
13
14
namespace Sylius\Behat\Page\Admin\Order;
15
16
use Behat\Mink\Element\NodeElement;
17
use Behat\Mink\Exception\ElementNotFoundException;
18
use Behat\Mink\Session;
19
use FriendsOfBehat\PageObjectExtension\Page\SymfonyPage;
20
use Sylius\Behat\Service\Accessor\TableAccessorInterface;
21
use Sylius\Bundle\MoneyBundle\Formatter\MoneyFormatter;
22
use Sylius\Bundle\MoneyBundle\Formatter\MoneyFormatterInterface;
23
use Sylius\Component\Core\Model\OrderInterface;
24
use Symfony\Component\Routing\RouterInterface;
25
26
class ShowPage extends SymfonyPage implements ShowPageInterface
27
{
28
    /** @var TableAccessorInterface */
29
    private $tableAccessor;
30
31
    /** @var MoneyFormatterInterface  */
32
    private $moneyFormatter;
33
34
    public function __construct(
35
        Session $session,
36
        $minkParameters,
37
        RouterInterface $router,
38
        TableAccessorInterface $tableAccessor,
39
        MoneyFormatterInterface $moneyFormatter
40
    ) {
41
        parent::__construct($session, $minkParameters, $router);
42
43
        $this->tableAccessor = $tableAccessor;
44
        $this->moneyFormatter = $moneyFormatter;
45
    }
46
47
    public function hasCustomer(string $customerName): bool
48
    {
49
        $customerText = $this->getElement('customer')->getText();
50
51
        return stripos($customerText, $customerName) !== false;
52
    }
53
54
    public function hasShippingAddress(string $customerName, string $street, string $postcode, string $city, string $countryName): bool
55
    {
56
        $shippingAddressText = $this->getElement('shipping_address')->getText();
57
58
        return $this->hasAddress($shippingAddressText, $customerName, $street, $postcode, $city, $countryName);
59
    }
60
61
    public function hasShippingAddressVisible(): bool
62
    {
63
        try {
64
            $this->getElement('shipping_address');
65
        } catch (ElementNotFoundException $exception) {
66
            return false;
67
        }
68
69
        return true;
70
    }
71
72
    public function hasBillingAddress(string $customerName, string $street, string $postcode, string $city, string $countryName): bool
73
    {
74
        $billingAddressText = $this->getElement('billing_address')->getText();
75
76
        return $this->hasAddress($billingAddressText, $customerName, $street, $postcode, $city, $countryName);
77
    }
78
79
    public function hasShipment(string $shippingDetails): bool
80
    {
81
        $shipmentsText = $this->getElement('shipments')->getText();
82
83
        return stripos($shipmentsText, $shippingDetails) !== false;
84
    }
85
86
    public function specifyTrackingCode(string $code): void
87
    {
88
        $this->getDocument()->fillField('sylius_shipment_ship_tracking', $code);
89
    }
90
91
    public function canShipOrder(OrderInterface $order): bool
92
    {
93
        return $this->getLastOrderShipmentElement($order)->hasButton('Ship');
94
    }
95
96
    public function shipOrder(OrderInterface $order): void
97
    {
98
        $this->getLastOrderShipmentElement($order)->pressButton('Ship');
99
    }
100
101
    public function hasPayment(string $paymentDetails): bool
102
    {
103
        $paymentsText = $this->getElement('payments')->getText();
104
105
        return stripos($paymentsText, $paymentDetails) !== false;
106
    }
107
108
    public function canCompleteOrderLastPayment(OrderInterface $order): bool
109
    {
110
        return $this->getLastOrderPaymentElement($order)->hasButton('Complete');
111
    }
112
113
    public function completeOrderLastPayment(OrderInterface $order): void
114
    {
115
        $this->getLastOrderPaymentElement($order)->pressButton('Complete');
116
    }
117
118
    public function refundOrderLastPayment(OrderInterface $order): void
119
    {
120
        $this->getLastOrderPaymentElement($order)->pressButton('Refund');
121
    }
122
123
    public function countItems(): int
124
    {
125
        return $this->tableAccessor->countTableBodyRows($this->getElement('table'));
126
    }
127
128
    public function isProductInTheList(string $productName): bool
129
    {
130
        try {
131
            $table = $this->getElement('table');
132
            $rows = $this->tableAccessor->getRowsWithFields(
133
                $table,
134
                ['item' => $productName]
135
            );
136
137
            foreach ($rows as $row) {
138
                $field = $this->tableAccessor->getFieldFromRow($table, $row, 'item');
139
                $name = $field->find('css', '.sylius-product-name');
140
                if (null !== $name && $name->getText() === $productName) {
141
                    return true;
142
                }
143
            }
144
145
            return false;
146
        } catch (\InvalidArgumentException $exception) {
147
            return false;
148
        }
149
    }
150
151
    public function getItemsTotal(): string
152
    {
153
        $itemsTotalElement = $this->getElement('items_total');
154
155
        return trim(str_replace('Items total:', '', $itemsTotalElement->getText()));
156
    }
157
158
    public function getTotal(): string
159
    {
160
        $totalElement = $this->getElement('total');
161
162
        return trim(str_replace('Order total:', '', $totalElement->getText()));
163
    }
164
165
    public function getShippingTotal(): string
166
    {
167
        $shippingTotalElement = $this->getElement('shipping_total');
168
169
        return trim(str_replace('Shipping total:', '', $shippingTotalElement->getText()));
170
    }
171
172
    public function getTaxTotal(): string
173
    {
174
        $taxTotalElement = $this->getElement('tax_total');
175
176
        return trim(str_replace('Tax total:', '', $taxTotalElement->getText()));
177
    }
178
179
    public function hasShippingCharge(string $shippingCharge): bool
180
    {
181
        $shippingChargesText = sprintf(
182
            '%s %s',
183
            substr($this->getElement('shipping_adjustment_name')->getText(), 0, -1),
184
            $this->getElement('shipping_charges')->getText()
185
        );
186
187
        return stripos($shippingChargesText, $shippingCharge) !== false;
188
    }
189
190
    public function getOrderPromotionTotal(): string
191
    {
192
        /** @var NodeElement[] $rows */
193
        $rows = $this->getElement('table')->findAll('css', 'tbody tr');
194
195
        $orderPromotionTotal = 0;
196
197
        foreach ($rows as $row) {
198
            $unitOrderPromotion =  $row->find('css', 'td:nth-child(4)')->getText();
199
            $quantity = $row->find('css', 'td:nth-child(6)')->getText();
200
            $itemOrderPromotion = (float) trim(str_replace('-$', '', $unitOrderPromotion)) * $quantity;
201
            $orderPromotionTotal += (int) ($itemOrderPromotion * 100);
202
        }
203
204
        return $this->getFormattedMoney($orderPromotionTotal > 0 ? -1 * $orderPromotionTotal: $orderPromotionTotal);
205
    }
206
207
    public function hasPromotionDiscount(string $promotionDiscount): bool
208
    {
209
        $promotionDiscountsText = $this->getElement('promotion_discounts')->getText();
210
211
        return stripos($promotionDiscountsText, $promotionDiscount) !== false;
212
    }
213
214
    public function hasTax(string $tax): bool
215
    {
216
        $taxesText = $this->getElement('taxes')->getText();
217
218
        return stripos($taxesText, $tax) !== false;
219
    }
220
221
    public function getItemCode(string $itemName): string
222
    {
223
        return $this->getItemProperty($itemName, 'sylius-product-variant-code');
224
    }
225
226
    public function getItemUnitPrice(string $itemName): string
227
    {
228
        return $this->getRowWithItem($itemName)->find('css', '.unit-price')->getText();
229
    }
230
231
    public function getItemDiscountedUnitPrice(string $itemName): string
232
    {
233
        return $this->getRowWithItem($itemName)->find('css', '.discounted-unit-price')->getText();
234
    }
235
236
    public function getItemOrderDiscount(string $itemName): string
237
    {
238
        return $this->getRowWithItem($itemName)->find('css', '.unit-order-discount')->getText();
239
    }
240
241
    public function getItemQuantity(string $itemName): string
242
    {
243
        return $this->getItemProperty($itemName, 'quantity');
244
    }
245
246
    public function getItemSubtotal(string $itemName): string
247
    {
248
        return $this->getItemProperty($itemName, 'subtotal');
249
    }
250
251
    public function getItemDiscount(string $itemName): string
252
    {
253
        return $this->getItemProperty($itemName, 'unit-discount');
254
    }
255
256
    public function getItemTax(string $itemName): string
257
    {
258
        return $this->getRowWithItem($itemName)->find('css', '.tax-excluded')->getText();
259
    }
260
261
    public function getItemTaxIncludedInPrice(string $itemName): string
262
    {
263
        return $this->getRowWithItem($itemName)->find('css', '.tax-included')->getText();
264
265
    }
266
267
    public function getItemTotal(string $itemName): string
268
    {
269
        return $this->getItemProperty($itemName, 'total');
270
    }
271
272
    public function getPaymentAmount(): string
273
    {
274
        $paymentsPrice = $this->getElement('payments')->find('css', '.description');
275
276
        return $paymentsPrice->getText();
277
    }
278
279
    public function getPaymentsCount(): int
280
    {
281
        try {
282
            $payments = $this->getElement('payments')->findAll('css', '.item');
283
        } catch (ElementNotFoundException $exception) {
284
            return 0;
285
        }
286
287
        return count($payments);
288
    }
289
290
    public function getShipmentsCount(): int
291
    {
292
        try {
293
            $shipments = $this->getElement('shipments')->findAll('css', '.item');
294
        } catch (ElementNotFoundException $exception) {
295
            return 0;
296
        }
297
298
        return count($shipments);
299
    }
300
301
    public function hasCancelButton(): bool
302
    {
303
        return $this->getDocument()->hasButton('Cancel');
304
    }
305
306
    public function getOrderState(): string
307
    {
308
        return $this->getElement('order_state')->getText();
309
    }
310
311
    public function getPaymentState(): string
312
    {
313
        return $this->getElement('order_payment_state')->getText();
314
    }
315
316
    public function getShippingState(): string
317
    {
318
        return $this->getElement('order_shipping_state')->getText();
319
    }
320
321
    public function cancelOrder(): void
322
    {
323
        $this->getDocument()->pressButton('Cancel');
324
    }
325
326
    public function deleteOrder(): void
327
    {
328
        $this->getDocument()->pressButton('Delete');
329
    }
330
331
    public function hasNote(string $note): bool
332
    {
333
        $orderNotesElement = $this->getElement('order_notes');
334
335
        return $orderNotesElement->getText() === $note;
336
    }
337
338
    public function hasShippingProvinceName(string $provinceName): bool
339
    {
340
        $shippingAddressText = $this->getElement('shipping_address')->getText();
341
342
        return false !== stripos($shippingAddressText, $provinceName);
343
    }
344
345
    public function hasBillingProvinceName(string $provinceName): bool
346
    {
347
        $billingAddressText = $this->getElement('billing_address')->getText();
348
349
        return false !== stripos($billingAddressText, $provinceName);
350
    }
351
352
    public function getIpAddressAssigned(): string
353
    {
354
        return $this->getElement('ip_address')->getText();
355
    }
356
357
    public function getOrderCurrency(): string
358
    {
359
        return $this->getElement('currency')->getText();
360
    }
361
362
    public function hasRefundButton(): bool
363
    {
364
        return $this->getDocument()->hasButton('Refund');
365
    }
366
367
    public function getShippingPromotionData(): string
368
    {
369
        return $this->getElement('promotion_shipping_discounts')->getText();
370
    }
371
372
    public function getRouteName(): string
373
    {
374
        return 'sylius_admin_order_show';
375
    }
376
377
    protected function getDefinedElements(): array
378
    {
379
        return array_merge(parent::getDefinedElements(), [
380
            'billing_address' => '#billing-address',
381
            'currency' => '#sylius-order-currency',
382
            'customer' => '#customer',
383
            'ip_address' => '#ipAddress',
384
            'items_total' => '#items-total',
385
            'order_notes' => '#sylius-order-notes',
386
            'order_payment_state' => '#payment-state > span',
387
            'order_shipping_state' => '#shipping-state > span',
388
            'order_state' => '#sylius-order-state',
389
            'payments' => '#sylius-payments',
390
            'promotion_discounts' => '#promotion-discounts',
391
            'promotion_shipping_discounts' => '#shipping-discount-value',
392
            'promotion_total' => '#promotion-total',
393
            'shipments' => '#sylius-shipments',
394
            'shipping_address' => '#shipping-address',
395
            'shipping_adjustment_name' => '#shipping-adjustment-label',
396
            'shipping_charges' => '#shipping-base-value',
397
            'shipping_total' => '#shipping-total',
398
            'table' => '.table',
399
            'tax_total' => '#tax-total',
400
            'taxes' => '#taxes',
401
            'total' => '#total',
402
        ]);
403
    }
404
405
    protected function getTableAccessor(): TableAccessorInterface
406
    {
407
        return $this->tableAccessor;
408
    }
409
410
    private function hasAddress(string $elementText, string $customerName, string $street, string $postcode, string $city, string $countryName): bool
411
    {
412
        return
413
            (stripos($elementText, $customerName) !== false) &&
414
            (stripos($elementText, $street) !== false) &&
415
            (stripos($elementText, $city) !== false) &&
416
            (stripos($elementText, $countryName . ' ' . $postcode) !== false)
417
        ;
418
    }
419
420
    private function getItemProperty(string $itemName, string $property): string
421
    {
422
        $rows = $this->tableAccessor->getRowsWithFields(
423
            $this->getElement('table'),
424
            ['item' => $itemName]
425
        );
426
427
        return $rows[0]->find('css', '.' . $property)->getText();
428
    }
429
430
    private function getRowWithItem(string $itemName): ?NodeElement
431
    {
432
        return $this->tableAccessor->getRowWithFields($this->getElement('table'), ['item' => $itemName]);
433
    }
434
435
    private function getLastOrderPaymentElement(OrderInterface $order): ?NodeElement
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
436
    {
437
        $payment = $order->getPayments()->last();
438
439
        $paymentStateElements = $this->getElement('payments')->findAll('css', sprintf('span.ui.label:contains(\'%s\')', ucfirst($payment->getState())));
440
        $paymentStateElement = end($paymentStateElements);
441
442
        return $paymentStateElement->getParent()->getParent();
443
    }
444
445
    private function getLastOrderShipmentElement(OrderInterface $order): ?NodeElement
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
446
    {
447
        $shipment = $order->getShipments()->last();
448
449
        $shipmentStateElements = $this->getElement('shipments')->findAll('css', sprintf('span.ui.label:contains(\'%s\')', ucfirst($shipment->getState())));
450
        $shipmentStateElement = end($shipmentStateElements);
451
452
        return $shipmentStateElement->getParent()->getParent();
453
    }
454
455
    private function getFormattedMoney(int $orderPromotionTotal): string
456
    {
457
        return $this->moneyFormatter->format($orderPromotionTotal, $this->getDocument()->find('css', '#sylius-order-currency')->getText());
458
    }
459
}
460