Skip to content

Commit 16262d6

Browse files
Merge pull request #2265 from suraj-webkul/issue#2230
Issue #2230 been fixed.
2 parents e6b0584 + 84454f3 commit 16262d6

File tree

1 file changed

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

1 file changed

+147
-15
lines changed

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

Lines changed: 147 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,37 @@ 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+
*/
97+
protected function determinePeriod($period = 'auto'): string
98+
{
99+
if ($period !== 'auto') {
100+
return $period;
101+
}
102+
103+
$diffInDays = $this->startDate->diffInDays($this->endDate);
104+
$diffInMonths = $this->startDate->diffInMonths($this->endDate);
105+
$diffInYears = $this->startDate->diffInYears($this->endDate);
106+
107+
if ($diffInYears > 3) {
108+
return 'year';
109+
} elseif ($diffInMonths > 6) {
110+
return 'month';
111+
} elseif ($diffInDays > 60) {
112+
return 'week';
113+
} else {
114+
return 'day';
115+
}
116+
}
117+
85118
/**
86119
* Retrieves total leads and their progress.
87120
*/
@@ -311,41 +344,140 @@ public function getOpenLeadsByStates()
311344
* @param \Carbon\Carbon $startDate
312345
* @param \Carbon\Carbon $endDate
313346
* @param string $valueColumn
347+
* @param string $dateColumn
314348
* @param string $period
315349
*/
316350
public function getOverTimeStats($startDate, $endDate, $valueColumn, $dateColumn = 'created_at', $period = 'auto'): array
317351
{
318-
$config = $this->getTimeInterval($startDate, $endDate, $dateColumn, $period);
352+
$period = $this->determinePeriod($period);
319353

320-
$groupColumn = $config['group_column'];
354+
$intervals = $this->generateTimeIntervals($startDate, $endDate, $period);
355+
356+
$groupColumn = $this->getGroupColumn($dateColumn, $period);
321357

322358
$query = $this->leadRepository
323359
->resetModel()
324360
->select(
325361
DB::raw("$groupColumn AS date"),
326-
DB::raw(DB::getTablePrefix()."$valueColumn AS total"),
327-
DB::raw('COUNT(*) AS count')
362+
DB::raw('COUNT(DISTINCT id) AS count'),
363+
DB::raw("SUM($valueColumn) AS total")
328364
)
329365
->whereIn('lead_pipeline_stage_id', $this->stageIds)
330366
->whereBetween($dateColumn, [$startDate, $endDate])
331-
->groupBy('date');
332-
333-
if (! empty($stageIds)) {
334-
$query->whereIn('lead_pipeline_stage_id', $stageIds);
335-
}
367+
->groupBy(DB::raw($groupColumn))
368+
->orderBy(DB::raw($groupColumn));
336369

337370
$results = $query->get();
371+
$resultLookup = $results->keyBy('date');
338372

339-
foreach ($config['intervals'] as $interval) {
340-
$total = $results->where('date', $interval['filter'])->first();
373+
$stats = [];
374+
375+
foreach ($intervals as $interval) {
376+
$result = $resultLookup->get($interval['key']);
341377

342378
$stats[] = [
343-
'label' => $interval['start'],
344-
'total' => $total?->total ?? 0,
345-
'count' => $total?->count ?? 0,
379+
'label' => $interval['label'],
380+
'count' => $result ? (int) $result->count : 0,
381+
'total' => $result ? (float) $result->total : 0,
382+
];
383+
}
384+
385+
return $stats;
386+
}
387+
388+
/**
389+
* Generate time intervals based on period
390+
*/
391+
protected function generateTimeIntervals(Carbon $startDate, Carbon $endDate, string $period): array
392+
{
393+
$intervals = [];
394+
$current = $startDate->copy();
395+
396+
while ($current <= $endDate) {
397+
$interval = [
398+
'key' => $this->formatDateForGrouping($current, $period),
399+
'label' => $this->formatDateForLabel($current, $period),
346400
];
401+
402+
$intervals[] = $interval;
403+
404+
switch ($period) {
405+
case 'day':
406+
$current->addDay();
407+
408+
break;
409+
case 'week':
410+
$current->addWeek();
411+
412+
break;
413+
case 'month':
414+
$current->addMonth();
415+
416+
break;
417+
case 'year':
418+
$current->addYear();
419+
420+
break;
421+
}
347422
}
348423

349-
return $stats ?? [];
424+
return $intervals;
425+
}
426+
427+
/**
428+
* Get the SQL group column based on period
429+
*/
430+
protected function getGroupColumn(string $dateColumn, string $period): string
431+
{
432+
switch ($period) {
433+
case 'day':
434+
return "DATE($dateColumn)";
435+
case 'week':
436+
return "DATE_FORMAT($dateColumn, '%Y-%u')";
437+
case 'month':
438+
return "DATE_FORMAT($dateColumn, '%Y-%m')";
439+
case 'year':
440+
return "YEAR($dateColumn)";
441+
default:
442+
return "DATE($dateColumn)";
443+
}
444+
}
445+
446+
/**
447+
* Format date for grouping key
448+
*/
449+
protected function formatDateForGrouping(Carbon $date, string $period): string
450+
{
451+
switch ($period) {
452+
case 'day':
453+
return $date->format('Y-m-d');
454+
case 'week':
455+
return $date->format('Y-W');
456+
case 'month':
457+
return $date->format('Y-m');
458+
case 'year':
459+
return $date->format('Y');
460+
default:
461+
return $date->format('Y-m-d');
462+
}
463+
}
464+
465+
/**
466+
* Format date for display label
467+
*/
468+
protected function formatDateForLabel(Carbon $date, string $period): string
469+
{
470+
switch ($period) {
471+
case 'day':
472+
return $date->format('M d');
473+
case 'week':
474+
return 'Week '.$date->format('W, Y');
475+
case 'month':
476+
return $date->format('M Y');
477+
case 'year':
478+
return $date->format('Y');
479+
default:
480+
return $date->format('M d');
481+
}
350482
}
351483
}

0 commit comments

Comments
 (0)