2
2
3
3
namespace Webkul \Admin \Helpers \Reporting ;
4
4
5
+ use Carbon \Carbon ;
5
6
use Illuminate \Support \Facades \DB ;
6
7
use Webkul \Lead \Repositories \LeadRepository ;
7
8
use Webkul \Lead \Repositories \StageRepository ;
@@ -55,6 +56,8 @@ public function getTotalLeadsOverTime($period = 'auto'): array
55
56
{
56
57
$ this ->stageIds = $ this ->allStageIds ;
57
58
59
+ $ period = $ this ->determinePeriod ($ period );
60
+
58
61
return $ this ->getOverTimeStats ($ this ->startDate , $ this ->endDate , 'leads.id ' , 'created_at ' , $ period );
59
62
}
60
63
@@ -67,6 +70,8 @@ public function getTotalWonLeadsOverTime($period = 'auto'): array
67
70
{
68
71
$ this ->stageIds = $ this ->wonStageIds ;
69
72
73
+ $ period = $ this ->determinePeriod ($ period );
74
+
70
75
return $ this ->getOverTimeStats ($ this ->startDate , $ this ->endDate , 'leads.id ' , 'closed_at ' , $ period );
71
76
}
72
77
@@ -79,9 +84,38 @@ public function getTotalLostLeadsOverTime($period = 'auto'): array
79
84
{
80
85
$ this ->stageIds = $ this ->lostStageIds ;
81
86
87
+ $ period = $ this ->determinePeriod ($ period );
88
+
82
89
return $ this ->getOverTimeStats ($ this ->startDate , $ this ->endDate , 'leads.id ' , 'closed_at ' , $ period );
83
90
}
84
91
92
+ /**
93
+ * Determine the appropriate period based on date range
94
+ *
95
+ * @param string $period
96
+ * @return string
97
+ */
98
+ protected function determinePeriod ($ period = 'auto ' ): string
99
+ {
100
+ if ($ period !== 'auto ' ) {
101
+ return $ period ;
102
+ }
103
+
104
+ $ diffInDays = $ this ->startDate ->diffInDays ($ this ->endDate );
105
+ $ diffInMonths = $ this ->startDate ->diffInMonths ($ this ->endDate );
106
+ $ diffInYears = $ this ->startDate ->diffInYears ($ this ->endDate );
107
+
108
+ if ($ diffInYears > 3 ) {
109
+ return 'year ' ;
110
+ } elseif ($ diffInMonths > 6 ) {
111
+ return 'month ' ;
112
+ } elseif ($ diffInDays > 60 ) {
113
+ return 'week ' ;
114
+ } else {
115
+ return 'day ' ;
116
+ }
117
+ }
118
+
85
119
/**
86
120
* Retrieves total leads and their progress.
87
121
*/
@@ -311,41 +345,157 @@ public function getOpenLeadsByStates()
311
345
* @param \Carbon\Carbon $startDate
312
346
* @param \Carbon\Carbon $endDate
313
347
* @param string $valueColumn
348
+ * @param string $dateColumn
314
349
* @param string $period
315
350
*/
316
351
public function getOverTimeStats ($ startDate , $ endDate , $ valueColumn , $ dateColumn = 'created_at ' , $ period = 'auto ' ): array
317
352
{
318
- $ config = $ this ->getTimeInterval ($ startDate , $ endDate , $ dateColumn , $ period );
353
+ $ period = $ this ->determinePeriod ($ period );
354
+
355
+ $ intervals = $ this ->generateTimeIntervals ($ startDate , $ endDate , $ period );
319
356
320
- $ groupColumn = $ config [ ' group_column ' ] ;
357
+ $ groupColumn = $ this -> getGroupColumn ( $ dateColumn , $ period ) ;
321
358
322
359
$ query = $ this ->leadRepository
323
360
->resetModel ()
324
361
->select (
325
362
DB ::raw ("$ groupColumn AS date " ),
326
- DB ::raw (DB :: getTablePrefix (). " $ valueColumn AS total " ),
327
- DB ::raw (' COUNT(* ) AS count ' )
363
+ DB ::raw (" COUNT(DISTINCT id) AS count " ),
364
+ DB ::raw (" SUM( $ valueColumn ) AS total " )
328
365
)
329
366
->whereIn ('lead_pipeline_stage_id ' , $ this ->stageIds )
330
367
->whereBetween ($ dateColumn , [$ startDate , $ endDate ])
331
- ->groupBy ('date ' );
332
-
333
- if (! empty ($ stageIds )) {
334
- $ query ->whereIn ('lead_pipeline_stage_id ' , $ stageIds );
335
- }
368
+ ->groupBy (DB ::raw ($ groupColumn ))
369
+ ->orderBy (DB ::raw ($ groupColumn ));
336
370
337
371
$ results = $ query ->get ();
372
+ $ resultLookup = $ results ->keyBy ('date ' );
373
+
374
+ $ stats = [];
338
375
339
- foreach ($ config [ ' intervals ' ] as $ interval ) {
340
- $ total = $ results -> where ( ' date ' , $ interval ['filter ' ])-> first ( );
376
+ foreach ($ intervals as $ interval ) {
377
+ $ result = $ resultLookup -> get ( $ interval ['key ' ] );
341
378
342
379
$ stats [] = [
343
- 'label ' => $ interval ['start ' ],
344
- 'total ' => $ total ?->total ?? 0 ,
345
- 'count ' => $ total ?->count ?? 0 ,
380
+ 'label ' => $ interval ['label ' ],
381
+ 'count ' => $ result ? (int ) $ result ->count : 0 ,
382
+ 'total ' => $ result ? (float ) $ result ->total : 0 ,
383
+ ];
384
+ }
385
+
386
+ return $ stats ;
387
+ }
388
+
389
+ /**
390
+ * Generate time intervals based on period
391
+ *
392
+ * @param Carbon $startDate
393
+ * @param Carbon $endDate
394
+ * @param string $period
395
+ * @return array
396
+ */
397
+ protected function generateTimeIntervals (Carbon $ startDate , Carbon $ endDate , string $ period ): array
398
+ {
399
+ $ intervals = [];
400
+ $ current = $ startDate ->copy ();
401
+
402
+ while ($ current <= $ endDate ) {
403
+ $ interval = [
404
+ 'key ' => $ this ->formatDateForGrouping ($ current , $ period ),
405
+ 'label ' => $ this ->formatDateForLabel ($ current , $ period ),
346
406
];
407
+
408
+ $ intervals [] = $ interval ;
409
+
410
+ switch ($ period ) {
411
+ case 'day ' :
412
+ $ current ->addDay ();
413
+
414
+ break ;
415
+ case 'week ' :
416
+ $ current ->addWeek ();
417
+
418
+ break ;
419
+ case 'month ' :
420
+ $ current ->addMonth ();
421
+
422
+ break ;
423
+ case 'year ' :
424
+ $ current ->addYear ();
425
+
426
+ break ;
427
+ }
347
428
}
348
429
349
- return $ stats ?? [];
430
+ return $ intervals ;
431
+ }
432
+
433
+ /**
434
+ * Get the SQL group column based on period
435
+ *
436
+ * @param string $dateColumn
437
+ * @param string $period
438
+ * @return string
439
+ */
440
+ protected function getGroupColumn (string $ dateColumn , string $ period ): string
441
+ {
442
+ switch ($ period ) {
443
+ case 'day ' :
444
+ return "DATE( $ dateColumn) " ;
445
+ case 'week ' :
446
+ return "DATE_FORMAT( $ dateColumn, '%Y-%u') " ;
447
+ case 'month ' :
448
+ return "DATE_FORMAT( $ dateColumn, '%Y-%m') " ;
449
+ case 'year ' :
450
+ return "YEAR( $ dateColumn) " ;
451
+ default :
452
+ return "DATE( $ dateColumn) " ;
453
+ }
454
+ }
455
+
456
+ /**
457
+ * Format date for grouping key
458
+ *
459
+ * @param Carbon $date
460
+ * @param string $period
461
+ * @return string
462
+ */
463
+ protected function formatDateForGrouping (Carbon $ date , string $ period ): string
464
+ {
465
+ switch ($ period ) {
466
+ case 'day ' :
467
+ return $ date ->format ('Y-m-d ' );
468
+ case 'week ' :
469
+ return $ date ->format ('Y-W ' );
470
+ case 'month ' :
471
+ return $ date ->format ('Y-m ' );
472
+ case 'year ' :
473
+ return $ date ->format ('Y ' );
474
+ default :
475
+ return $ date ->format ('Y-m-d ' );
476
+ }
477
+ }
478
+
479
+ /**
480
+ * Format date for display label
481
+ *
482
+ * @param Carbon $date
483
+ * @param string $period
484
+ * @return string
485
+ */
486
+ protected function formatDateForLabel (Carbon $ date , string $ period ): string
487
+ {
488
+ switch ($ period ) {
489
+ case 'day ' :
490
+ return $ date ->format ('M d ' );
491
+ case 'week ' :
492
+ return 'Week ' . $ date ->format ('W, Y ' );
493
+ case 'month ' :
494
+ return $ date ->format ('M Y ' );
495
+ case 'year ' :
496
+ return $ date ->format ('Y ' );
497
+ default :
498
+ return $ date ->format ('M d ' );
499
+ }
350
500
}
351
501
}
0 commit comments