Skip to content

Commit 9f79b09

Browse files
committed
Issue #2230 has been fixed.
1 parent 6d68eb2 commit 9f79b09

File tree

1 file changed

+165
-15
lines changed
  • packages/Webkul/Admin/src/Helpers/Reporting

1 file changed

+165
-15
lines changed

packages/Webkul/Admin/src/Helpers/Reporting/Lead.php

Lines changed: 165 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace Webkul\Admin\Helpers\Reporting;
44

5+
use Carbon\Carbon;
56
use Illuminate\Support\Facades\DB;
67
use Webkul\Lead\Repositories\LeadRepository;
78
use Webkul\Lead\Repositories\StageRepository;
@@ -55,6 +56,8 @@ public function getTotalLeadsOverTime($period = 'auto'): array
5556
{
5657
$this->stageIds = $this->allStageIds;
5758

59+
$period = $this->determinePeriod($period);
60+
5861
return $this->getOverTimeStats($this->startDate, $this->endDate, 'leads.id', 'created_at', $period);
5962
}
6063

@@ -67,6 +70,8 @@ public function getTotalWonLeadsOverTime($period = 'auto'): array
6770
{
6871
$this->stageIds = $this->wonStageIds;
6972

73+
$period = $this->determinePeriod($period);
74+
7075
return $this->getOverTimeStats($this->startDate, $this->endDate, 'leads.id', 'closed_at', $period);
7176
}
7277

@@ -79,9 +84,38 @@ public function getTotalLostLeadsOverTime($period = 'auto'): array
7984
{
8085
$this->stageIds = $this->lostStageIds;
8186

87+
$period = $this->determinePeriod($period);
88+
8289
return $this->getOverTimeStats($this->startDate, $this->endDate, 'leads.id', 'closed_at', $period);
8390
}
8491

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+
85119
/**
86120
* Retrieves total leads and their progress.
87121
*/
@@ -311,41 +345,157 @@ public function getOpenLeadsByStates()
311345
* @param \Carbon\Carbon $startDate
312346
* @param \Carbon\Carbon $endDate
313347
* @param string $valueColumn
348+
* @param string $dateColumn
314349
* @param string $period
315350
*/
316351
public function getOverTimeStats($startDate, $endDate, $valueColumn, $dateColumn = 'created_at', $period = 'auto'): array
317352
{
318-
$config = $this->getTimeInterval($startDate, $endDate, $dateColumn, $period);
353+
$period = $this->determinePeriod($period);
354+
355+
$intervals = $this->generateTimeIntervals($startDate, $endDate, $period);
319356

320-
$groupColumn = $config['group_column'];
357+
$groupColumn = $this->getGroupColumn($dateColumn, $period);
321358

322359
$query = $this->leadRepository
323360
->resetModel()
324361
->select(
325362
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")
328365
)
329366
->whereIn('lead_pipeline_stage_id', $this->stageIds)
330367
->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));
336370

337371
$results = $query->get();
372+
$resultLookup = $results->keyBy('date');
373+
374+
$stats = [];
338375

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']);
341378

342379
$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),
346406
];
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+
}
347428
}
348429

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+
}
350500
}
351501
}

0 commit comments

Comments
 (0)