Completed
Push — master ( cfa808...648607 )
by Paweł
63:01 queued 48:26
created

OrderRepository::findOneByNumberAndCustomer()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 12
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 12
rs 9.4285
cc 1
eloc 9
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
namespace Sylius\Bundle\CoreBundle\Doctrine\ORM;
13
14
use Doctrine\ORM\QueryBuilder;
15
use Sylius\Bundle\CartBundle\Doctrine\ORM\CartRepository;
16
use Sylius\Component\Core\Model\CouponInterface;
17
use Sylius\Component\Core\Model\CustomerInterface;
18
use Sylius\Component\Core\Model\OrderInterface;
19
use Sylius\Component\Core\Repository\OrderRepositoryInterface;
20
21
class OrderRepository extends CartRepository implements OrderRepositoryInterface
22
{
23
    /**
24
     * {@inheritdoc}
25
     */
26
    public function createListQueryBuilder()
27
    {
28
        $queryBuilder = $this->createQueryBuilder('o');
29
30
        return $queryBuilder
31
            ->addSelect('customer')
32
            ->leftJoin('o.customer', 'customer')
33
            ->andWhere($queryBuilder->expr()->isNotNull('o.completedAt'))
34
        ;
35
    }
36
37
    /**
38
     * {@inheritdoc}
39
     */
40
    public function createByCustomerQueryBuilder(CustomerInterface $customer)
41
    {
42
        $queryBuilder = $this->createQueryBuilder('o');
43
44
        $queryBuilder
45
            ->andWhere($queryBuilder->expr()->isNotNull('o.completedAt'))
46
            ->innerJoin('o.customer', 'customer')
47
            ->andWhere('customer = :customer')
48
            ->setParameter('customer', $customer)
49
        ;
50
51
        return $queryBuilder;
52
    }
53
54
    /**
55
     * {@inheritdoc}
56
     */
57
    public function createPaginatorByCustomer(CustomerInterface $customer, array $sorting = [])
58
    {
59
        $queryBuilder = $this->createByCustomerQueryBuilder($customer);
60
        $this->applySorting($queryBuilder, $sorting);
61
62
        return $this->getPaginator($queryBuilder);
63
    }
64
65
    /**
66
     * {@inheritdoc}
67
     */
68
    public function findByCustomer(CustomerInterface $customer, array $sorting = [])
69
    {
70
        $queryBuilder = $this->createByCustomerQueryBuilder($customer);
71
        $this->applySorting($queryBuilder, $sorting);
72
73
        return $queryBuilder
74
            ->getQuery()
75
            ->getResult()
76
        ;
77
    }
78
79
    /**
80
     * {@inheritdoc}
81
     */
82
    public function findForDetailsPage($id)
83
    {
84
        $queryBuilder = $this->createQueryBuilder('o');
85
        $queryBuilder
86
            ->leftJoin('o.adjustments', 'adjustment')
87
            ->leftJoin('o.customer', 'customer')
88
            ->leftJoin('o.items', 'item')
89
            ->leftJoin('item.units', 'itemUnit')
90
            ->leftJoin('o.shipments', 'shipment')
91
            ->leftJoin('shipment.method', 'shippingMethod')
92
            ->leftJoin('o.payments', 'payments')
93
            ->leftJoin('payments.method', 'paymentMethods')
94
            ->leftJoin('item.variant', 'variant')
95
            ->leftJoin('variant.images', 'image')
96
            ->leftJoin('variant.object', 'product')
97
            ->leftJoin('variant.options', 'optionValue')
98
            ->leftJoin('optionValue.option', 'option')
99
            ->leftJoin('o.billingAddress', 'billingAddress')
100
            ->leftJoin('o.shippingAddress', 'shippingAddress')
101
            ->addSelect('item')
102
            ->addSelect('adjustment')
103
            ->addSelect('customer')
104
            ->addSelect('itemUnit')
105
            ->addSelect('shipment')
106
            ->addSelect('shippingMethod')
107
            ->addSelect('payments')
108
            ->addSelect('paymentMethods')
109
            ->addSelect('variant')
110
            ->addSelect('image')
111
            ->addSelect('product')
112
            ->addSelect('option')
113
            ->addSelect('optionValue')
114
            ->addSelect('billingAddress')
115
            ->addSelect('shippingAddress')
116
            ->andWhere($queryBuilder->expr()->eq('o.id', ':id'))
117
            ->setParameter('id', $id)
118
        ;
119
120
        return $queryBuilder
121
            ->getQuery()
122
            ->getOneOrNullResult()
123
        ;
124
    }
125
126
    /**
127
     * {@inheritdoc}
128
     */
129
    public function createFilterPaginator(array $criteria = null, array $sorting = null)
130
    {
131
        $queryBuilder = $this->createQueryBuilder('o');
132
133
        $queryBuilder
134
            ->andWhere($queryBuilder->expr()->isNotNull('o.completedAt'))
135
            ->leftJoin('o.customer', 'customer')
136
            ->addSelect('customer')
137
        ;
138
139
        if (!empty($criteria['number'])) {
140
            $queryBuilder
141
                ->andWhere('o.number = :number')
142
                ->setParameter('number', $criteria['number'])
143
            ;
144
        }
145
        if (!empty($criteria['totalFrom'])) {
146
            $queryBuilder
147
                ->andWhere($queryBuilder->expr()->gte('o.total', ':totalFrom'))
148
                ->setParameter('totalFrom', $criteria['totalFrom'] * 100)
149
            ;
150
        }
151
        if (!empty($criteria['totalTo'])) {
152
            $queryBuilder
153
                ->andWhere($queryBuilder->expr()->lte('o.total', ':totalTo'))
154
                ->setParameter('totalTo', $criteria['totalTo'] * 100)
155
            ;
156
        }
157
        if (!empty($criteria['createdAtFrom'])) {
158
            $queryBuilder
159
                ->andWhere($queryBuilder->expr()->gte('o.createdAt', ':createdAtFrom'))
160
                ->setParameter('createdAtFrom', $criteria['createdAtFrom'])
161
            ;
162
        }
163
        if (!empty($criteria['createdAtTo'])) {
164
            $queryBuilder
165
                ->andWhere($queryBuilder->expr()->lte('o.createdAt', ':createdAtTo'))
166
                ->setParameter('createdAtTo', $criteria['createdAtTo'])
167
            ;
168
        }
169
        if (!empty($criteria['paymentState'])) {
170
            $queryBuilder
171
                ->andWhere($queryBuilder->expr()->eq('o.paymentState', ':paymentState'))
172
                ->setParameter('paymentState', $criteria['paymentState'])
173
            ;
174
        }
175
        if (!empty($criteria['channel'])) {
176
            $queryBuilder
177
                ->andWhere($queryBuilder->expr()->eq('o.channel', ':channel'))
178
                ->setParameter('channel', $criteria['channel'])
179
            ;
180
        }
181
182
        if (empty($sorting)) {
183
            if (!is_array($sorting)) {
184
                $sorting = [];
185
            }
186
            $sorting['updatedAt'] = 'desc';
187
        }
188
189
        $this->applySorting($queryBuilder, $sorting);
190
191
        return $this->getPaginator($queryBuilder);
192
    }
193
194
    /**
195
     * {@inheritdoc}
196
     */
197
    public function countByCustomerAndCoupon(CustomerInterface $customer, CouponInterface $coupon)
198
    {
199
        $queryBuilder = $this->createQueryBuilder('o')
200
            ->select('count(o.id)')
201
            ->leftJoin('o.items', 'item')
202
            ->innerJoin('o.promotionCoupon', 'coupon')
203
            ->andWhere('o.customer = :customer')
204
            ->andWhere('o.completedAt IS NOT NULL')
205
            ->andWhere('coupon = :coupon')
206
            ->setParameter('customer', $customer)
207
            ->setParameter('coupon', $coupon)
208
        ;
209
210
        $count = (int) $queryBuilder
211
            ->getQuery()
212
            ->getSingleScalarResult()
213
        ;
214
215
        return $count;
216
    }
217
218
    /**
219
     * {@inheritdoc}
220
     */
221
    public function createCheckoutsPaginator(array $criteria = null, array $sorting = null)
222
    {
223
        $queryBuilder = $this->createQueryBuilder('o');
224
        $queryBuilder->andWhere($queryBuilder->expr()->isNull('o.completedAt'));
225
226
        if (!empty($criteria['createdAtFrom'])) {
227
            $queryBuilder
228
                ->andWhere($queryBuilder->expr()->gte('o.createdAt', ':createdAtFrom'))
229
                ->setParameter('createdAtFrom', $criteria['createdAtFrom'])
230
            ;
231
        }
232
        if (!empty($criteria['createdAtTo'])) {
233
            $queryBuilder
234
                ->andWhere($queryBuilder->expr()->lte('o.createdAt', ':createdAtTo'))
235
                ->setParameter('createdAtTo', $criteria['createdAtTo'])
236
            ;
237
        }
238
        if (!empty($criteria['channel'])) {
239
            $queryBuilder
240
                ->andWhere($queryBuilder->expr()->eq('o.channel', ':channel'))
241
                ->setParameter('channel', $criteria['channel'])
242
            ;
243
        }
244
245
        if (empty($sorting)) {
246
            if (!is_array($sorting)) {
247
                $sorting = [];
248
            }
249
            $sorting['updatedAt'] = 'desc';
250
        }
251
252
        $this->applySorting($queryBuilder, $sorting);
253
254
        return $this->getPaginator($queryBuilder);
255
    }
256
257
    /**
258
     * {@inheritdoc}
259
     */
260
    public function countByCustomerAndPaymentState(CustomerInterface $customer, $state)
261
    {
262
        $queryBuilder = $this->createByCustomerQueryBuilder($customer);
263
264
        $queryBuilder
265
            ->select('count(o.id)')
266
            ->andWhere('o.paymentState = :state')
267
            ->setParameter('state', $state)
268
        ;
269
270
        return (int) $queryBuilder
271
            ->getQuery()
272
            ->getSingleScalarResult()
273
        ;
274
    }
275
276
    /**
277
     * {@inheritdoc}
278
     */
279
    public function findBetweenDates(\DateTime $from, \DateTime $to, $state = null)
280
    {
281
        $queryBuilder = $this->createQueryBuilderBetweenDates($from, $to, $state);
282
283
        return $queryBuilder
284
            ->getQuery()
285
            ->getResult()
286
        ;
287
    }
288
289
    /**
290
     * {@inheritdoc}
291
     */
292
    public function countBetweenDates(\DateTime $from, \DateTime $to, $state = null)
293
    {
294
        $queryBuilder = $this->createQueryBuilderBetweenDates($from, $to, $state);
295
296
        return (int) $queryBuilder
297
            ->select('count(o.id)')
298
            ->getQuery()
299
            ->getSingleScalarResult()
300
        ;
301
    }
302
303
    /**
304
     * {@inheritdoc}
305
     */
306
    public function revenueBetweenDates(\DateTime $from, \DateTime $to, $state = null)
307
    {
308
        $queryBuilder = $this->createQueryBuilderBetweenDates($from, $to, $state);
309
310
        return (int) $queryBuilder
311
            ->select('sum(o.total)')
312
            ->getQuery()
313
            ->getSingleScalarResult()
314
        ;
315
    }
316
317
    /**
318
     * {@inheritdoc}
319
     */
320
    public function revenueBetweenDatesGroupByDate(array $configuration = [])
321
    {
322
        $groupBy = '';
323
        foreach ($configuration['groupBy'] as $groupByArray) {
324
            $groupBy = $groupByArray.'(date)'.' '.$groupBy;
325
        }
326
        $groupBy = substr($groupBy, 0, -1);
327
        $groupBy = str_replace(' ', ', ', $groupBy);
328
329
        $queryBuilder = $this->getEntityManager()->getConnection()->createQueryBuilder();
330
331
        $queryBuilder
332
            ->select('DATE(o.completed_at) as date', 'COUNT(o.id) as "Number of orders"')
333
            ->from($this->getClassMetadata($this->_entityName)->getTableName(), 'o')
0 ignored issues
show
Unused Code introduced by
The call to OrderRepository::getClassMetadata() has too many arguments starting with $this->_entityName.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
334
            ->where($queryBuilder->expr()->gte('o.completed_at', ':from'))
335
            ->andWhere($queryBuilder->expr()->lte('o.completed_at', ':to'))
336
            ->setParameter('from', $configuration['start']->format('Y-m-d H:i:s'))
337
            ->setParameter('to', $configuration['end']->format('Y-m-d H:i:s'))
338
            ->groupBy($groupBy)
339
            ->orderBy($groupBy)
340
        ;
341
342
        $baseCurrencyCode = $configuration['baseCurrency'] ? 'in '.$configuration['baseCurrency']->getCode() : '';
343
        $queryBuilder
344
            ->select('DATE(o.completed_at) as date', 'TRUNCATE(SUM(o.total * o.exchange_rate)/ 100,2) as "total sum '.$baseCurrencyCode.'"')
345
        ;
346
347
        return $queryBuilder
348
            ->execute()
349
            ->fetchAll()
350
        ;
351
    }
352
353
    /**
354
     * {@inheritdoc}
355
     */
356
    public function ordersBetweenDatesGroupByDate(array $configuration = [])
357
    {
358
        $groupBy = '';
359
360
        foreach ($configuration['groupBy'] as $groupByElement) {
361
            $groupBy = $groupByElement.'(date)'.' '.$groupBy;
362
        }
363
364
        $groupBy = substr($groupBy, 0, -1);
365
        $groupBy = str_replace(' ', ', ', $groupBy);
366
367
        $queryBuilder = $this->getEntityManager()->getConnection()->createQueryBuilder();
368
369
        $queryBuilder
370
            ->select('DATE(o.completed_at) as date', 'COUNT(o.id) as "Number of orders"')
371
            ->from($this->getClassMetadata($this->_entityName)->getTableName(), 'o')
0 ignored issues
show
Unused Code introduced by
The call to OrderRepository::getClassMetadata() has too many arguments starting with $this->_entityName.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
372
            ->where($queryBuilder->expr()->gte('o.completed_at', ':from'))
373
            ->andWhere($queryBuilder->expr()->lte('o.completed_at', ':to'))
374
            ->setParameter('from', $configuration['start']->format('Y-m-d H:i:s'))
375
            ->setParameter('to', $configuration['end']->format('Y-m-d H:i:s'))
376
            ->groupBy($groupBy)
377
            ->orderBy($groupBy)
378
        ;
379
380
        return $queryBuilder
381
            ->execute()
382
            ->fetchAll()
383
        ;
384
    }
385
386
    /**
387
     * {@inheritdoc}
388
     */
389
    public function findExpired(\DateTime $expiresAt, $state = OrderInterface::STATE_PENDING)
390
    {
391
        $queryBuilder = $this->createQueryBuilder('o')
392
            ->leftJoin('o.items', 'item')
393
            ->addSelect('item')
394
        ;
395
396
        $queryBuilder
397
            ->andWhere($queryBuilder->expr()->lt('o.expiresAt', ':expiresAt'))
398
            ->andWhere('o.state = :state')
399
            ->setParameter('expiresAt', $expiresAt)
400
            ->setParameter('state', $state)
401
        ;
402
403
        return $queryBuilder->getQuery()->getResult();
404
    }
405
406
    /**
407
     * {@inheritdoc}
408
     */
409
    public function findCompleted(array $sorting = [], $limit = 5)
410
    {
411
        $queryBuilder = $this->createQueryBuilder('o');
412
        $queryBuilder->andWhere($queryBuilder->expr()->isNotNull('o.completedAt'));
413
414
        $this->applySorting($queryBuilder, $sorting);
415
416
        return $queryBuilder
417
            ->setMaxResults($limit)
418
            ->getQuery()
419
            ->getResult()
420
        ;
421
    }
422
423
    /**
424
     * {@inheritdoc}
425
     */
426
    public function findOneByNumberAndCustomer($number, CustomerInterface $customer)
427
    {
428
        return $this->createQueryBuilder('o')
429
            ->leftJoin('o.customer', 'customer')
430
            ->andWhere('customer = :customer')
431
            ->andWhere('o.number = :number')
432
            ->setParameter('customer', $customer)
433
            ->setParameter('number', $number)
434
            ->getQuery()
435
            ->getOneOrNullResult()
436
        ;
437
    }
438
439
    /**
440
     * @param \DateTime $from
441
     * @param \DateTime $to
442
     * @param string $state
443
     *
444
     * @return QueryBuilder
445
     */
446
    private function createQueryBuilderBetweenDates(\DateTime $from, \DateTime $to, $state)
447
    {
448
        $queryBuilder = $this->createQueryBuilder('o');
449
450
        if (null !== $state) {
451
            $queryBuilder->andWhere('o.state = :state')->setParameter('state', $state);
452
        }
453
454
        $queryBuilder
455
            ->andWhere($queryBuilder->expr()->isNotNull('o.completedAt'))
456
            ->andWhere($queryBuilder->expr()->gte('o.createdAt', ':from'))
457
            ->andWhere($queryBuilder->expr()->lte('o.createdAt', ':to'))
458
            ->setParameter('from', $from)
459
            ->setParameter('to', $to)
460
        ;
461
462
        return $queryBuilder;
463
    }
464
}
465