PluginProbe ʕ •ᴥ•ʔ
VikAppointments Services Booking Calendar / 1.2.21
VikAppointments Services Booking Calendar v1.2.21
1.2.21 1.2.20 trunk 1.2.17 1.2.18 1.2.19
vikappointments / site / helpers / libraries / models / statistics.php
vikappointments / site / helpers / libraries / models Last commit date
conversion.php 3 days ago customer.php 3 days ago customfields.php 3 days ago index.html 3 days ago locations.php 3 days ago orderstatus.php 3 days ago restrictions.php 3 days ago specialrates.php 3 days ago statistics.php 3 days ago subscriptions.php 3 days ago
statistics.php
441 lines
1 <?php
2 /**
3 * @package VikAppointments
4 * @subpackage core
5 * @author E4J s.r.l.
6 * @copyright Copyright (C) 2021 E4J s.r.l. All Rights Reserved.
7 * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL
8 * @link https://vikwp.com
9 */
10
11 // No direct access
12 defined('ABSPATH') or die('No script kiddies please!');
13
14 /**
15 * VikAppointments statistics class handler.
16 *
17 * @since 1.6
18 */
19 class VAPStatistics
20 {
21 /**
22 * An array containing the statistics fetched.
23 *
24 * @var array
25 */
26 private $statistics = array();
27
28 /**
29 * Class constructor.
30 *
31 * @param integer $year The year to fetch.
32 * @param integer $id_emp The employee to check for.
33 * @param integer $id_ser The service to check for (optional).
34 *
35 * @uses getStatistics()
36 */
37 public function __construct($year, $id_emp, $id_ser = null)
38 {
39 $this->statistics = self::getStatistics($year, $id_emp, $id_ser);
40 }
41
42 /**
43 * Returns the total amount earned within the specified year.
44 *
45 * @return float
46 */
47 public function getYearTotalEarning()
48 {
49 return $this->statistics[self::YEAR_TOTAL_EARNING]['total'];
50 }
51
52 /**
53 * Returns the total number of reservations received within the
54 * specified year.
55 *
56 * @return integer
57 */
58 public function getYearTotalReservations()
59 {
60 return $this->statistics[self::YEAR_TOTAL_EARNING]['numres'];
61 }
62
63 /**
64 * Returns the total amount earned for the specified month
65 * of the given year.
66 *
67 * @param integer $month From 1 to 12.
68 *
69 * @return float
70 */
71 public function getMonthTotalEarning($month)
72 {
73 return $this->statistics[self::MONTHS_TOTAL_EARNING][$month]['total'];
74 }
75
76 /**
77 * Returns the total number of reservations received for the
78 * specified month of the given year.
79 *
80 * @param integer $month From 1 ro 12.
81 *
82 * @return integer
83 */
84 public function getMonthTotalReservations($month)
85 {
86 return $this->statistics[self::MONTHS_TOTAL_EARNING][$month]['numres'];
87 }
88
89 /**
90 * Returns the total amount earned by the employee for the
91 * specified month of the given year.
92 *
93 * @param integer $month From 1 to 12.
94 *
95 * @return float
96 */
97 public function getEmployeeMonthTotalEarning($month)
98 {
99 return $this->statistics[self::EMPLOYEE_MONTHS_TOTAL_EARNING][$month]['total'];
100 }
101
102 /**
103 * Returns the total number of reservations received for the
104 * specified month of the given year, that belong to the
105 * current employee.
106 *
107 * @param integer $month From 1 ro 12.
108 *
109 * @return integer
110 */
111 public function getEmployeeMonthTotalReservations($month)
112 {
113 return $this->statistics[self::EMPLOYEE_MONTHS_TOTAL_EARNING][$month]['numres'];
114 }
115
116 /**
117 * Returns an array containing the statistics details
118 * for each service within the specified month of the given year.
119 * For example:
120 * [
121 * 0 => [sname, numres, total],
122 * 1 => [sname, numres, total],
123 * ]
124 *
125 * @param integer $month From 1 ro 12.
126 *
127 * @return array
128 */
129 public function getEmployeeMonthServiceArray($month)
130 {
131 return $this->statistics[self::EMPLOYEE_MONTHS_SERVICE_TOTAL_EARNING][$month];
132 }
133
134 /**
135 * Calculates the total amount earned within the given year.
136 *
137 * @param integer $year
138 * @param mixed $dbo
139 *
140 * @return array An array containing the following attributes:
141 * - numres integer the total number of appointments;
142 * - total float the total amount earned.
143 *
144 * @uses getDateArray()
145 * @uses getBaseQuery()
146 */
147 protected function calculateYearTotalEarning($year, $dbo = null)
148 {
149 if (!$dbo)
150 {
151 $dbo = JFactory::getDbo();
152 }
153
154 $syear = self::getDateArray($year, 1);
155 $eyear = self::getDateArray($year + 1, 1);
156
157 $q = self::getBaseQuery($syear[0], $eyear[0], $dbo);
158
159 $dbo->setQuery($q);
160 return $dbo->loadAssoc();
161 }
162
163 /**
164 * Calculates the monthly total amount earned within the given year.
165 *
166 * @param integer $year
167 * @param mixed $dbo
168 *
169 * @return array An array containing the statistics for each month [1-12].
170 *
171 * @uses getDateArray()
172 * @uses getBaseQuery()
173 */
174 protected function calculateMonthsTotalEarning($year, $dbo = null)
175 {
176 if (!$dbo)
177 {
178 $dbo = JFactory::getDbo();
179 }
180
181 $mon_arr = array();
182
183 for ($i = 1; $i <= 12; $i++)
184 {
185 $smon = self::getDateArray($year, $i);
186
187 if ($i < 12)
188 {
189 $emon = self::getDateArray($year, $i + 1);
190 }
191 else
192 {
193 $emon = self::getDateArray($year + 1, 1);
194 }
195
196 $q = self::getBaseQuery($smon[0], $emon[0], $dbo);
197
198 $dbo->setQuery($q);
199 $mon_arr[$i] = $dbo->loadAssoc();
200 }
201
202 return $mon_arr;
203 }
204
205 /**
206 * Calculates the monthly total amount earned within the given year
207 * by the specified employee.
208 *
209 * @param integer $year
210 * @param integer $id_emp
211 * @param mixed $dbo
212 *
213 * @return array An array containing the following attributes:
214 * - numres integer the total number of appointments;
215 * - total float the total amount earned.
216 *
217 * @uses getDateArray()
218 * @uses getBaseQuery()
219 */
220 protected function calculateEmployeeMonthsTotalEarning($year, $id_emp, $dbo = null)
221 {
222 if (!$dbo)
223 {
224 $dbo = JFactory::getDbo();
225 }
226
227 $mon_arr = array();
228
229 for ($i = 1; $i <= 12; $i++)
230 {
231 $smon = self::getDateArray($year, $i);
232
233 if ($i < 12)
234 {
235 $emon = self::getDateArray($year, $i + 1);
236 }
237 else
238 {
239 $emon = self::getDateArray($year + 1, 1);
240 }
241
242 $q = self::getBaseQuery($smon[0], $emon[0], $dbo);
243
244 // extend query to filter the reservations by employee ID
245 $q->where($dbo->qn('r.id_employee') . ' = ' . (int) $id_emp);
246
247 $dbo->setQuery($q);
248 $mon_arr[$i] = $dbo->loadAssoc();
249 }
250
251 return $mon_arr;
252 }
253
254 /**
255 * Calculates the monthly total amount earned within the given year
256 * by the specified employee.
257 *
258 * @param integer $year
259 * @param integer $id_emp
260 * @param integer $id_ser
261 * @param mixed $dbo
262 *
263 * @return array An array containing the statistics for each month [1-12].
264 *
265 * @uses getDateArray()
266 * @uses getBaseQuery()
267 */
268 protected function calculateEmployeeMonthsServiceTotalEarning($year, $id_emp, $id_ser = null, $dbo = null)
269 {
270 if (!$dbo)
271 {
272 $dbo = JFactory::getDbo();
273 }
274
275 $mon_arr = array();
276
277 for ($i = 1; $i <= 12; $i++)
278 {
279 $smon = self::getDateArray($year, $i);
280
281 if ($i < 12)
282 {
283 $emon = self::getDateArray($year, $i + 1);
284 }
285 else
286 {
287 $emon = self::getDateArray($year + 1, 1);
288 }
289
290 $q = self::getBaseQuery($smon[0], $emon[0], $dbo);
291
292 // extend query to split the reservations by service
293 $q->select($dbo->qn('s.name', 'sname'));
294 $q->from($dbo->qn('#__vikappointments_service', 's'));
295 $q->where($dbo->qn('r.id_service') . ' = ' . $dbo->qn('s.id'));
296
297 // extend query to filter the reservations by employee ID
298 $q->where($dbo->qn('r.id_employee') . ' = ' . (int) $id_emp);
299
300 /**
301 * In case the service was passed, retrieve only the information for that service.
302 * Otherwise group by service name in order to retrieve all the services properly.
303 *
304 * @since 1.6.3
305 */
306 if ($id_ser)
307 {
308 $q->where($dbo->qn('r.id_service') . ' = ' . (int) $id_ser);
309 }
310 else
311 {
312 $q->group($dbo->qn('s.name'));
313 }
314
315 $dbo->setQuery($q);
316 $mon_arr[$i] = $dbo->loadAssocList();
317 }
318
319 return $mon_arr;
320 }
321
322 /**
323 * Returns an array containing the statistics fetched.
324 * Here's the elements list:
325 * - [ytl] Year total earning;
326 * - [mtl] Monthly total earning;
327 * - [emtl] Employee monthly total earning;
328 * - [emstl] Employee monthly total earning for each service.
329 *
330 * @param integer $year
331 * @param integer $id_emp
332 * @param integer $id_ser
333 * @param mixed $dbo
334 *
335 * @return array
336 *
337 * @uses calculateYearTotalEarning()
338 * @uses calculateMonthsTotalEarning()
339 * @uses calculateEmployeeMonthsTotalEarning()
340 * @uses calculateEmployeeMonthsServiceTotalEarning()
341 */
342 public function getStatistics($year, $id_emp, $id_ser = null, $dbo = null)
343 {
344 if (!$dbo)
345 {
346 $dbo = JFactory::getDbo();
347 }
348
349 $stat = array(
350 self::YEAR_TOTAL_EARNING => self::calculateYearTotalEarning($year, $dbo),
351 self::MONTHS_TOTAL_EARNING => self::calculateMonthsTotalEarning($year, $dbo),
352 self::EMPLOYEE_MONTHS_TOTAL_EARNING => self::calculateEmployeeMonthsTotalEarning($year, $id_emp, $dbo),
353 self::EMPLOYEE_MONTHS_SERVICE_TOTAL_EARNING => self::calculateEmployeeMonthsServiceTotalEarning($year, $id_emp, $id_ser, $dbo),
354 );
355
356 return $stat;
357 }
358
359 /**
360 * Returns a date array for the specified year and month.
361 *
362 * @param integer $year The year. If null, the current year will be used.
363 * @param integer $month The month. If null, the current month will be used.
364 *
365 * @return array The date array.
366 *
367 * @see getdate()
368 */
369 private function getDateArray($year = null, $month = null)
370 {
371 $arr = getdate();
372
373 if (!$month)
374 {
375 $month = $arr['mon'];
376 }
377
378 if (!$year)
379 {
380 $year = $arr['year'];
381 }
382
383 return getdate(mktime(0, 0, 0, $month, 1, $year));
384 }
385
386 /**
387 * Returns the base query to use to fetch the statistics.
388 *
389 * @param integer $start The initial delimiter timestamp (included).
390 * @param integer $end The ending delimiter timestamp (excluded).
391 * @param mixed $dbo
392 *
393 * @return mixed The query builder instance.
394 */
395 private function getBaseQuery($start, $end, $dbo)
396 {
397 $q = $dbo->getQuery(true);
398
399 $q->select('COUNT(' . $dbo->qn('r.id') . ') AS ' . $dbo->qn('numres'));
400 $q->select('SUM(' . $dbo->qn('r.total_cost') . ') AS ' . $dbo->qn('total'));
401
402 $q->from($dbo->qn('#__vikappointments_reservation', 'r'));
403
404 $q->where(array(
405 $dbo->qn('r.status') . ' = ' . $dbo->q('CONFIRMED'),
406 $dbo->qn('r.checkin_ts') . ' BETWEEN ' . $start . ' AND ' . ($end - 1),
407 $dbo->qn('r.closure') . ' = 0',
408 ));
409
410 return $q;
411 }
412
413 /**
414 * Identifier for year total earning.
415 *
416 * @var string
417 */
418 const YEAR_TOTAL_EARNING = 'ytl';
419
420 /**
421 * Identifier for months total earning.
422 *
423 * @var string
424 */
425 const MONTHS_TOTAL_EARNING = 'mtl';
426
427 /**
428 * Identifier for employee months total earning.
429 *
430 * @var string
431 */
432 const EMPLOYEE_MONTHS_TOTAL_EARNING = 'emtl';
433
434 /**
435 * Identifier for employee months service total earning.
436 *
437 * @var string
438 */
439 const EMPLOYEE_MONTHS_SERVICE_TOTAL_EARNING = 'emstl';
440 }
441