Completed
Push — master ( 2d49a9...7faf52 )
by Paweł
85:44 queued 75:35
created

createByCustomerAndChannelIdQueryBuilder()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 11
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 8
nc 1
nop 2
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\Bundle\CoreBundle\Doctrine\ORM;
15
16
use Doctrine\ORM\EntityManager;
17
use Doctrine\ORM\Mapping;
18
use Doctrine\ORM\QueryBuilder;
19
use Sylius\Bundle\OrderBundle\Doctrine\ORM\OrderRepository as BaseOrderRepository;
20
use Sylius\Component\Core\Model\ChannelInterface;
21
use Sylius\Component\Core\Model\CustomerInterface;
22
use Sylius\Component\Core\Model\OrderInterface;
23
use Sylius\Component\Core\Model\PromotionCouponInterface;
24
use Sylius\Component\Core\OrderCheckoutStates;
25
use Sylius\Component\Core\OrderPaymentStates;
26
use Sylius\Component\Core\Repository\OrderRepositoryInterface;
27
use SyliusLabs\AssociationHydrator\AssociationHydrator;
28
29
class OrderRepository extends BaseOrderRepository implements OrderRepositoryInterface
30
{
31
    /**
32
     * @var AssociationHydrator
33
     */
34
    protected $associationHydrator;
35
36
    /**
37
     * {@inheritdoc}
38
     */
39
    public function __construct(EntityManager $entityManager, Mapping\ClassMetadata $class)
40
    {
41
        parent::__construct($entityManager, $class);
42
43
        $this->associationHydrator = new AssociationHydrator($entityManager, $class);
44
    }
45
46
    /**
47
     * {@inheritdoc}
48
     */
49
    public function createListQueryBuilder(): QueryBuilder
50
    {
51
        return $this->createQueryBuilder('o')
52
            ->addSelect('channel')
53
            ->addSelect('customer')
54
            ->innerJoin('o.channel', 'channel')
55
            ->leftJoin('o.customer', 'customer')
56
            ->andWhere('o.state != :state')
57
            ->setParameter('state', OrderInterface::STATE_CART)
58
        ;
59
    }
60
61
    /**
62
     * {@inheritdoc}
63
     */
64
    public function createByCustomerIdQueryBuilder($customerId): QueryBuilder
65
    {
66
        return $this->createQueryBuilder('o')
67
            ->andWhere('o.customer = :customerId')
68
            ->andWhere('o.state != :state')
69
            ->setParameter('customerId', $customerId)
70
            ->setParameter('state', OrderInterface::STATE_CART)
71
        ;
72
    }
73
74
    /**
75
     * {@inheritdoc}
76
     */
77
    public function createByCustomerAndChannelIdQueryBuilder($customerId, $channelId): QueryBuilder
78
    {
79
        return $this->createQueryBuilder('o')
80
            ->andWhere('o.customer = :customerId')
81
            ->andWhere('o.channel = :channelId')
82
            ->andWhere('o.state != :state')
83
            ->setParameter('customerId', $customerId)
84
            ->setParameter('channelId', $channelId)
85
            ->setParameter('state', OrderInterface::STATE_CART)
86
        ;
87
    }
88
89
    /**
90
     * {@inheritdoc}
91
     */
92
    public function findByCustomer(CustomerInterface $customer): array
93
    {
94
        return $this->createByCustomerIdQueryBuilder($customer->getId())
95
            ->getQuery()
96
            ->getResult()
97
        ;
98
    }
99
100
    /**
101
     * {@inheritdoc}
102
     */
103
    public function findForCustomerStatistics(CustomerInterface $customer): array
104
    {
105
106
        return $this->createQueryBuilder('o')
107
            ->andWhere('o.customer = :customerId')
108
            ->andWhere('o.state = :state')
109
            ->setParameter('customerId', $customer->getId())
110
            ->setParameter('state', OrderInterface::STATE_FULFILLED)
111
            ->getQuery()
112
            ->getResult()
113
        ;
114
    }
115
116
    /**
117
     * {@inheritdoc}
118
     */
119
    public function findOneForPayment($id): ?OrderInterface
120
    {
121
        return $this->createQueryBuilder('o')
122
            ->addSelect('payments')
123
            ->addSelect('paymentMethods')
124
            ->leftJoin('o.payments', 'payments')
125
            ->leftJoin('payments.method', 'paymentMethods')
126
            ->andWhere('o.id = :id')
127
            ->setParameter('id', $id)
128
            ->getQuery()
129
            ->getOneOrNullResult()
130
        ;
131
    }
132
133
    /**
134
     * {@inheritdoc}
135
     */
136
    public function countByCustomerAndCoupon(CustomerInterface $customer, PromotionCouponInterface $coupon): int
137
    {
138
        return (int) $this->createQueryBuilder('o')
139
            ->select('COUNT(o.id)')
140
            ->andWhere('o.customer = :customer')
141
            ->andWhere('o.promotionCoupon = :coupon')
142
            ->andWhere('o.state NOT IN (:states)')
143
            ->setParameter('customer', $customer)
144
            ->setParameter('coupon', $coupon)
145
            ->setParameter('states', [OrderInterface::STATE_CART, OrderInterface::STATE_CANCELLED])
146
            ->getQuery()
147
            ->getSingleScalarResult()
148
        ;
149
    }
150
151
    /**
152
     * {@inheritdoc}
153
     */
154
    public function countByCustomer(CustomerInterface $customer): int
155
    {
156
        return (int) $this->createQueryBuilder('o')
157
            ->select('COUNT(o.id)')
158
            ->andWhere('o.customer = :customer')
159
            ->andWhere('o.state NOT IN (:states)')
160
            ->setParameter('customer', $customer)
161
            ->setParameter('states', [OrderInterface::STATE_CART, OrderInterface::STATE_CANCELLED])
162
            ->getQuery()
163
            ->getSingleScalarResult()
164
        ;
165
    }
166
167
    /**
168
     * {@inheritdoc}
169
     */
170
    public function findOneByNumberAndCustomer(string $number, CustomerInterface $customer): ?OrderInterface
171
    {
172
        return $this->createQueryBuilder('o')
173
            ->andWhere('o.customer = :customer')
174
            ->andWhere('o.number = :number')
175
            ->setParameter('customer', $customer)
176
            ->setParameter('number', $number)
177
            ->getQuery()
178
            ->getOneOrNullResult()
179
        ;
180
    }
181
182
    /**
183
     * {@inheritdoc}
184
     */
185
    public function findCartByChannel($id, ChannelInterface $channel): ?OrderInterface
186
    {
187
        return $this->createQueryBuilder('o')
188
            ->andWhere('o.id = :id')
189
            ->andWhere('o.state = :state')
190
            ->andWhere('o.channel = :channel')
191
            ->setParameter('id', $id)
192
            ->setParameter('state', OrderInterface::STATE_CART)
193
            ->setParameter('channel', $channel)
194
            ->getQuery()
195
            ->getOneOrNullResult()
196
        ;
197
    }
198
199
    /**
200
     * {@inheritdoc}
201
     */
202
    public function findLatestCartByChannelAndCustomer(ChannelInterface $channel, CustomerInterface $customer): ?OrderInterface
203
    {
204
        return $this->createQueryBuilder('o')
205
            ->andWhere('o.state = :state')
206
            ->andWhere('o.channel = :channel')
207
            ->andWhere('o.customer = :customer')
208
            ->setParameter('state', OrderInterface::STATE_CART)
209
            ->setParameter('channel', $channel)
210
            ->setParameter('customer', $customer)
211
            ->addOrderBy('o.createdAt', 'DESC')
212
            ->setMaxResults(1)
213
            ->getQuery()
214
            ->getOneOrNullResult()
215
        ;
216
    }
217
218
    /**
219
     * {@inheritdoc}
220
     */
221
    public function getTotalSalesForChannel(ChannelInterface $channel): int
222
    {
223
        return (int) $this->createQueryBuilder('o')
224
            ->select('SUM(o.total)')
225
            ->andWhere('o.channel = :channel')
226
            ->andWhere('o.state = :state')
227
            ->setParameter('channel', $channel)
228
            ->setParameter('state', OrderInterface::STATE_FULFILLED)
229
            ->getQuery()
230
            ->getSingleScalarResult()
231
        ;
232
    }
233
234
    /**
235
     * {@inheritdoc}
236
     */
237
    public function countFulfilledByChannel(ChannelInterface $channel): int
238
    {
239
        return (int) $this->createQueryBuilder('o')
240
            ->select('COUNT(o.id)')
241
            ->andWhere('o.channel = :channel')
242
            ->andWhere('o.state = :state')
243
            ->setParameter('channel', $channel)
244
            ->setParameter('state', OrderInterface::STATE_FULFILLED)
245
            ->getQuery()
246
            ->getSingleScalarResult()
247
        ;
248
    }
249
250
    /**
251
     * {@inheritdoc}
252
     */
253
    public function findLatestInChannel(int $count, ChannelInterface $channel): array
254
    {
255
        return $this->createQueryBuilder('o')
256
            ->andWhere('o.channel = :channel')
257
            ->andWhere('o.state != :state')
258
            ->addOrderBy('o.checkoutCompletedAt', 'DESC')
259
            ->setParameter('channel', $channel)
260
            ->setParameter('state', OrderInterface::STATE_CART)
261
            ->setMaxResults($count)
262
            ->getQuery()
263
            ->getResult()
264
        ;
265
    }
266
267
    /**
268
     * {@inheritdoc}
269
     */
270
    public function findOrdersUnpaidSince(\DateTimeInterface $terminalDate): array
271
    {
272
        return $this->createQueryBuilder('o')
273
            ->where('o.checkoutState = :checkoutState')
274
            ->andWhere('o.paymentState != :paymentState')
275
            ->andWhere('o.state = :orderState')
276
            ->andWhere('o.checkoutCompletedAt < :terminalDate')
277
            ->setParameter('checkoutState', OrderCheckoutStates::STATE_COMPLETED)
278
            ->setParameter('paymentState', OrderPaymentStates::STATE_PAID)
279
            ->setParameter('orderState', OrderInterface::STATE_NEW)
280
            ->setParameter('terminalDate', $terminalDate)
281
            ->getQuery()
282
            ->getResult()
283
        ;
284
    }
285
286
    /**
287
     * {@inheritdoc}
288
     */
289
    public function findCartForSummary($id): ?OrderInterface
290
    {
291
        /** @var OrderInterface $order */
292
        $order = $this->createQueryBuilder('o')
293
            ->andWhere('o.id = :id')
294
            ->andWhere('o.state = :state')
295
            ->setParameter('id', $id)
296
            ->setParameter('state', OrderInterface::STATE_CART)
297
            ->getQuery()
298
            ->getOneOrNullResult()
299
        ;
300
301
        $this->associationHydrator->hydrateAssociations($order, [
302
            'adjustments',
303
            'items',
304
            'items.adjustments',
305
            'items.units',
306
            'items.units.adjustments',
307
            'items.variant',
308
            'items.variant.optionValues',
309
            'items.variant.optionValues.translations',
310
            'items.variant.product',
311
            'items.variant.product.translations',
312
            'items.variant.product.images',
313
            'items.variant.product.options',
314
            'items.variant.product.options.translations',
315
        ]);
316
317
        return $order;
318
    }
319
320
    /**
321
     * {@inheritdoc}
322
     */
323
    public function findCartForAddressing($id): ?OrderInterface
324
    {
325
        /** @var OrderInterface $order */
326
        $order = $this->createQueryBuilder('o')
327
            ->andWhere('o.id = :id')
328
            ->andWhere('o.state = :state')
329
            ->setParameter('id', $id)
330
            ->setParameter('state', OrderInterface::STATE_CART)
331
            ->getQuery()
332
            ->getOneOrNullResult()
333
        ;
334
335
        $this->associationHydrator->hydrateAssociations($order, [
336
            'items',
337
            'items.variant',
338
            'items.variant.product',
339
            'items.variant.product.translations',
340
        ]);
341
342
        return $order;
343
    }
344
345
    /**
346
     * {@inheritdoc}
347
     */
348
    public function findCartForSelectingShipping($id): ?OrderInterface
349
    {
350
        /** @var OrderInterface $order */
351
        $order = $this->createQueryBuilder('o')
352
            ->andWhere('o.id = :id')
353
            ->andWhere('o.state = :state')
354
            ->setParameter('id', $id)
355
            ->setParameter('state', OrderInterface::STATE_CART)
356
            ->getQuery()
357
            ->getOneOrNullResult()
358
        ;
359
360
        $this->associationHydrator->hydrateAssociations($order, [
361
            'items',
362
            'items.variant',
363
            'items.variant.product',
364
            'items.variant.product.translations',
365
        ]);
366
367
        return $order;
368
    }
369
370
    /**
371
     * {@inheritdoc}
372
     */
373
    public function findCartForSelectingPayment($id): ?OrderInterface
374
    {
375
        /** @var OrderInterface $order */
376
        $order = $this->createQueryBuilder('o')
377
            ->andWhere('o.id = :id')
378
            ->andWhere('o.state = :state')
379
            ->setParameter('id', $id)
380
            ->setParameter('state', OrderInterface::STATE_CART)
381
            ->getQuery()
382
            ->getOneOrNullResult()
383
        ;
384
385
        $this->associationHydrator->hydrateAssociations($order, [
386
            'items',
387
            'items.variant',
388
            'items.variant.product',
389
            'items.variant.product.translations',
390
        ]);
391
392
        return $order;
393
    }
394
}
395