Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
iamgergo committed Dec 23, 2023
1 parent fdcc935 commit 828390d
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 35 deletions.
8 changes: 5 additions & 3 deletions src/Widgets/Metric.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Closure;
use Cone\Root\Exceptions\QueryResolutionException;
use Cone\Root\Widgets\Results\Result;
use DateTimeInterface;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\Request;
Expand All @@ -24,7 +25,7 @@ abstract class Metric extends Widget
/**
* Calculate the metric data.
*/
abstract public function calculate(Request $request): array;
abstract public function calculate(Request $request): Result;

/**
* Set the query.
Expand Down Expand Up @@ -89,12 +90,13 @@ public function getCurrentRange(Request $request): string
}

/**
* Create a new method.
* Calculate the range.
*/
protected function range(DateTimeInterface $date, string $range): mixed
{
return match ($range) {
'TODAY' => $date->startOfDay(),
'DAY' => $date->subDay(),
'WEEK' => $date->subWeek(),
'MONTH' => $date->subMonth(),
'QUARTER' => $date->subQuarter(),
Expand Down Expand Up @@ -126,7 +128,7 @@ public function data(Request $request): array
{
return array_merge(parent::data($request), [
'ranges' => $this->ranges(),
'data' => $this->calculate($request),
'data' => $this->calculate($request)->toArray(),
]);
}
}
10 changes: 10 additions & 0 deletions src/Widgets/Results/Result.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

namespace Cone\Root\Widgets\Results;

use Illuminate\Contracts\Support\Arrayable;

abstract class Result implements Arrayable
{
//
}
45 changes: 45 additions & 0 deletions src/Widgets/Results/ValueResult.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php

namespace Cone\Root\Widgets\Results;

class ValueResult extends Result
{
/**
* The current value.
*/
protected float $current;

/**
* The previous value.
*/
protected float $previous;

/**
* Create a new result instance.
*/
public function __construct(float $current, float $previous = 0)
{
$this->current = round($current, 2);
$this->previous = round($previous, 2);
}

/**
* Calculate the trend.
*/
public function trend(): float
{
return $this->previous === 0 ? 0 : round(($this->current - $this->previous) / (($this->current + $this->previous) / 2) * 100, 1);
}

/**
* Convert the result as an array.
*/
public function toArray(): array
{
return [
'previous' => $this->previous,
'current' => $this->current,
'trend' => $this->trend(),
];
}
}
10 changes: 0 additions & 10 deletions src/Widgets/Trend.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,10 @@

namespace Cone\Root\Widgets;

use Illuminate\Http\Request;

abstract class Trend extends Metric
{
/**
* The Blade template.
*/
protected string $template = 'root::widgets.trend';

/**
* Calculate the metric data.
*/
public function calculate(Request $request): array
{
return [];
}
}
54 changes: 32 additions & 22 deletions src/Widgets/Value.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Cone\Root\Widgets;

use Cone\Root\Widgets\Results\ValueResult;
use DateTimeInterface;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\Request;
Expand Down Expand Up @@ -43,7 +44,9 @@ public function previous(Request $request): DateTimeInterface
{
$from = $this->from($request);

return $this->range($from, $this->getCurrentRange($request));
$range = $this->getCurrentRange($request);

return $this->range($from, $range === 'TODAY' ? 'DAY' : $range);
}

/**
Expand All @@ -61,44 +64,51 @@ public function resolveQuery(Request $request): Builder

$column = $query->getModel()->getQualifiedCreatedAtColumn();

return $query->whereBetween($column, [$previous, $to])->groupByRaw(sprintf(
"(case when %s between '%s' and '%s' then 0 else 1 end)",
return $query->selectRaw(sprintf(
"(case when %s between '%s' and '%s' then 'previous' else 'current' end) as `__interval`",
$query->getQuery()->getGrammar()->wrap($column),
(string) $previous,
(string) $from
));
))->whereBetween($column, [$previous, $to])->groupBy('__interval');
});
}

/**
* Count values.
* Aggregate count values.
*/
public function count(Request $request, string $column = '*'): array
public function count(Request $request, Builder $query, string $column = '*'): ValueResult
{
return $this->resolveQuery($request)
->getQuery()
->selectRaw(sprintf('count(%s) as `total`', $column))
->get()
->pluck('total')
->toArray();
return $this->toResult(
$query->selectRaw(sprintf('count(%s) as `__value`', $query->getQuery()->getGrammar()->wrap($column)))
);
}

/**
* Calculate the metric data.
* Aggregate average values.
*/
public function calculate(Request $request): array
public function avg(Request $request, Builder $query, string $column): ValueResult
{
$data = $this->count($request);
return $this->toResult(
$query->selectRaw(sprintf('avg(%s) as `__value`', $query->getQuery()->getGrammar()->wrap($column)))
);
}

$previous = count($data) === 1 ? 0 : $data[0];
/**
* Calculate the metric data.
*/
public function calculate(Request $request): ValueResult
{
return $this->avg($request, $this->resolveQuery($request), 'discount');
}

$current = count($data) === 1 ? $data[0] : $data[1];
/**
* Convert the query to result.
*/
public function toResult(Builder $query): ValueResult
{
$data = $query->getQuery()->get()->pluck('__value', '__interval')->all();

return [
'previous' => $previous,
'current' => $current,
'trend' => $previous === 0 ? 0 : round(($current - $previous) / (($current + $previous) / 2) * 100, 1),
];
return new ValueResult($data['current'] ?? 0, $data['previous'] ?? 0);
}

/**
Expand Down

0 comments on commit 828390d

Please sign in to comment.