1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace OroCRM\Bundle\MagentoBundle\Provider; |
4
|
|
|
|
5
|
|
|
use Doctrine\ORM\QueryBuilder; |
6
|
|
|
|
7
|
|
|
use Symfony\Bridge\Doctrine\RegistryInterface; |
8
|
|
|
|
9
|
|
|
use Oro\Bundle\DashboardBundle\Provider\BigNumber\BigNumberDateHelper; |
10
|
|
|
use Oro\Bundle\SecurityBundle\ORM\Walker\AclHelper; |
11
|
|
|
|
12
|
|
|
use OroCRM\Bundle\MagentoBundle\Entity\Repository\OrderRepository; |
13
|
|
|
use OroCRM\Bundle\ChannelBundle\Entity\Repository\ChannelRepository; |
14
|
|
|
use OroCRM\Bundle\MagentoBundle\Entity\Repository\CartRepository; |
15
|
|
|
use OroCRM\Bundle\MagentoBundle\Entity\Repository\CustomerRepository; |
16
|
|
|
|
17
|
|
|
class MagentoBigNumberProvider |
18
|
|
|
{ |
19
|
|
|
/** @var RegistryInterface */ |
20
|
|
|
protected $doctrine; |
21
|
|
|
|
22
|
|
|
/** @var AclHelper */ |
23
|
|
|
protected $aclHelper; |
24
|
|
|
|
25
|
|
|
/** @var BigNumberDateHelper */ |
26
|
|
|
protected $dateHelper; |
27
|
|
|
|
28
|
|
|
/** @var ChannelRepository */ |
29
|
|
|
protected $channelRepository; |
30
|
|
|
|
31
|
|
|
/** |
32
|
|
|
* @param RegistryInterface $doctrine |
33
|
|
|
* @param AclHelper $aclHelper |
34
|
|
|
* @param BigNumberDateHelper $dateHelper |
35
|
|
|
* @param ChannelRepository $channelRepository |
36
|
|
|
*/ |
37
|
|
|
public function __construct( |
38
|
|
|
RegistryInterface $doctrine, |
39
|
|
|
AclHelper $aclHelper, |
40
|
|
|
BigNumberDateHelper $dateHelper, |
41
|
|
|
ChannelRepository $channelRepository |
42
|
|
|
) { |
43
|
|
|
$this->doctrine = $doctrine; |
44
|
|
|
$this->aclHelper = $aclHelper; |
45
|
|
|
$this->dateHelper = $dateHelper; |
46
|
|
|
$this->channelRepository = $channelRepository; |
47
|
|
|
} |
48
|
|
|
|
49
|
|
|
/** |
50
|
|
|
* @param array $dateRange |
51
|
|
|
* |
52
|
|
|
* @return int |
53
|
|
|
*/ |
54
|
|
|
public function getRevenueValues($dateRange) |
55
|
|
|
{ |
56
|
|
|
list($start, $end) = $this->dateHelper->getPeriod($dateRange, 'OroCRMMagentoBundle:Order', 'createdAt'); |
57
|
|
|
|
58
|
|
|
$qb = $this->getOrderRepository()->getRevenueValueQB(); |
59
|
|
|
$this->applyDateFiltering($qb, 'orders.createdAt', $start, $end); |
60
|
|
|
$value = $this->aclHelper->apply($qb)->getOneOrNullResult(); |
61
|
|
|
|
62
|
|
|
return $value['val'] ? : 0; |
63
|
|
|
} |
64
|
|
|
|
65
|
|
|
/** |
66
|
|
|
* @param array $dateRange |
67
|
|
|
* |
68
|
|
|
* @return int |
69
|
|
|
*/ |
70
|
|
View Code Duplication |
public function getOrdersNumberValues($dateRange) |
|
|
|
|
71
|
|
|
{ |
72
|
|
|
list($start, $end) = $this->dateHelper->getPeriod($dateRange, 'OroCRMMagentoBundle:Order', 'createdAt'); |
73
|
|
|
$qb = $this->getOrderRepository()->getOrdersNumberValueQB(); |
74
|
|
|
$this->applyDateFiltering($qb, 'o.createdAt', $start, $end); |
75
|
|
|
$value = $this->aclHelper->apply($qb)->getOneOrNullResult(); |
76
|
|
|
|
77
|
|
|
return $value['val'] ? : 0; |
78
|
|
|
} |
79
|
|
|
|
80
|
|
|
/** |
81
|
|
|
* @param array $dateRange |
82
|
|
|
* |
83
|
|
|
* @return int |
84
|
|
|
*/ |
85
|
|
|
public function getAOVValues($dateRange) |
86
|
|
|
{ |
87
|
|
|
list($start, $end) = $this->dateHelper->getPeriod($dateRange, 'OroCRMMagentoBundle:Order', 'createdAt'); |
88
|
|
|
|
89
|
|
|
$qb = $this->getOrderRepository()->getAOVValueQB(); |
90
|
|
|
$this->applyDateFiltering($qb, 'o.createdAt', $start, $end); |
91
|
|
|
$value = $this->aclHelper->apply($qb)->getOneOrNullResult(); |
92
|
|
|
|
93
|
|
|
return $value['ordersCount'] ? $value['revenue'] / $value['ordersCount'] : 0; |
94
|
|
|
} |
95
|
|
|
|
96
|
|
|
/** |
97
|
|
|
* @param array $dateRange |
98
|
|
|
* |
99
|
|
|
* @return float |
100
|
|
|
*/ |
101
|
|
|
public function getDiscountedOrdersPercentValues($dateRange) |
102
|
|
|
{ |
103
|
|
|
list($start, $end) = $this->dateHelper->getPeriod($dateRange, 'OroCRMMagentoBundle:Order', 'createdAt'); |
104
|
|
|
$qb = $this->getOrderRepository()->getDiscountedOrdersPercentQB(); |
105
|
|
|
$this->applyDateFiltering($qb, 'o.createdAt', $start, $end); |
106
|
|
|
$value = $this->aclHelper->apply($qb)->getOneOrNullResult(); |
107
|
|
|
|
108
|
|
|
return $value['allOrders'] ? $value['discounted'] / $value['allOrders'] : 0; |
109
|
|
|
} |
110
|
|
|
|
111
|
|
|
/** |
112
|
|
|
* @param array $dateRange |
113
|
|
|
* |
114
|
|
|
* @return int |
115
|
|
|
*/ |
116
|
|
View Code Duplication |
public function getNewCustomersCountValues($dateRange) |
|
|
|
|
117
|
|
|
{ |
118
|
|
|
list($start, $end) = $this->dateHelper->getPeriod($dateRange, 'OroCRMMagentoBundle:Customer', 'createdAt'); |
119
|
|
|
$qb = $this->getCustomerRepository()->getNewCustomersNumberWhoMadeOrderQB(); |
120
|
|
|
$this->applyDateFiltering($qb, 'orders.createdAt', $start, $end); |
121
|
|
|
$this->applyDateFiltering($qb, 'customer.createdAt', $start, $end); |
122
|
|
|
$value = $this->aclHelper->apply($qb)->getOneOrNullResult(); |
123
|
|
|
|
124
|
|
|
return $value['val'] ? : 0; |
125
|
|
|
} |
126
|
|
|
|
127
|
|
|
/** |
128
|
|
|
* @param array $dateRange |
129
|
|
|
* |
130
|
|
|
* @return int |
131
|
|
|
*/ |
132
|
|
View Code Duplication |
public function getReturningCustomersCountValues($dateRange) |
|
|
|
|
133
|
|
|
{ |
134
|
|
|
list($start, $end) = $this->dateHelper->getPeriod($dateRange, 'OroCRMMagentoBundle:Customer', 'createdAt'); |
135
|
|
|
$qb = $this->getCustomerRepository()->getReturningCustomersWhoMadeOrderQB(); |
136
|
|
|
$this->applyDateFiltering($qb, 'orders.createdAt', $start, $end); |
137
|
|
|
if ($start) { |
138
|
|
|
$qb |
139
|
|
|
->andWhere('customer.createdAt < :start') |
140
|
|
|
->setParameter('start', $start); |
141
|
|
|
} |
142
|
|
|
$value = $this->aclHelper->apply($qb)->getOneOrNullResult(); |
143
|
|
|
|
144
|
|
|
return $value['val'] ? : 0; |
145
|
|
|
} |
146
|
|
|
|
147
|
|
|
/** |
148
|
|
|
* @param array $dateRange |
149
|
|
|
* |
150
|
|
|
* @return int |
151
|
|
|
*/ |
152
|
|
View Code Duplication |
public function getAbandonedRevenueValues($dateRange) |
|
|
|
|
153
|
|
|
{ |
154
|
|
|
list($start, $end) = $this->dateHelper->getPeriod($dateRange, 'OroCRMMagentoBundle:Cart', 'createdAt'); |
155
|
|
|
|
156
|
|
|
$qb = $this->getCartRepository()->getAbandonedRevenueQB(); |
157
|
|
|
$this->applyDateFiltering($qb, 'cart.createdAt', $start, $end); |
158
|
|
|
$value = $this->aclHelper->apply($qb)->getOneOrNullResult(); |
159
|
|
|
|
160
|
|
|
return $value['val'] ? : 0; |
161
|
|
|
} |
162
|
|
|
|
163
|
|
|
/** |
164
|
|
|
* @param array $dateRange |
165
|
|
|
* |
166
|
|
|
* @return int |
167
|
|
|
*/ |
168
|
|
View Code Duplication |
public function getAbandonedCountValues($dateRange) |
|
|
|
|
169
|
|
|
{ |
170
|
|
|
list($start, $end) = $this->dateHelper->getPeriod($dateRange, 'OroCRMMagentoBundle:Cart', 'createdAt'); |
171
|
|
|
|
172
|
|
|
$qb = $this->getCartRepository()->getAbandonedCountQB(); |
173
|
|
|
$value = $this->aclHelper->apply($qb)->getOneOrNullResult(); |
174
|
|
|
$this->applyDateFiltering($qb, 'cart.createdAt', $start, $end); |
175
|
|
|
|
176
|
|
|
return $value['val'] ? : 0; |
177
|
|
|
} |
178
|
|
|
|
179
|
|
|
/** |
180
|
|
|
* @param array $dateRange |
181
|
|
|
* |
182
|
|
|
* @return float|null |
183
|
|
|
*/ |
184
|
|
|
public function getAbandonRateValues($dateRange) |
185
|
|
|
{ |
186
|
|
|
list($start, $end) = $this->dateHelper->getPeriod($dateRange, 'OroCRMMagentoBundle:Cart', 'createdAt'); |
187
|
|
|
$qb = $this->getCartRepository()->getGrandTotalSumQB(); |
188
|
|
|
$this->applyDateFiltering($qb, 'cart.createdAt', $start, $end); |
189
|
|
|
$allCards = $this->aclHelper->apply($qb)->getOneOrNullResult(); |
190
|
|
|
$allCards = (int)$allCards['val']; |
191
|
|
|
$result = 0; |
192
|
|
|
if (0 !== $allCards) { |
193
|
|
|
$abandonedCartsCount = $this->getAbandonedCountValues($dateRange); |
194
|
|
|
$result = $abandonedCartsCount / $allCards; |
195
|
|
|
} |
196
|
|
|
|
197
|
|
|
return $result; |
198
|
|
|
} |
199
|
|
|
|
200
|
|
|
/** |
201
|
|
|
* @param array $dateRange |
202
|
|
|
* |
203
|
|
|
* @return int |
204
|
|
|
*/ |
205
|
|
|
public function getSiteVisitsValues($dateRange) |
206
|
|
|
{ |
207
|
|
|
list($start, $end) = $this->dateHelper->getPeriod( |
208
|
|
|
$dateRange, |
209
|
|
|
'OroTrackingBundle:TrackingVisit', |
210
|
|
|
'firstActionTime' |
211
|
|
|
); |
212
|
|
|
$visitsQb = $this->channelRepository->getVisitsCountForChannelTypeQB(ChannelType::TYPE); |
213
|
|
|
$this->applyDateFiltering($visitsQb, 'visit.firstActionTime', $start, $end); |
214
|
|
|
|
215
|
|
|
return (int)$this->aclHelper->apply($visitsQb)->getSingleScalarResult(); |
216
|
|
|
} |
217
|
|
|
|
218
|
|
|
/** |
219
|
|
|
* @param array $dateRange |
220
|
|
|
* |
221
|
|
|
* @return int |
222
|
|
|
*/ |
223
|
|
View Code Duplication |
public function getOrderConversionValues($dateRange) |
|
|
|
|
224
|
|
|
{ |
225
|
|
|
$result = 0; |
226
|
|
|
|
227
|
|
|
list($start, $end) = $this->dateHelper->getPeriod($dateRange, 'OroCRMMagentoBundle:Order', 'createdAt'); |
228
|
|
|
$visitsQb = $this->channelRepository->getVisitsCountForChannelTypeQB(ChannelType::TYPE); |
229
|
|
|
$this->applyDateFiltering($visitsQb, 'visit.firstActionTime', $start, $end); |
230
|
|
|
$visits = (int)$this->aclHelper->apply($visitsQb)->getSingleScalarResult(); |
231
|
|
|
if ($visits != 0) { |
232
|
|
|
$ordersCount = $this->getOrdersNumberValues($dateRange); |
233
|
|
|
$result = $ordersCount / $visits; |
234
|
|
|
} |
235
|
|
|
|
236
|
|
|
return $result; |
237
|
|
|
} |
238
|
|
|
|
239
|
|
|
/** |
240
|
|
|
* @param array $dateRange |
241
|
|
|
* |
242
|
|
|
* @return int |
243
|
|
|
*/ |
244
|
|
View Code Duplication |
public function getCustomerConversionValues($dateRange) |
|
|
|
|
245
|
|
|
{ |
246
|
|
|
$result = 0; |
247
|
|
|
|
248
|
|
|
list($start, $end) = $this->dateHelper->getPeriod($dateRange, 'OroCRMMagentoBundle:Customer', 'createdAt'); |
249
|
|
|
|
250
|
|
|
$visitsQb = $this->channelRepository->getVisitsCountForChannelTypeQB(ChannelType::TYPE); |
251
|
|
|
$this->applyDateFiltering($visitsQb, 'visit.firstActionTime', $start, $end); |
252
|
|
|
$visits = (int)$this->aclHelper->apply($visitsQb)->getSingleScalarResult(); |
253
|
|
|
if ($visits !== 0) { |
254
|
|
|
$customers = $this->getNewCustomersCountValues($dateRange); |
255
|
|
|
$result = $customers / $visits; |
256
|
|
|
} |
257
|
|
|
|
258
|
|
|
return $result; |
259
|
|
|
} |
260
|
|
|
|
261
|
|
|
/** |
262
|
|
|
* @return OrderRepository |
263
|
|
|
*/ |
264
|
|
|
protected function getOrderRepository() |
265
|
|
|
{ |
266
|
|
|
return $this->doctrine->getRepository('OroCRMMagentoBundle:Order'); |
267
|
|
|
} |
268
|
|
|
|
269
|
|
|
/** |
270
|
|
|
* @return CustomerRepository |
271
|
|
|
*/ |
272
|
|
|
protected function getCustomerRepository() |
273
|
|
|
{ |
274
|
|
|
return $this->doctrine->getRepository('OroCRMMagentoBundle:Customer'); |
275
|
|
|
} |
276
|
|
|
|
277
|
|
|
/** |
278
|
|
|
* @return CartRepository |
279
|
|
|
*/ |
280
|
|
|
protected function getCartRepository() |
281
|
|
|
{ |
282
|
|
|
return $this->doctrine->getRepository('OroCRMMagentoBundle:Cart'); |
283
|
|
|
} |
284
|
|
|
|
285
|
|
|
/** |
286
|
|
|
* @param QueryBuilder $qb |
287
|
|
|
* @param string $field |
288
|
|
|
* @param \DateTime|null $start |
289
|
|
|
* @param \DateTime|null $end |
290
|
|
|
*/ |
291
|
|
View Code Duplication |
protected function applyDateFiltering( |
|
|
|
|
292
|
|
|
QueryBuilder $qb, |
293
|
|
|
$field, |
294
|
|
|
\DateTime $start = null, |
295
|
|
|
\DateTime $end = null |
296
|
|
|
) { |
297
|
|
|
if ($start) { |
298
|
|
|
$qb |
299
|
|
|
->andWhere(sprintf('%s >= :start', $field)) |
300
|
|
|
->setParameter('start', $start); |
301
|
|
|
} |
302
|
|
|
if ($end) { |
303
|
|
|
$qb |
304
|
|
|
->andWhere(sprintf('%s <= :end', $field)) |
305
|
|
|
->setParameter('end', $end); |
306
|
|
|
} |
307
|
|
|
} |
308
|
|
|
} |
309
|
|
|
|
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.