From 11ae0fc5a924be2f94aa6a6c85bd5a023e98b923 Mon Sep 17 00:00:00 2001 From: eliseekn Date: Sun, 17 Sep 2023 11:38:11 +0000 Subject: [PATCH] Fix get valid data for past years, months, weeks and days --- src/LaravelMetrics.php | 150 +++++++++++++++++++++++------------------ 1 file changed, 84 insertions(+), 66 deletions(-) diff --git a/src/LaravelMetrics.php b/src/LaravelMetrics.php index a6bce64..ec9077f 100644 --- a/src/LaravelMetrics.php +++ b/src/LaravelMetrics.php @@ -8,13 +8,13 @@ use Eliseekn\LaravelMetrics\Enums\Aggregate; use Eliseekn\LaravelMetrics\Enums\Period; use Eliseekn\LaravelMetrics\Exceptions\InvalidAggregateException; -use Eliseekn\LaravelMetrics\Exceptions\InvalidDateFormatException; use Eliseekn\LaravelMetrics\Exceptions\InvalidPeriodException; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Query\Builder as QueryBuilder; use Illuminate\Support\Collection; -use Illuminate\Support\Facades\Config; use Illuminate\Support\Facades\DB; +use Eliseekn\LaravelMetrics\Exceptions\InvalidDateFormatException; +use Illuminate\Support\Facades\Config; /** * LaravelMetrics @@ -190,9 +190,7 @@ protected function metricsData(): mixed return $query->where(DB::raw("day($this->dateColumn)"), $this->day); }) ->when($this->count > 1, function (Builder|QueryBuilder $query) { - return $query->whereBetween(DB::raw("day($this->dateColumn)"), [ - Carbon::now()->subDays($this->count)->day, $this->day - ]); + return $query->whereBetween(DB::raw("day($this->dateColumn)"), $this->getDayPeriod()); }) ->first(), @@ -204,9 +202,7 @@ protected function metricsData(): mixed return $query->where(DB::raw($this->formatPeriod(Period::WEEK->value)), $this->week); }) ->when($this->count > 1, function (Builder|QueryBuilder $query) { - return $query->whereBetween(DB::raw($this->formatPeriod(Period::WEEK->value)), [ - Carbon::now()->subWeeks($this->count)->week, $this->week - ]); + return $query->whereBetween(DB::raw($this->formatPeriod(Period::WEEK->value)), $this->getWeekPeriod()); }) ->first(), @@ -217,9 +213,7 @@ protected function metricsData(): mixed return $query->where(DB::raw($this->formatPeriod(Period::MONTH->value)), $this->month); }) ->when($this->count > 1, function (Builder|QueryBuilder $query) { - return $query->whereBetween(DB::raw($this->formatPeriod(Period::MONTH->value)), [ - $this->parseMonth(), $this->month - ]); + return $query->whereBetween(DB::raw($this->formatPeriod(Period::MONTH->value)), $this->getMonthPeriod()); }) ->first(), @@ -261,9 +255,7 @@ protected function trendsData(): Collection return $query->where(DB::raw("day($this->dateColumn)"), $this->day); }) ->when($this->count > 1, function (Builder|QueryBuilder $query) { - return $query->whereBetween(DB::raw("day($this->dateColumn)"), [ - Carbon::now()->subDays($this->count)->day, $this->day - ]); + return $query->whereBetween(DB::raw("day($this->dateColumn)"), $this->getDayPeriod()); }) ->groupBy('label') ->orderBy('label') @@ -277,9 +269,7 @@ protected function trendsData(): Collection return $query->where(DB::raw($this->formatPeriod(Period::WEEK->value)), $this->week); }) ->when($this->count > 1, function (Builder|QueryBuilder $query) { - return $query->whereBetween(DB::raw($this->formatPeriod(Period::WEEK->value)), [ - Carbon::now()->subWeeks($this->count)->week, $this->week - ]); + return $query->whereBetween(DB::raw($this->formatPeriod(Period::WEEK->value)), $this->getWeekPeriod()); }) ->groupBy('label') ->orderBy('label') @@ -292,9 +282,7 @@ protected function trendsData(): Collection return $query->where(DB::raw($this->formatPeriod(Period::MONTH->value)), $this->month); }) ->when($this->count > 1, function (Builder|QueryBuilder $query) { - return $query->whereBetween(DB::raw($this->formatPeriod(Period::MONTH->value)), [ - $this->parseMonth(), $this->month - ]); + return $query->whereBetween(DB::raw($this->formatPeriod(Period::MONTH->value)), $this->getMonthPeriod()); }) ->groupBy('label') ->orderBy('label') @@ -322,33 +310,6 @@ protected function trendsData(): Collection }; } - protected function parseMonth(): int - { - $diff = $this->month - Carbon::now()->startOfYear()->month; - - if ($diff < $this->count) { - return Carbon::now()->startOfYear()->month; - } - - return Carbon::now()->subMonths($this->count)->month; - } - - protected function locale(): string - { - return Config::get('app.locale'); - } - - protected function formatPeriod(string $period): string - { - return match ($period) { - Period::DAY->value => "weekday($this->dateColumn)", - Period::WEEK->value => "week($this->dateColumn)", - Period::MONTH->value => "month($this->dateColumn)", - Period::YEAR->value => "year($this->dateColumn)", - default => '', - }; - } - protected function asData(): string { return "$this->aggregate($this->column) as data"; @@ -365,25 +326,6 @@ protected function asLabel(?string $label = null, bool $format = true): string return $label . " as label"; } - protected function formatDate(Collection $data): Collection - { - return $data->map(function ($datum) { - if ($this->period === Period::MONTH->value) { - $datum->label = Carbon::parse($this->year . '-' . $datum->label)->locale(self::locale())->monthName; - } elseif ($this->period === Period::DAY->value) { - $datum->label = Carbon::parse($this->year . '-' . $this->month . '-' . $datum->label)->locale(self::locale())->dayName; - } elseif ($this->period === Period::WEEK->value) { - $datum->label = 'Week ' . $datum->label; - } elseif ($this->period === Period::YEAR->value) { - $datum->label = intval($datum->label); - } else { - $datum->label = Carbon::parse($datum->label)->locale(self::locale())->toFormattedDateString(); - } - - return $datum; - }); - } - /** * Generate metrics data */ @@ -415,6 +357,82 @@ public function trends(): array return $result; } + protected function carbon(): Carbon + { + return Carbon::parse($this->year . '-' . $this->month . '-' . $this->day); + } + + protected function getDayPeriod(): array + { + $day = $this->month !== Carbon::now()->month ? $this->carbon()->endOfMonth()->day : $this->day; + $diff = $day - $this->carbon()->startOfMonth()->day; + + if ($diff < $this->count) { + return [$this->carbon()->startOfMonth()->day, $day]; + } + + return [$this->carbon()->subDays($this->count)->day, $day]; + } + + protected function getWeekPeriod(): array + { + $week = $this->month !== Carbon::now()->month ? $this->carbon()->endOfMonth()->week : $this->week; + $diff = $week - $this->carbon()->startOfMonth()->week; + + if ($diff < $this->count) { + return [$this->carbon()->startOfMonth()->week, $week]; + } + + return [$this->carbon()->subWeeks($this->count)->week, $week]; + } + + protected function getMonthPeriod(): array + { + $month = $this->year !== Carbon::now()->year ? $this->carbon()->endOfYear()->month : $this->month; + $diff = $month - $this->carbon()->startOfYear()->month; + + if ($diff < $this->count) { + return [$this->carbon()->startOfYear()->month, $month]; + } + + return [$this->carbon()->subMonths($this->count)->month, $month]; + } + + protected function locale(): string + { + return Config::get('app.locale'); + } + + protected function formatPeriod(string $period): string + { + return match ($period) { + Period::DAY->value => "weekday($this->dateColumn)", + Period::WEEK->value => "week($this->dateColumn)", + Period::MONTH->value => "month($this->dateColumn)", + Period::YEAR->value => "year($this->dateColumn)", + default => '', + }; + } + + protected function formatDate(Collection $data): Collection + { + return $data->map(function ($datum) { + if ($this->period === Period::MONTH->value) { + $datum->label = Carbon::parse($this->year . '-' . $datum->label)->locale(self::locale())->monthName; + } elseif ($this->period === Period::DAY->value) { + $datum->label = Carbon::parse($this->year . '-' . $this->month . '-' . $datum->label)->locale(self::locale())->dayName; + } elseif ($this->period === Period::WEEK->value) { + $datum->label = 'Week ' . $datum->label; + } elseif ($this->period === Period::YEAR->value) { + $datum->label = intval($datum->label); + } else { + $datum->label = Carbon::parse($datum->label)->locale(self::locale())->toFormattedDateString(); + } + + return $datum; + }); + } + protected function checkDateFormat(array $dates): void { foreach ($dates as $date) {