getMappedSalesOrderTotalsBySalesOrderIds()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 8
nc 1
nop 1
dl 0
loc 11
rs 10
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * Copyright © 2016-present Spryker Systems GmbH. All rights reserved.
5
 * Use of this software requires acceptance of the Evaluation License Agreement. See LICENSE file.
6
 */
7
8
namespace Spryker\Zed\Sales\Persistence;
9
10
use ArrayObject;
11
use Generated\Shared\Transfer\AddressTransfer;
12
use Generated\Shared\Transfer\ExpenseTransfer;
13
use Generated\Shared\Transfer\FilterTransfer;
14
use Generated\Shared\Transfer\OrderCollectionTransfer;
15
use Generated\Shared\Transfer\OrderCriteriaTransfer;
16
use Generated\Shared\Transfer\OrderFilterTransfer;
17
use Generated\Shared\Transfer\OrderItemFilterTransfer;
18
use Generated\Shared\Transfer\OrderListRequestTransfer;
19
use Generated\Shared\Transfer\OrderListTransfer;
20
use Generated\Shared\Transfer\OrderTransfer;
21
use Generated\Shared\Transfer\PaginationTransfer;
22
use Generated\Shared\Transfer\SalesExpenseCollectionDeleteCriteriaTransfer;
23
use Generated\Shared\Transfer\TaxTotalTransfer;
24
use Generated\Shared\Transfer\TotalsTransfer;
25
use Orm\Zed\Oms\Persistence\Map\SpyOmsOrderItemStateTableMap;
26
use Orm\Zed\Sales\Persistence\Map\SpySalesOrderTableMap;
27
use Orm\Zed\Sales\Persistence\SpySalesExpenseQuery;
28
use Orm\Zed\Sales\Persistence\SpySalesOrder;
29
use Orm\Zed\Sales\Persistence\SpySalesOrderAddress;
30
use Orm\Zed\Sales\Persistence\SpySalesOrderItemQuery;
31
use Orm\Zed\Sales\Persistence\SpySalesOrderQuery;
32
use Propel\Runtime\ActiveQuery\Criteria;
33
use Propel\Runtime\ActiveQuery\ModelCriteria;
34
use Spryker\Zed\Kernel\Persistence\AbstractRepository;
35
use Spryker\Zed\Propel\PropelFilterCriteria;
36
use Spryker\Zed\Sales\Business\Exception\InvalidSalesOrderException;
37
use Spryker\Zed\Sales\Persistence\Propel\QueryBuilder\OrderSearchFilterFieldQueryBuilder;
38
39
/**
40
 * @method \Spryker\Zed\Sales\Persistence\SalesPersistenceFactory getFactory()
41
 */
