added explicit classes for widgets (#3170)

This commit is contained in:
Kevin Papst
2022-02-22 21:15:19 +01:00
committed by GitHub
parent 3d3ae97af4
commit c8b47d1033
30 changed files with 1187 additions and 94 deletions

View File

@@ -0,0 +1,48 @@
<?php
/*
* This file is part of the Kimai time-tracking app.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace App\Event;
use Symfony\Contracts\EventDispatcher\Event;
/**
* Used to display the full revenue information for a certain date-range.
*/
final class RevenueStatisticEvent extends Event
{
private $begin;
private $end;
private $revenue = 0.0;
public function __construct(?\DateTime $begin, ?\DateTime $end)
{
$this->begin = $begin;
$this->end = $end;
}
public function getBegin(): ?\DateTime
{
return $this->begin;
}
public function getEnd(): ?\DateTime
{
return $this->end;
}
public function getRevenue(): float
{
return $this->revenue;
}
public function addRevenue(float $revenue): void
{
$this->revenue += $revenue;
}
}

View File

@@ -0,0 +1,53 @@
<?php
/*
* This file is part of the Kimai time-tracking app.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace App\Event;
use App\Entity\User;
use Symfony\Contracts\EventDispatcher\Event;
/**
* Used to display the full revenue information for a certain date-range and user.
*/
final class UserRevenueStatisticEvent extends Event
{
private $event;
private $user;
public function __construct(User $user, ?\DateTime $begin, ?\DateTime $end)
{
$this->user = $user;
$this->event = new RevenueStatisticEvent($begin, $end);
}
public function getBegin(): ?\DateTime
{
return $this->event->getBegin();
}
public function getEnd(): ?\DateTime
{
return $this->event->getEnd();
}
public function getRevenue(): float
{
return $this->event->getRevenue();
}
public function addRevenue(float $revenue): void
{
$this->event->addRevenue($revenue);
}
public function getUser(): User
{
return $this->user;
}
}

View File

@@ -181,44 +181,6 @@ class WidgetRepository
'color' => 'red',
'type' => Counter::class,
],
'userAmountToday' => [
'title' => 'stats.amountToday',
'query' => TimesheetRepository::STATS_QUERY_RATE,
'user' => true,
'begin' => '00:00:00',
'end' => '23:59:59',
'icon' => 'money',
'color' => 'green',
'type' => Counter::class,
],
'userAmountWeek' => [
'title' => 'stats.amountWeek',
'query' => TimesheetRepository::STATS_QUERY_RATE,
'user' => true,
'begin' => 'monday this week 00:00:00',
'end' => 'sunday this week 23:59:59',
'icon' => 'money',
'color' => 'blue',
'type' => Counter::class,
],
'userAmountMonth' => [
'title' => 'stats.amountMonth',
'query' => TimesheetRepository::STATS_QUERY_RATE,
'user' => true,
'begin' => 'first day of this month 00:00:00',
'end' => 'last day of this month 23:59:59',
'icon' => 'money',
'color' => 'purple',
'type' => Counter::class,
],
'userAmountTotal' => [
'title' => 'stats.amountTotal',
'query' => TimesheetRepository::STATS_QUERY_RATE,
'user' => true,
'icon' => 'money',
'color' => 'red',
'type' => Counter::class,
],
'durationToday' => [
'title' => 'stats.durationToday',
'query' => TimesheetRepository::STATS_QUERY_DURATION,
@@ -257,44 +219,6 @@ class WidgetRepository
'user' => false,
'type' => Counter::class,
],
'amountToday' => [
'title' => 'stats.amountToday',
'query' => TimesheetRepository::STATS_QUERY_RATE,
'begin' => '00:00:00',
'end' => '23:59:59',
'icon' => 'money',
'color' => 'green',
'user' => false,
'type' => Counter::class,
],
'amountWeek' => [
'title' => 'stats.amountWeek',
'query' => TimesheetRepository::STATS_QUERY_RATE,
'begin' => 'monday this week 00:00:00',
'end' => 'sunday this week 23:59:59',
'icon' => 'money',
'color' => 'blue',
'user' => false,
'type' => Counter::class,
],
'amountMonth' => [
'title' => 'stats.amountMonth',
'query' => TimesheetRepository::STATS_QUERY_RATE,
'begin' => 'first day of this month 00:00:00',
'end' => 'last day of this month 23:59:59',
'icon' => 'money',
'color' => 'purple',
'user' => false,
'type' => Counter::class,
],
'amountTotal' => [
'title' => 'stats.amountTotal',
'query' => TimesheetRepository::STATS_QUERY_RATE,
'icon' => 'money',
'color' => 'red',
'user' => false,
'type' => Counter::class,
],
'activeUsersToday' => [
'title' => 'stats.userActiveToday',
'query' => TimesheetRepository::STATS_QUERY_USER,

View File

@@ -0,0 +1,59 @@
<?php
/*
* This file is part of the Kimai time-tracking app.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace App\Widget\Type;
use App\Event\RevenueStatisticEvent;
use App\Repository\TimesheetRepository;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
abstract class AbstractAmountPeriod extends SimpleStatisticChart
{
private $dispatcher;
public function __construct(TimesheetRepository $repository, EventDispatcherInterface $dispatcher)
{
parent::__construct($repository);
$this->dispatcher = $dispatcher;
}
public function getTitle(): string
{
return 'stats.' . $this->getId();
}
public function getTemplateName(): string
{
return 'widget/widget-counter.html.twig';
}
public function getOptions(array $options = []): array
{
return array_merge([
'icon' => 'money',
'dataType' => 'money',
], parent::getOptions($options));
}
public function getData(array $options = [])
{
$this->setQuery(TimesheetRepository::STATS_QUERY_RATE);
$this->setQueryWithUser(false);
$data = parent::getData($options);
$event = new RevenueStatisticEvent($this->begin, $this->end);
if ($data !== null) {
$event->addRevenue($data);
}
$this->dispatcher->dispatch($event);
return $event->getRevenue();
}
}

View File

@@ -0,0 +1,59 @@
<?php
/*
* This file is part of the Kimai time-tracking app.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace App\Widget\Type;
use App\Event\UserRevenueStatisticEvent;
use App\Repository\TimesheetRepository;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
abstract class AbstractUserAmountPeriod extends SimpleStatisticChart
{
private $dispatcher;
public function __construct(TimesheetRepository $repository, EventDispatcherInterface $dispatcher)
{
parent::__construct($repository);
$this->dispatcher = $dispatcher;
}
public function getTitle(): string
{
return 'stats.' . str_replace('userA', 'a', $this->getId());
}
public function getTemplateName(): string
{
return 'widget/widget-counter.html.twig';
}
public function getOptions(array $options = []): array
{
return array_merge([
'icon' => 'money',
'dataType' => 'money',
], parent::getOptions($options));
}
public function getData(array $options = [])
{
$this->setQuery(TimesheetRepository::STATS_QUERY_RATE);
$this->setQueryWithUser(true);
$data = parent::getData($options);
$event = new UserRevenueStatisticEvent($this->user, $this->begin, $this->end);
if ($data !== null) {
$event->addRevenue($data);
}
$this->dispatcher->dispatch($event);
return $event->getRevenue();
}
}

View File

@@ -0,0 +1,33 @@
<?php
/*
* This file is part of the Kimai time-tracking app.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace App\Widget\Type;
use App\Widget\WidgetInterface;
final class AmountMonth extends AbstractAmountPeriod
{
public function getOptions(array $options = []): array
{
return array_merge(['color' => WidgetInterface::COLOR_MONTH], parent::getOptions($options));
}
public function getId(): string
{
return 'amountMonth';
}
public function getData(array $options = [])
{
$this->setBegin('first day of this month 00:00:00');
$this->setEnd('last day of this month 23:59:59');
return parent::getData($options);
}
}

View File

@@ -0,0 +1,33 @@
<?php
/*
* This file is part of the Kimai time-tracking app.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace App\Widget\Type;
use App\Widget\WidgetInterface;
final class AmountToday extends AbstractAmountPeriod
{
public function getOptions(array $options = []): array
{
return array_merge(['color' => WidgetInterface::COLOR_TODAY], parent::getOptions($options));
}
public function getId(): string
{
return 'amountToday';
}
public function getData(array $options = [])
{
$this->setBegin('00:00:00');
$this->setEnd('23:59:59');
return parent::getData($options);
}
}

View File

@@ -0,0 +1,25 @@
<?php
/*
* This file is part of the Kimai time-tracking app.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace App\Widget\Type;
use App\Widget\WidgetInterface;
final class AmountTotal extends AbstractAmountPeriod
{
public function getOptions(array $options = []): array
{
return array_merge(['color' => WidgetInterface::COLOR_TOTAL], parent::getOptions($options));
}
public function getId(): string
{
return 'amountTotal';
}
}

View File

@@ -0,0 +1,33 @@
<?php
/*
* This file is part of the Kimai time-tracking app.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace App\Widget\Type;
use App\Widget\WidgetInterface;
final class AmountWeek extends AbstractAmountPeriod
{
public function getOptions(array $options = []): array
{
return array_merge(['color' => WidgetInterface::COLOR_WEEK], parent::getOptions($options));
}
public function getId(): string
{
return 'amountWeek';
}
public function getData(array $options = [])
{
$this->setBegin('monday this week 00:00:00');
$this->setEnd('sunday this week 23:59:59');
return parent::getData($options);
}
}

View File

@@ -10,17 +10,23 @@
namespace App\Widget\Type;
use App\Configuration\SystemConfiguration;
use App\Event\RevenueStatisticEvent;
use App\Repository\TimesheetRepository;
use App\Widget\WidgetInterface;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
final class AmountYear extends CounterYear
{
public function __construct(TimesheetRepository $repository, SystemConfiguration $systemConfiguration)
private $dispatcher;
public function __construct(TimesheetRepository $repository, SystemConfiguration $systemConfiguration, EventDispatcherInterface $dispatcher)
{
parent::__construct($repository, $systemConfiguration);
$this->dispatcher = $dispatcher;
$this->setId('amountYear');
$this->setOption('dataType', 'money');
$this->setOption('icon', 'money');
$this->setOption('color', 'yellow');
$this->setOption('color', WidgetInterface::COLOR_YEAR);
$this->setTitle('stats.amountYear');
}
@@ -30,6 +36,14 @@ final class AmountYear extends CounterYear
$this->setQuery(TimesheetRepository::STATS_QUERY_RATE);
$this->setQueryWithUser(false);
return parent::getData($options);
$data = parent::getData($options);
$event = new RevenueStatisticEvent($this->begin, $this->end);
if ($data !== null) {
$event->addRevenue($data);
}
$this->dispatcher->dispatch($event);
return $event->getRevenue();
}
}

View File

@@ -34,7 +34,7 @@ class SimpleStatisticChart extends SimpleWidget implements UserWidget
/**
* @var User|null
*/
private $user;
protected $user;
/**
* @var bool
*/
@@ -106,11 +106,11 @@ class SimpleStatisticChart extends SimpleWidget implements UserWidget
$end = $this->end;
if (!empty($begin) && \is_string($begin)) {
$begin = new \DateTime($begin, $timezone);
$this->begin = new \DateTime($begin, $timezone);
}
if (!empty($end) && \is_string($end)) {
$end = new \DateTime($end, $timezone);
$this->end = new \DateTime($end, $timezone);
}
try {
@@ -119,7 +119,7 @@ class SimpleStatisticChart extends SimpleWidget implements UserWidget
$user = $this->user;
}
return $this->repository->getStatistic($this->query, $begin, $end, $user);
return $this->repository->getStatistic($this->query, $this->begin, $this->end, $user);
} catch (\Exception $ex) {
throw new WidgetException(
'Failed loading widget data: ' . $ex->getMessage()

View File

@@ -0,0 +1,33 @@
<?php
/*
* This file is part of the Kimai time-tracking app.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace App\Widget\Type;
use App\Widget\WidgetInterface;
final class UserAmountMonth extends AbstractUserAmountPeriod
{
public function getOptions(array $options = []): array
{
return array_merge(['color' => WidgetInterface::COLOR_MONTH], parent::getOptions($options));
}
public function getId(): string
{
return 'userAmountMonth';
}
public function getData(array $options = [])
{
$this->setBegin('first day of this month 00:00:00');
$this->setEnd('last day of this month 23:59:59');
return parent::getData($options);
}
}

View File

@@ -0,0 +1,33 @@
<?php
/*
* This file is part of the Kimai time-tracking app.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace App\Widget\Type;
use App\Widget\WidgetInterface;
final class UserAmountToday extends AbstractUserAmountPeriod
{
public function getOptions(array $options = []): array
{
return array_merge(['color' => WidgetInterface::COLOR_TODAY], parent::getOptions($options));
}
public function getId(): string
{
return 'userAmountToday';
}
public function getData(array $options = [])
{
$this->setBegin('00:00:00');
$this->setEnd('23:59:59');
return parent::getData($options);
}
}

View File

@@ -0,0 +1,25 @@
<?php
/*
* This file is part of the Kimai time-tracking app.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace App\Widget\Type;
use App\Widget\WidgetInterface;
final class UserAmountTotal extends AbstractUserAmountPeriod
{
public function getOptions(array $options = []): array
{
return array_merge(['color' => WidgetInterface::COLOR_TOTAL], parent::getOptions($options));
}
public function getId(): string
{
return 'userAmountTotal';
}
}

View File

@@ -0,0 +1,33 @@
<?php
/*
* This file is part of the Kimai time-tracking app.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace App\Widget\Type;
use App\Widget\WidgetInterface;
final class UserAmountWeek extends AbstractUserAmountPeriod
{
public function getOptions(array $options = []): array
{
return array_merge(['color' => WidgetInterface::COLOR_WEEK], parent::getOptions($options));
}
public function getId(): string
{
return 'userAmountWeek';
}
public function getData(array $options = [])
{
$this->setBegin('monday this week 00:00:00');
$this->setEnd('sunday this week 23:59:59');
return parent::getData($options);
}
}

View File

@@ -10,17 +10,23 @@
namespace App\Widget\Type;
use App\Configuration\SystemConfiguration;
use App\Event\UserRevenueStatisticEvent;
use App\Repository\TimesheetRepository;
use App\Widget\WidgetInterface;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
final class UserAmountYear extends CounterYear
{
public function __construct(TimesheetRepository $repository, SystemConfiguration $systemConfiguration)
private $dispatcher;
public function __construct(TimesheetRepository $repository, SystemConfiguration $systemConfiguration, EventDispatcherInterface $dispatcher)
{
parent::__construct($repository, $systemConfiguration);
$this->dispatcher = $dispatcher;
$this->setId('userAmountYear');
$this->setOption('dataType', 'money');
$this->setOption('icon', 'money');
$this->setOption('color', 'yellow');
$this->setOption('color', WidgetInterface::COLOR_YEAR);
$this->setTitle('stats.amountYear');
}
@@ -30,6 +36,14 @@ final class UserAmountYear extends CounterYear
$this->setQuery(TimesheetRepository::STATS_QUERY_RATE);
$this->setQueryWithUser(true);
return parent::getData($options);
$data = parent::getData($options);
$event = new UserRevenueStatisticEvent($this->user, $this->begin, $this->end);
if ($data !== null) {
$event->addRevenue($data);
}
$this->dispatcher->dispatch($event);
return $event->getRevenue();
}
}

View File

@@ -11,6 +11,12 @@ namespace App\Widget;
interface WidgetInterface
{
public const COLOR_TODAY = 'green';
public const COLOR_WEEK = 'blue';
public const COLOR_MONTH = 'purple';
public const COLOR_YEAR = 'yellow';
public const COLOR_TOTAL = 'red';
/**
* Returns a unique ID for this widget.
*