LeadRepository::processOpportunitiesByLeadSource()   D
last analyzed

Complexity

Conditions 9
Paths 45

Size

Total Lines 43
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 43
rs 4.909
c 0
b 0
f 0
cc 9
eloc 25
nc 45
nop 2
1
<?php
2
3
namespace Oro\Bundle\SalesBundle\Entity\Repository;
4
5
use Doctrine\ORM\EntityRepository;
6
use Doctrine\ORM\QueryBuilder;
7
8
use Oro\Component\DoctrineUtils\ORM\QueryUtils;
9
use Oro\Bundle\SecurityBundle\ORM\Walker\AclHelper;
10
11
class LeadRepository extends EntityRepository
12
{
13
    /**
14
     * Returns top $limit opportunities grouped by lead source
15
     *
16
     * @deprecated since 1.10. Use OpportunityRepository::getOpportunitiesCountGroupByLeadSource instead
17
     * @see        OpportunityRepository::getOpportunitiesCountGroupByLeadSource
18
     *
19
     * @param  AclHelper $aclHelper
20
     * @param  int       $limit
21
     * @param  array     $dateRange
22
     *
23
     * @return array     [itemCount, label]
24
     */
25
    public function getOpportunitiesByLeadSource(AclHelper $aclHelper, $limit = 10, $dateRange = null, $owners = [])
26
    {
27
        $qb = $this->createQueryBuilder('l')
28
            ->select('s.id as source, count(o.id) as itemCount')
29
            ->leftJoin('l.opportunities', 'o')
30
            ->leftJoin('l.source', 's')
31
            ->groupBy('source');
32
33
        if ($dateRange && $dateRange['start'] && $dateRange['end']) {
34
            $qb->andWhere($qb->expr()->between('o.createdAt', ':dateStart', ':dateEnd'))
35
                ->setParameter('dateStart', $dateRange['start'])
36
                ->setParameter('dateEnd', $dateRange['end']);
37
        }
38
        if ($owners) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $owners of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
39
            QueryUtils::applyOptimizedIn($qb, 'o.owner', $owners);
40
        }
41
42
        $rows = $aclHelper->apply($qb)->getArrayResult();
43
44
        return $this->processOpportunitiesByLeadSource($rows, $limit);
0 ignored issues
show
Deprecated Code introduced by
The method Oro\Bundle\SalesBundle\E...rtunitiesByLeadSource() has been deprecated with message: since 1.10. Used by deprecated getOpportunitiesByLeadSource

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
45
    }
46
47
    /**
48
     * @deprecated since 1.10. Used by deprecated getOpportunitiesByLeadSource
49
     * @see        LeadRepository::getOpportunitiesByLeadSource
50
     *
51
     * @param array $rows
52
     * @param int   $limit
53
     *
54
     * @return array
55
     */
56
    protected function processOpportunitiesByLeadSource(array $rows, $limit)
57
    {
58
        $result       = [];
59
        $unclassified = null;
60
        $others       = [];
61
62
        $this->sortByCountReverse($rows);
0 ignored issues
show
Deprecated Code introduced by
The method Oro\Bundle\SalesBundle\E...y::sortByCountReverse() has been deprecated with message: since 1.10. Used by deprecated getOpportunitiesByLeadSource

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
63
        foreach ($rows as $row) {
64
            if ($row['itemCount']) {
65
                if ($row['source'] === null) {
66
                    $unclassified = $row;
67
                } else {
68
                    if (count($result) < $limit) {
69
                        $result[] = $row;
70
                    } else {
71
                        $others[] = $row;
72
                    }
73
                }
74
            }
75
        }
76
77
        if ($unclassified) {
78
            if (count($result) === $limit) {
79
                // allocate space for 'unclassified' item
80
                array_unshift($others, array_pop($result));
81
            }
82
            // add 'unclassified' item to the top to avoid moving it to $others
83
            array_unshift($result, $unclassified);
84
        }
85
        if (!empty($others)) {
86
            if (count($result) === $limit) {
87
                // allocate space for 'others' item
88
                array_unshift($others, array_pop($result));
89
            }
90
            // add 'others' item
91
            $result[] = [
92
                'source'    => '',
93
                'itemCount' => $this->sumCount($others)
0 ignored issues
show
Deprecated Code introduced by
The method Oro\Bundle\SalesBundle\E...dRepository::sumCount() has been deprecated with message: since 1.10. Used by deprecated getOpportunitiesByLeadSource

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
94
            ];
95
        }
96
97
        return $result;
98
    }
