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