42
class SalesRepository extends AbstractRepository implements SalesRepositoryInterface
43
{
44
    /**
45
     * @var string
46
     */
47
    protected const ID_SALES_ORDER = 'id_sales_order';
48
49
    /**
50
     * @var array<string, string>
51
     */
52
    protected const SORT_KEYS_MAP = [
53
        'createdAt' => SpySalesOrderTableMap::COL_CREATED_AT,
54
        'updatedAt' => SpySalesOrderTableMap::COL_UPDATED_AT,
55
    ];
56
57
    /**
58
     * @param string $customerReference
59
     * @param string $orderReference
60
     *
61
     * @return int|null
62
     */
63
    public function findCustomerOrderIdByOrderReference(string $customerReference, string $orderReference): ?int
64
    {
65
        /** @var int|null $idSalesOrder */
66
        $idSalesOrder = $this->getFactory()
67
            ->createSalesOrderQuery()
68
            ->filterByCustomerReference($customerReference)
69
            ->filterByOrderReference($orderReference)
70
            ->select([static::ID_SALES_ORDER])
71
            ->findOne();
72
73
        return $idSalesOrder;
74
    }
75
76
    /**
77
     * @param int $idOrderAddress
78
     *
79
     * @return \Generated\Shared\Transfer\AddressTransfer|null
80
     */
81
    public function findOrderAddressByIdOrderAddress(int $idOrderAddress): ?AddressTransfer
82
    {
83
        $addressEntity = $this->getFactory()
84
            ->createSalesOrderAddressQuery()
85
            ->leftJoinWithCountry()
86
            ->filterByIdSalesOrderAddress($idOrderAddress)
87
            ->findOne();
88
89
        if ($addressEntity === null) {
90
            return null;
91
        }
92
93
        return $this->hydrateAddressTransferFromEntity($this->createOrderAddressTransfer(), $addressEntity);
94
    }
95
96
    /**
97
     * @module Oms
98
     *
99
     * @param \Generated\Shared\Transfer\OrderItemFilterTransfer $orderItemFilterTransfer
100
     *
101
     * @return array<\Generated\Shared\Transfer\ItemTransfer>
102
     */
103
    public function getOrderItems(OrderItemFilterTransfer $orderItemFilterTransfer): array
104
    {
105
        $salesOrderItemQuery = $this->getFactory()
106
            ->createSalesOrderItemQuery()
107
            ->innerJoinWithOrder()
108
            ->leftJoinWithProcess()
109
            ->leftJoinWithState();
110
111
        $salesOrderItemQuery = $this->setOrderItemFilters($salesOrderItemQuery, $orderItemFilterTransfer);
112
113
        $salesOrderItemQuery = $this->buildQueryFromCriteria(
114
            $salesOrderItemQuery,
115
            $orderItemFilterTransfer->getFilter(),
116
        );
117
118
        $salesOrderItemQuery->setFormatter(ModelCriteria::FORMAT_OBJECT);
119
120
        return $this->getFactory()
121
            ->createSalesOrderItemMapper()
122
            ->mapSalesOrderItemEntityCollectionToOrderItemTransfers($salesOrderItemQuery->find());
123
    }
124
125
    /**
126
     * @param array<int> $salesOrderIds
127
     *
128
     * @return array<string>
129
     */
130
    public function getCurrencyIsoCodesBySalesOrderIds(array $salesOrderIds): array
131
    {
132
        if (!$salesOrderIds) {
133
            return [];
134
        }
135
136
        /** @var \Propel\Runtime\Collection\ObjectCollection $currencyIsoCodes */
137
        $currencyIsoCodes = $this->getFactory()
138
            ->createSalesOrderQuery()
139
            ->filterByIdSalesOrder_In($salesOrderIds)
140
            ->select([static::ID_SALES_ORDER, SpySalesOrderTableMap::COL_CURRENCY_ISO_CODE])
141
            ->find();
142
143
        return $currencyIsoCodes->toKeyValue(static::ID_SALES_ORDER, SpySalesOrderTableMap::COL_CURRENCY_ISO_CODE);
144
    }
145
146
    /**
147
     * @param \Generated\Shared\Transfer\OrderListTransfer $orderListTransfer
148
     *
149
     * @return \Generated\Shared\Transfer\OrderListTransfer
150
     */
151
    public function searchOrders(OrderListTransfer $orderListTransfer): OrderListTransfer
152
    {
153
        $orderListTransfer
154
            ->requireFormat();
155
156
        $salesOrderQuery = $this->getFactory()
157
            ->createSalesOrderQuery()
158
            ->groupByIdSalesOrder()
159
            ->setIgnoreCase(true);
160
161
        $salesOrderQuery = $this->buildSearchOrdersQuery($salesOrderQuery, $orderListTransfer);
162
163
        if ($orderListTransfer->getPagination()) {
164
            $salesOrderQuery = $this->preparePagination($salesOrderQuery, $orderListTransfer->getPaginationOrFail());
165
        }
166
167
        $orderTransfers = $this->getFactory()
168
            ->createSalesOrderMapper()
169
            ->mapSalesOrderEntityCollectionToOrderTransfers($salesOrderQuery->find());
170
171
        return $orderListTransfer->setOrders(new ArrayObject($orderTransfers));
172
    }
173
174
    /**
175
     * @param array<int> $salesOrderIds
176
     *
177
     * @return array<\Generated\Shared\Transfer\ItemTransfer>
178
     */
179
    public function getSalesOrderItemsByOrderIds(array $salesOrderIds): array
180
    {
181
        $salesOrderItemQuery = $this->getFactory()
182
            ->createSalesOrderItemQuery()
183
            ->filterByFkSalesOrder_In($salesOrderIds);
184
185
        return $this->getFactory()
186
            ->createSalesOrderItemMapper()
187
            ->mapSalesOrderItemEntityCollectionToOrderItemTransfers($salesOrderItemQuery->find());
188
    }
189
190
    /**
191
     * @param array<int> $salesOrderIds
192
     *
193
     * @return array<\Generated\Shared\Transfer\TotalsTransfer>
194
     */
195
    public function getMappedSalesOrderTotalsBySalesOrderIds(array $salesOrderIds): array
196
    {
197
        $salesOrderTotalsQuery = $this->getFactory()
198
            ->getSalesOrderTotalsPropelQuery()
199
            ->filterByFkSalesOrder_In($salesOrderIds)
200
            ->groupByFkSalesOrder()
201
            ->orderByCreatedAt();
202
203
        return $this->getFactory()
204
            ->createSalesOrderMapper()
205
            ->mapSalesOrderTotalsEntityCollectionToMappedOrderTotalsByIdSalesOrder($salesOrderTotalsQuery->find());
206
    }
207
208
    /**
209
     * @param \Orm\Zed\Sales\Persistence\SpySalesOrderQuery $salesOrderQuery
210
     * @param \Generated\Shared\Transfer\OrderListTransfer $orderListTransfer
211
     *
212
     * @return \Orm\Zed\Sales\Persistence\SpySalesOrderQuery
213
     */
214
    protected function buildSearchOrdersQuery(
215
        SpySalesOrderQuery $salesOrderQuery,
216
        OrderListTransfer $orderListTransfer
217
    ): SpySalesOrderQuery {
218
        $salesOrderQuery = $this->getFactory()
219
            ->createOrderSearchFilterFieldQueryBuilder()
220
            ->addSalesOrderQueryFilters($salesOrderQuery, $orderListTransfer);
221
222
        $queryJoinCollectionTransfer = $orderListTransfer->getQueryJoins();
223
224
        if ($queryJoinCollectionTransfer && $queryJoinCollectionTransfer->getQueryJoins()->count()) {
225
            $salesOrderQuery = $this->getFactory()
226
                ->createOrderSearchQueryJoinQueryBuilder()
227
                ->addSalesOrderQueryFilters($salesOrderQuery, $queryJoinCollectionTransfer);
228
        }
229
230
        if ($this->isSearchByAllFilterFieldSet($orderListTransfer->getFilterFields())) {
231
            $salesOrderQuery->where([OrderSearchFilterFieldQueryBuilder::CONDITION_GROUP_ALL]);
232
        }
233
234
        return $salesOrderQuery;
235
    }
236
237
    /**
238
     * @param \Propel\Runtime\ActiveQuery\ModelCriteria $query
239
     * @param \Generated\Shared\Transfer\PaginationTransfer $paginationTransfer
240
     *
241
     * @return \Propel\Runtime\ActiveQuery\ModelCriteria
242
     */
243
    protected function preparePagination(
244
        ModelCriteria $query,
245
        PaginationTransfer $paginationTransfer
246
    ): ModelCriteria {
247
        $page = $paginationTransfer
248
            ->requirePage()
249
            ->getPage();
250
251
        $maxPerPage = $paginationTransfer
252
            ->requireMaxPerPage()
253
            ->getMaxPerPage();
254
255
        $propelModelPager = $query->paginate($page, $maxPerPage);
256
257
        $paginationTransfer->setNbResults($propelModelPager->getNbResults())
258
            ->setFirstIndex($propelModelPager->getFirstIndex())
259
            ->setLastIndex($propelModelPager->getLastIndex())
260
            ->setFirstPage($propelModelPager->getFirstPage())
261
            ->setLastPage($propelModelPager->getLastPage())
262
            ->setNextPage($propelModelPager->getNextPage())
263
            ->setPreviousPage($propelModelPager->getPreviousPage());
264
265
        return $propelModelPager->getQuery();
266
    }
267
268
    /**
269
     * @param \Generated\Shared\Transfer\AddressTransfer $addressTransfer
270
     * @param \Orm\Zed\Sales\Persistence\SpySalesOrderAddress $addressEntity
271
     *
272
     * @return \Generated\Shared\Transfer\AddressTransfer
273
     */
274
    protected function hydrateAddressTransferFromEntity(
275
        AddressTransfer $addressTransfer,
276
        SpySalesOrderAddress $addressEntity
277
    ): AddressTransfer {
278
        $addressTransfer->fromArray($addressEntity->toArray(), true);
279
        $addressTransfer->setIso2Code($addressEntity->getCountry()->getIso2Code());
280
281
        return $addressTransfer;
282
    }
283
284
    /**
285
     * @return \Generated\Shared\Transfer\AddressTransfer
286
     */
287
    protected function createOrderAddressTransfer(): AddressTransfer
288
    {
289
        return new AddressTransfer();
290
    }
291
292
    /**
293
     * @param \Generated\Shared\Transfer\OrderListRequestTransfer $orderListRequestTransfer
294
     *
295
     * @return \Generated\Shared\Transfer\OrderListTransfer
296
     */
297
    public function getCustomerOrderListByCustomerReference(OrderListRequestTransfer $orderListRequestTransfer): OrderListTransfer
298
    {
299
        $orderListQuery = $this->getFactory()
300
            ->createSalesOrderQuery()
301
            ->filterByCustomerReference($orderListRequestTransfer->getCustomerReference());
302
303
        if ($orderListRequestTransfer->getOrderReferences()) {
304
            $orderListQuery->filterByOrderReference_In($orderListRequestTransfer->getOrderReferences());
305
        }
306
307
        $ordersCount = $orderListQuery->count();
308
        if (!$ordersCount) {
309
            return new OrderListTransfer();
310
        }
311
312
        $orderListQuery = $this->applyFilterToQuery($orderListQuery, $orderListRequestTransfer->getFilter());
313
314
        $orderListTransfer = $this->getFactory()
315
            ->createSalesOrderMapper()
316
            ->mapSalesOrderEntitiesToOrderListTransfer($orderListQuery->find()->getArrayCopy(), new OrderListTransfer());
317
318
        $orderListTransfer->setPagination((new PaginationTransfer())->setNbResults($ordersCount));
319
320
        return $orderListTransfer;
321
    }
322
323
    /**
324
     * @param \Orm\Zed\Sales\Persistence\SpySalesOrderQuery $orderListQuery
325
     * @param \Generated\Shared\Transfer\FilterTransfer|null $filterTransfer
326
     *
327
     * @return \Orm\Zed\Sales\Persistence\SpySalesOrderQuery
328
     */
329
    protected function applyFilterToQuery(SpySalesOrderQuery $orderListQuery, ?FilterTransfer $filterTransfer): SpySalesOrderQuery
330
    {
331
        if ($filterTransfer) {
332
            if ($filterTransfer->getOrderBy() && isset(static::SORT_KEYS_MAP[$filterTransfer->getOrderBy()])) {
333
                $filterTransfer->setOrderBy(static::SORT_KEYS_MAP[$filterTransfer->getOrderBy()]);
334
            }
335
336
            $orderListQuery->mergeWith(
337
                (new PropelFilterCriteria($filterTransfer))->toCriteria(),
338
            );
339
        }
340
341
        return $orderListQuery;
342
    }
343
344
    /**
345
     * @param \Orm\Zed\Sales\Persistence\SpySalesOrderItemQuery $salesOrderItemQuery
346
     * @param \Generated\Shared\Transfer\OrderItemFilterTransfer $orderItemFilterTransfer
347
     *
348
     * @return \Orm\Zed\Sales\Persistence\SpySalesOrderItemQuery
349
     */
350
    protected function setOrderItemFilters(
351
        SpySalesOrderItemQuery $salesOrderItemQuery,
352
        OrderItemFilterTransfer $orderItemFilterTransfer
353
    ): SpySalesOrderItemQuery {
354
        if ($orderItemFilterTransfer->getSalesOrderItemIds()) {
355
            $salesOrderItemQuery->filterByIdSalesOrderItem_In(array_unique($orderItemFilterTransfer->getSalesOrderItemIds()));
356
        }
357
358
        if ($orderItemFilterTransfer->getSalesOrderItemUuids()) {
359
            $salesOrderItemQuery->filterByUuid_In(array_unique($orderItemFilterTransfer->getSalesOrderItemUuids()));
360
        }
361
362
        if ($orderItemFilterTransfer->getSalesOrderIds()) {
363
            $salesOrderItemQuery->filterByFkSalesOrder_In(array_unique($orderItemFilterTransfer->getSalesOrderIds()));
364
        }
365
366
        if ($orderItemFilterTransfer->getCustomerReferences()) {
367
            $salesOrderItemQuery
368
                ->useOrderQuery()
369
                    ->filterByCustomerReference_In(array_unique($orderItemFilterTransfer->getCustomerReferences()))
370
                ->endUse();
371
        }
372
373
        if ($orderItemFilterTransfer->getOrderReferences()) {
374
            $salesOrderItemQuery
375
                ->useOrderQuery()
376
                    ->filterByOrderReference_In(array_unique($orderItemFilterTransfer->getOrderReferences()))
377
                ->endUse();
378
        }
379
380
        if ($orderItemFilterTransfer->getItemStates()) {
381
            $salesOrderItemQuery
382
                ->useStateQuery()
383
                    ->filterByName_In(array_unique($orderItemFilterTransfer->getItemStates()))
384
                ->endUse();
385
        }
386
387
        return $salesOrderItemQuery;
388
    }
389
390
    /**
391
     * @param \ArrayObject<int, \Generated\Shared\Transfer\FilterFieldTransfer> $filterFieldTransfers
392
     *
393
     * @return bool
394
     */
395
    protected function isSearchByAllFilterFieldSet(ArrayObject $filterFieldTransfers): bool
396
    {
397
        foreach ($filterFieldTransfers as $filterFieldTransfer) {
398
            if ($filterFieldTransfer->getType() === OrderSearchFilterFieldQueryBuilder::SEARCH_TYPE_ALL) {
399
                return true;
400
            }
401
        }
402
403
        return false;
404
    }
405
406
    /**
407
     * @param \Generated\Shared\Transfer\OrderFilterTransfer $orderFilterTransfer
408
     *
409
     * @return \Generated\Shared\Transfer\OrderTransfer
410
     */
411
    public function getSalesOrderDetails(OrderFilterTransfer $orderFilterTransfer): OrderTransfer
412
    {
413
        $orderEntity = $this->getSalesOrderEntity($orderFilterTransfer);
414
415
        return $this->createOrderTransfer($orderEntity);
416
    }
417
418
    /**
419
     * @param \Generated\Shared\Transfer\OrderTransfer $orderTransfer
420
     *
421
     * @return int
422
     */
423
    public function getTotalCustomerOrderCount(OrderTransfer $orderTransfer): int
424
    {
425
        $customerReference = $orderTransfer->getCustomerReference();
426
427
        if ($customerReference === null) {
428
            return 0;
429
        }
430
431
        return $this->getFactory()
432
            ->createSalesOrderQuery()
433
            ->filterByCustomerReference($customerReference)
434
            ->count();
435
    }
436
437
    /**
438
     * @param int $idSalesOrder
439
     *
440
     * @return int
441
     */
442
    public function countUniqueProductsForOrder(int $idSalesOrder): int
443
    {
444
        return (int)$this->getFactory()
445
            ->createSalesOrderItemQuery()
446
            ->filterByFkSalesOrder($idSalesOrder)
447
            ->withColumn('COUNT(*)', 'Count')
448
            ->select(['Count'])
449
            ->groupBySku()
450
            ->orderBy('Count')
451
            ->count();
452
    }
453
454
    /**
455
     * @param \Generated\Shared\Transfer\OrderCriteriaTransfer $orderCriteriaTransfer
456
     *
457
     * @return \Generated\Shared\Transfer\OrderCollectionTransfer
458
     */
459
    public function getOrderCollection(OrderCriteriaTransfer $orderCriteriaTransfer): OrderCollectionTransfer
460
    {
461
        $orderCollectionTransfer = new OrderCollectionTransfer();
462
463
        $salesOrderQuery = $this->getFactory()
464
            ->createSalesOrderQuery()
465
            ->leftJoinWith('SpySalesOrder.BillingAddress billingAddress')
466
            ->leftJoinWith('billingAddress.Country billingCountry')
467
            ->leftJoinWith('SpySalesOrder.ShippingAddress shippingAddress')
468
            ->leftJoinWith('shippingAddress.Country shippingCountry');
469
        $salesOrderQuery = $this->applySalesOrderFilters($salesOrderQuery, $orderCriteriaTransfer);
470
471
        /** @var \ArrayObject<array-key, \Generated\Shared\Transfer\SortTransfer> $sortTransfers */
472
        $sortTransfers = $orderCriteriaTransfer->getSortCollection();
473
        $salesOrderQuery = $this->applySorting($salesOrderQuery, $sortTransfers);
474
475
        $paginationTransfer = $orderCriteriaTransfer->getPagination();
476
        if ($paginationTransfer) {
477
            $salesOrderQuery = $this->applyPagination($salesOrderQuery, $paginationTransfer);
478
            $orderCollectionTransfer->setPagination($paginationTransfer);
479
        }
480
481
        $salesOrderEntitiesIndexedByIdSalesOrder = $salesOrderQuery->find()
482
            ->getArrayCopy('IdSalesOrder');
483
        $salesOrderEntitiesIndexedByIdSalesOrder = $this->expandSalesOrdersWithSalesOrderItems(
484
            $salesOrderEntitiesIndexedByIdSalesOrder,
485
        );
486
        $salesOrderEntitiesIndexedByIdSalesOrder = $this->expandSalesOrdersWithSalesExpenses(
487
            $salesOrderEntitiesIndexedByIdSalesOrder,
488
        );
489
490
        foreach ($salesOrderEntitiesIndexedByIdSalesOrder as $salesOrderEntity) {
491
            $orderCollectionTransfer->addOrder($this->createOrderTransfer($salesOrderEntity));
492
        }
493
494
        return $orderCollectionTransfer;
495
    }
496
497
    /**
498
     * @param \Generated\Shared\Transfer\OrderFilterTransfer $orderFilterTransfer
499
     *
500
     * @return \Generated\Shared\Transfer\OrderTransfer|null
501
     */
502
    public function findOrderWithoutItems(OrderFilterTransfer $orderFilterTransfer): ?OrderTransfer
503
    {
504
        $orderFilterTransfer->requireSalesOrderId();
505
506
        $salesOrderEntity = $this->getFactory()
507
            ->createSalesOrderQuery()
508
            ->filterByIdSalesOrder($orderFilterTransfer->getSalesOrderId())
509
            ->findOne();
510
511
        if ($salesOrderEntity === null) {
512
            return null;
513
        }
514
515
        return $this->getFactory()
516
            ->createSalesOrderMapper()
517
            ->mapSalesOrderEntityToSalesOrderTransfer($salesOrderEntity, new OrderTransfer());
518
    }
519
520
    /**
521
     * @param \Generated\Shared\Transfer\SalesExpenseCollectionDeleteCriteriaTransfer $salesExpenseCollectionDeleteCriteriaTransfer
522
     *
523
     * @return list<\Generated\Shared\Transfer\ExpenseTransfer>
524
     */
525
    public function getSalesExpensesBySalesExpenseCollectionDeleteCriteria(
526
        SalesExpenseCollectionDeleteCriteriaTransfer $salesExpenseCollectionDeleteCriteriaTransfer
527
    ): array {
528
        $salesExpenseQuery = $this->getFactory()->createSalesExpenseQuery();
529
        $salesExpenseQuery = $this->appySalesExpenseCollectionDeleteCriteriaFilters(
530
            $salesExpenseQuery,
531
            $salesExpenseCollectionDeleteCriteriaTransfer,
532
        );
533
534
        $salesExpenseEntities = $salesExpenseQuery->find();
535
536
        if ($salesExpenseEntities->count() === 0) {
537
            return [];
538
        }
539
540
        return $this->getFactory()
541
            ->createSalesExpenseMapper()
542
            ->mapSalesExpenseEntitiesToExpenseTransfers($salesExpenseEntities, []);
543
    }
544
545
    /**
546
     * @return list<string>
547
     */
548
    public function getOmsOrderItemStates(): array
549
    {
550
        return $this->getFactory()
551
            ->getOmsOrderItemStatePropelQuery()
552
            ->select([SpyOmsOrderItemStateTableMap::COL_NAME])
553
            ->orderBy(SpyOmsOrderItemStateTableMap::COL_ID_OMS_ORDER_ITEM_STATE)
554
            ->find()
555
            ->getData();
556
    }
557
558
    /**
559
     * @param \Generated\Shared\Transfer\OrderFilterTransfer $orderFilterTransfer
560
     *
561
     * @throws \Spryker\Zed\Sales\Business\Exception\InvalidSalesOrderException
562
     *
563
     * @return \Orm\Zed\Sales\Persistence\SpySalesOrder
564
     */
565
    protected function getSalesOrderEntity(OrderFilterTransfer $orderFilterTransfer): SpySalesOrder
566
    {
567
        $salesOrderQuery = $this->getFactory()->createSalesOrderQuery()
568
            ->setModelAlias('order')
569
            ->innerJoinWith('order.BillingAddress billingAddress')
570
            ->innerJoinWith('billingAddress.Country billingCountry')
571
            ->leftJoinWith('order.ShippingAddress shippingAddress')
572
            ->leftJoinWith('shippingAddress.Country shippingCountry');
573
        $salesOrderQuery = $this->setOrderFilters($salesOrderQuery, $orderFilterTransfer);
574
        $salesOrderQuery = $this->buildQueryFromCriteria(
575
            $salesOrderQuery,
576
            $orderFilterTransfer->getFilter(),
577
        );
578
        $salesOrderQuery->setFormatter(ModelCriteria::FORMAT_OBJECT);
579
        $orderEntity = $salesOrderQuery->findOne();
580
581
        if ($orderEntity === null) {
582
            throw new InvalidSalesOrderException(
583
                sprintf(
584
                    'Order could not be found for ID %s',
585
                    $orderFilterTransfer->getSalesOrderId(),
586
                ),
587
            );
588
        }
589
590
        return $orderEntity;
591
    }
592
593
    /**
594
     * @param \Orm\Zed\Sales\Persistence\SpySalesOrder $salesOrderEntity
595
     *
596
     * @return \Generated\Shared\Transfer\OrderTransfer
597
     */
598
    protected function createOrderTransfer(SpySalesOrder $salesOrderEntity): OrderTransfer
599
    {
600
        $orderTransfer = $this->getFactory()
601
            ->createSalesOrderMapper()
602
            ->mapSalesOrderEntityToSalesOrderTransfer($salesOrderEntity, new OrderTransfer());
603
        $orderTransfer = $this->setOrderTotals($salesOrderEntity, $orderTransfer);
604
        $orderTransfer = $this->setBillingAddress($salesOrderEntity, $orderTransfer);
605
        $orderTransfer = $this->setShippingAddress($salesOrderEntity, $orderTransfer);
606
        $orderTransfer = $this->setOrderExpenses($salesOrderEntity, $orderTransfer);
607
        $orderTransfer = $this->setMissingCustomer($salesOrderEntity, $orderTransfer);
608
609
        return $orderTransfer;
610
    }
611
612
    /**
613
     * @param \Orm\Zed\Sales\Persistence\SpySalesOrderQuery $salesOrderQuery
614
     * @param \Generated\Shared\Transfer\OrderFilterTransfer $orderFilterTransfer
615
     *
616
     * @return \Orm\Zed\Sales\Persistence\SpySalesOrderQuery
617
     */
618
    protected function setOrderFilters(SpySalesOrderQuery $salesOrderQuery, OrderFilterTransfer $orderFilterTransfer): SpySalesOrderQuery
619
    {
620
        if ($orderFilterTransfer->getSalesOrderId()) {
621
            $salesOrderQuery->filterByIdSalesOrder($orderFilterTransfer->getSalesOrderId());
622
        }
623
        if ($orderFilterTransfer->getCustomerReference()) {
624
            $salesOrderQuery->filterByCustomerReference($orderFilterTransfer->getCustomerReference());
625
        }
626
        if ($orderFilterTransfer->getOrderReference()) {
627
            $salesOrderQuery->filterByOrderReference($orderFilterTransfer->getOrderReference());
628
        }
629
630
        return $salesOrderQuery;
631
    }
632
633
    /**
634
     * @param \Orm\Zed\Sales\Persistence\SpySalesOrder $orderEntity
635
     * @param \Generated\Shared\Transfer\OrderTransfer $orderTransfer
636
     *
637
     * @return \Generated\Shared\Transfer\OrderTransfer
638
     */
639
    protected function setOrderTotals(SpySalesOrder $orderEntity, OrderTransfer $orderTransfer): OrderTransfer
640
    {
641
        $salesOrderTotalsEntity = $orderEntity->getLastOrderTotals();
642
643
        if (!$salesOrderTotalsEntity) {
644
            return $orderTransfer;
645
        }
646
647
        $totalsTransfer = $this->getFactory()
648
            ->createSalesOrderTotalsMapper()
649
            ->mapSalesOrderTotalsTransfer($salesOrderTotalsEntity, new TotalsTransfer(), new TaxTotalTransfer());
650
651
        $orderTransfer->setTotals($totalsTransfer);
652
653
        return $orderTransfer;
654
    }
655
656
    /**
657
     * @param \Orm\Zed\Sales\Persistence\SpySalesOrder $orderEntity
658
     * @param \Generated\Shared\Transfer\OrderTransfer $orderTransfer
659
     *
660
     * @return \Generated\Shared\Transfer\OrderTransfer
661
     */
662
    protected function setBillingAddress(SpySalesOrder $orderEntity, OrderTransfer $orderTransfer): OrderTransfer
663
    {
664
        $billingAddressTransfer = $this->getFactory()
665
            ->createSalesOrderAddressMapper()
666
            ->mapAddressEntityToAddressTransfer(new AddressTransfer(), $orderEntity->getBillingAddress());
667
668
        $orderTransfer->setBillingAddress($billingAddressTransfer);
669
670
        return $orderTransfer;
671
    }
672
673
    /**
674
     * @param \Orm\Zed\Sales\Persistence\SpySalesOrder $orderEntity
675
     * @param \Generated\Shared\Transfer\OrderTransfer $orderTransfer
676
     *
677
     * @return \Generated\Shared\Transfer\OrderTransfer
678
     */
679
    protected function setShippingAddress(SpySalesOrder $orderEntity, OrderTransfer $orderTransfer): OrderTransfer
680
    {
681
        $orderShippingAddressEntity = $orderEntity->getShippingAddress();
682
683
        if ($orderShippingAddressEntity === null) {
684
            return $orderTransfer;
685
        }
686
687
        $shippingAddressTransfer = $this->getFactory()
688
            ->createSalesOrderAddressMapper()
689
            ->mapAddressEntityToAddressTransfer(new AddressTransfer(), $orderShippingAddressEntity);
690
691
        $orderTransfer->setShippingAddress($shippingAddressTransfer);
692
693
        return $orderTransfer;
694
    }
695
696
    /**
697
     * @param \Orm\Zed\Sales\Persistence\SpySalesOrder $orderEntity
698
     * @param \Generated\Shared\Transfer\OrderTransfer $orderTransfer
699
     *
700
     * @return \Generated\Shared\Transfer\OrderTransfer
701
     */
702
    protected function setOrderExpenses(SpySalesOrder $orderEntity, OrderTransfer $orderTransfer): OrderTransfer
703
    {
704
        foreach ($orderEntity->getExpenses(new Criteria()) as $expenseEntity) {
705
            $expenseTransfer = $this->getFactory()
706
                ->createSalesExpenseMapper()
707
                ->mapExpenseEntityToSalesExpenseTransfer(new ExpenseTransfer(), $expenseEntity);
708
709
            $orderTransfer->addExpense($expenseTransfer);
710
        }
711
712
        return $orderTransfer;
713
    }
714
715
    /**
716
     * @param \Orm\Zed\Sales\Persistence\SpySalesOrder $orderEntity
717
     * @param \Generated\Shared\Transfer\OrderTransfer $orderTransfer
718
     *
719
     * @return \Generated\Shared\Transfer\OrderTransfer
720
     */
721
    protected function setMissingCustomer(SpySalesOrder $orderEntity, OrderTransfer $orderTransfer): OrderTransfer
722
    {
723
        if (!$orderEntity->getCustomer()) {
724
            $orderTransfer->setCustomerReference(null);
725
            $orderTransfer->setFkCustomer(null);
726
        }
727
728
        return $orderTransfer;
729
    }
730
731
    /**
732
     * @param \Orm\Zed\Sales\Persistence\SpySalesOrderQuery $salesOrderQuery
733
     * @param \Generated\Shared\Transfer\OrderCriteriaTransfer $orderCriteriaTransfer
734
     *
735
     * @return \Orm\Zed\Sales\Persistence\SpySalesOrderQuery
736
     */
737
    protected function applySalesOrderFilters(
738
        SpySalesOrderQuery $salesOrderQuery,
739
        OrderCriteriaTransfer $orderCriteriaTransfer
740
    ): SpySalesOrderQuery {
741
        $orderConditionsTransfer = $orderCriteriaTransfer->getOrderConditions();
742
        if ($orderConditionsTransfer === null) {
743
            return $salesOrderQuery;
744
        }
745
746
        if ($orderConditionsTransfer->getSalesOrderIds() !== []) {
747
            $salesOrderQuery->filterByIdSalesOrder_In($orderConditionsTransfer->getSalesOrderIds());
748
        }
749
750
        if ($orderConditionsTransfer->getOrderReferences() !== []) {
751
            $salesOrderQuery->filterByOrderReference_In($orderConditionsTransfer->getOrderReferences());
752
        }
753
754
        if ($orderConditionsTransfer->getCustomerReferences() !== []) {
755
            $salesOrderQuery->filterByCustomerReference_In($orderConditionsTransfer->getCustomerReferences());
756
        }
757
758
        return $salesOrderQuery;
759
    }
760
761
    /**
762
     * @param \Propel\Runtime\ActiveQuery\ModelCriteria $modelCriteria
763
     * @param \ArrayObject<array-key, \Generated\Shared\Transfer\SortTransfer> $sortTransfers
764
     *
765
     * @return \Propel\Runtime\ActiveQuery\ModelCriteria
766
     */
767
    protected function applySorting(
768
        ModelCriteria $modelCriteria,
769
        ArrayObject $sortTransfers
770
    ): ModelCriteria {
771
        foreach ($sortTransfers as $sortTransfer) {
772
            $modelCriteria->orderBy(
773
                $sortTransfer->getFieldOrFail(),
774
                $sortTransfer->getIsAscending() ? Criteria::ASC : Criteria::DESC,
775
            );
776
        }
777
778
        return $modelCriteria;
779
    }
780
781
    /**
782
     * @param \Propel\Runtime\ActiveQuery\ModelCriteria $modelCriteria
783
     * @param \Generated\Shared\Transfer\PaginationTransfer $paginationTransfer
784
     *
785
     * @return \Propel\Runtime\ActiveQuery\ModelCriteria
786
     */
787
    protected function applyPagination(
788
        ModelCriteria $modelCriteria,
789
        PaginationTransfer $paginationTransfer
790
    ): ModelCriteria {
791
        if ($paginationTransfer->getOffset() !== null && $paginationTransfer->getLimit() !== null) {
792
            $paginationTransfer->setNbResults($modelCriteria->count());
793
794
            return $modelCriteria
795
                ->offset($paginationTransfer->getOffsetOrFail())
796
                ->setLimit($paginationTransfer->getLimitOrFail());
797
        }
798
799
        if ($paginationTransfer->getPage() !== null && $paginationTransfer->getMaxPerPage()) {
800
            $propelModelPager = $modelCriteria->paginate(
801
                $paginationTransfer->getPageOrFail(),
802
                $paginationTransfer->getMaxPerPageOrFail(),
803
            );
804
805
            $paginationTransfer->setNbResults($propelModelPager->getNbResults())
806
                ->setFirstIndex($propelModelPager->getFirstIndex())
807
                ->setLastIndex($propelModelPager->getLastIndex())
808
                ->setFirstPage($propelModelPager->getFirstPage())
809
                ->setLastPage($propelModelPager->getLastPage())
810
                ->setNextPage($propelModelPager->getNextPage())
811
                ->setPreviousPage($propelModelPager->getPreviousPage());
812
813
            return $propelModelPager->getQuery();
814
        }
815
816
        return $modelCriteria;
817
    }
818
819
    /**
820
     * @param array<int, \Orm\Zed\Sales\Persistence\SpySalesOrder> $salesOrderEntitiesIndexedByIdSalesOrder
821
     *
822
     * @return array<int, \Orm\Zed\Sales\Persistence\SpySalesOrder>
823
     */
824
    protected function expandSalesOrdersWithSalesOrderItems(array $salesOrderEntitiesIndexedByIdSalesOrder): array
825
    {
826
        $salesOrderItemEntities = $this->getFactory()
827
            ->createSalesOrderItemQuery()
828
            ->filterByFkSalesOrder_In(array_keys($salesOrderEntitiesIndexedByIdSalesOrder))
829
            ->find();
830
831
        foreach ($salesOrderItemEntities as $salesOrderItemEntity) {
832
            $idSalesOrder = $salesOrderItemEntity->getFkSalesOrder();
833
            if (!isset($salesOrderEntitiesIndexedByIdSalesOrder[$idSalesOrder])) {
834
                continue;
835
            }
836
837
            $salesOrderEntitiesIndexedByIdSalesOrder[$idSalesOrder]->addItem($salesOrderItemEntity);
838
        }
839
840
        return $salesOrderEntitiesIndexedByIdSalesOrder;
841
    }
842
843
    /**
844
     * @param array<int, \Orm\Zed\Sales\Persistence\SpySalesOrder> $salesOrderEntitiesIndexedByIdSalesOrder
845
     *
846
     * @return array<int, \Orm\Zed\Sales\Persistence\SpySalesOrder>
847
     */
848
    protected function expandSalesOrdersWithSalesExpenses(array $salesOrderEntitiesIndexedByIdSalesOrder): array
849
    {
850
        $salesExpenseEntities = $this->getFactory()
851
            ->createSalesExpenseQuery()
852
            ->filterByFkSalesOrder_In(array_keys($salesOrderEntitiesIndexedByIdSalesOrder))
853
            ->find();
854
855
        foreach ($salesExpenseEntities as $salesExpenseEntity) {
856
            $idSalesOrder = $salesExpenseEntity->getFkSalesOrder();
857
            if (!isset($salesOrderEntitiesIndexedByIdSalesOrder[$idSalesOrder])) {
858
                continue;
859
            }
860
861
            $salesOrderEntitiesIndexedByIdSalesOrder[$idSalesOrder]->addExpense($salesExpenseEntity);
862
        }
863
864
        return $salesOrderEntitiesIndexedByIdSalesOrder;
865
    }
866
867
    /**
868
     * @param \Orm\Zed\Sales\Persistence\SpySalesExpenseQuery $salesExpenseQuery
869
     * @param \Generated\Shared\Transfer\SalesExpenseCollectionDeleteCriteriaTransfer $salesExpenseCollectionDeleteCriteriaTransfer
870
     *
871
     * @return \Orm\Zed\Sales\Persistence\SpySalesExpenseQuery
872
     */
873
    protected function appySalesExpenseCollectionDeleteCriteriaFilters(
874
        SpySalesExpenseQuery $salesExpenseQuery,
875
        SalesExpenseCollectionDeleteCriteriaTransfer $salesExpenseCollectionDeleteCriteriaTransfer
876
    ): SpySalesExpenseQuery {
877
        if ($salesExpenseCollectionDeleteCriteriaTransfer->getSalesOrderIds()) {
878
            $salesExpenseQuery->filterByFkSalesOrder_In($salesExpenseCollectionDeleteCriteriaTransfer->getSalesOrderIds());
879
        }
880
881
        if ($salesExpenseCollectionDeleteCriteriaTransfer->getTypes()) {
882
            $salesExpenseQuery->filterByType_In($salesExpenseCollectionDeleteCriteriaTransfer->getTypes());
883
        }
884
885
        return $salesExpenseQuery;
886
    }
887
}
888