99
100
    /**
101
     * @deprecated since 1.10. Used by deprecated getOpportunitiesByLeadSource
102
     * @see        LeadRepository::getOpportunitiesByLeadSource
103
     *
104
     * @param array $rows
105
     *
106
     * @return int
107
     */
108
    protected function sumCount(array $rows)
109
    {
110
        $result = 0;
111
        foreach ($rows as $row) {
112
            $result += $row['itemCount'];
113
        }
114
115
        return $result;
116
    }
117
118
    /**
119
     * @deprecated since 1.10. Used by deprecated getOpportunitiesByLeadSource
120
     * @see        LeadRepository::getOpportunitiesByLeadSource
121
     *
122
     * @param array $rows
123
     */
124
    protected function sortByCountReverse(array &$rows)
125
    {
126
        usort(
127
            $rows,
128 View Code Duplication
            function ($a, $b) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
129
                if ($a['itemCount'] === $b['itemCount']) {
130
                    return 0;
131
                }
132
133
                return $a['itemCount'] < $b['itemCount'] ? 1 : -1;
134
            }
135
        );
136
    }
137
138
    /**
139
     * @param AclHelper $aclHelper
140
     * @param \DateTime $start
141
     * @param \DateTime $end
142
     * @param int[] $owners
143
     *
144
     * @return int
145
     */
146
    public function getLeadsCount(AclHelper $aclHelper, \DateTime $start = null, \DateTime $end = null, $owners = [])
147
    {
148
        $qb = $this
149
            ->createLeadsCountQb($start, $end, $owners)
150
            ->innerJoin('l.opportunities', 'o');
151
152
        return $aclHelper->apply($qb)->getSingleScalarResult();
153
    }
154
155
    /**
156
     * @param AclHelper $aclHelper
157
     * @param \DateTime $start
158
     * @param \DateTime $end
159
     * @param int[] $owners
160
     *
161
     * @return int
162
     */
163
    public function getNewLeadsCount(AclHelper $aclHelper, \DateTime $start = null, \DateTime $end = null, $owners = [])
164
    {
165
        $qb = $this->createLeadsCountQb($start, $end, $owners);
166
167
        return $aclHelper->apply($qb)->getSingleScalarResult();
168
    }
169
170
    /**
171
     * @param AclHelper $aclHelper
172
     * @param int[] $owners
173
     *
174
     * @return int
175
     */
176
    public function getOpenLeadsCount(AclHelper $aclHelper, $owners = [])
177
    {
178
        $qb = $this->createLeadsCountQb(null, null, $owners);
179
        $qb->andWhere(
180
            $qb->expr()->notIn('l.status', ['qualified', 'canceled'])
181
        );
182
183
        return $aclHelper->apply($qb)->getSingleScalarResult();
184
    }
185
186
    /**
187
     * @param \DateTime $start
188
     * @param \DateTime $end
189
     * @param int[] $owners
190
     *
191
     * @return QueryBuilder
192
     */
193 View Code Duplication
    protected function createLeadsCountQb(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
194
        \DateTime $start = null,
195
        \DateTime $end = null,
196
        $owners = []
197
    ) {
198
        $qb = $this
199
            ->createQueryBuilder('l')
200
            ->select('COUNT(DISTINCT l.id)');
201
202
        if ($start) {
203
            $qb
204
                ->andWhere('l.createdAt > :start')
205
                ->setParameter('start', $start);
206
        }
207
        if ($end) {
208
            $qb
209
                ->andWhere('l.createdAt < :end')
210
                ->setParameter('end', $end);
211
        }
212
213
        if ($owners) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $owners of type integer[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
214
            QueryUtils::applyOptimizedIn($qb, 'l.owner', $owners);
215
        }
216
217
        return $qb;
218
    }
219
}
220