Accounts Chart Implementation

This commit is contained in:
Jack Anderson 2021-01-06 08:56:43 +00:00 committed by Dillon-Brown
parent 0ca4b558d5
commit e9b9819e7d
4 changed files with 422 additions and 0 deletions

View file

@ -0,0 +1,39 @@
<?php
use Symfony\Component\DependencyInjection\Container;
if (!isset($container)) {
return;
}
/** @var Container $container */
$widgets = $container->getParameter('module.listview.sidebar_widgets');
if (!isset($widgets['modules']['accounts'])) {
$widgets['modules']['accounts'] = [];
}
if (!isset($widgets['modules']['accounts']['widgets'])) {
$widgets['modules']['accounts']['widgets'] = [];
}
$widgets['modules']['accounts']['widgets']['accounts-new-by-month'] = [
'type' => 'chart',
'labelKey' => 'LBL_QUICK_CHARTS',
'options' => [
'toggle' => true,
'headerTitle' => false,
'charts' => [
[
'chartKey' => 'accounts-new-by-month',
'chartType' => 'line-chart',
'statisticsType' => 'accounts-new-by-month',
'labelKey' => 'ACCOUNT_TYPES_PER_MONTH',
'chartOptions' => [
]
]
]
]
];
$container->setParameter('module.listview.sidebar_widgets', $widgets);

View file

@ -0,0 +1,158 @@
<?php
namespace App\Legacy\Statistics\Series;
use App\Entity\Statistic;
use App\Legacy\Data\ListDataQueryHandler;
use App\Legacy\LegacyHandler;
use App\Legacy\LegacyScopeState;
use App\Legacy\Statistics\StatisticsHandlingTrait;
use App\Model\Statistics\ChartOptions;
use App\Service\ModuleNameMapperInterface;
use App\Service\StatisticsProviderInterface;
use BeanFactory;
use SugarBean;
class AccountsNewByMonth extends LegacyHandler implements StatisticsProviderInterface
{
use StatisticsHandlingTrait;
public const KEY = 'accounts-new-by-month';
/**
* @var ListDataQueryHandler
*/
private $queryHandler;
/**
* @var ModuleNameMapperInterface
*/
private $moduleNameMapper;
/**
* LeadDaysOpen constructor.
* @param string $projectDir
* @param string $legacyDir
* @param string $legacySessionName
* @param string $defaultSessionName
* @param LegacyScopeState $legacyScopeState
* @param ListDataQueryHandler $queryHandler
* @param ModuleNameMapperInterface $moduleNameMapper
*/
public function __construct(
string $projectDir,
string $legacyDir,
string $legacySessionName,
string $defaultSessionName,
LegacyScopeState $legacyScopeState,
ListDataQueryHandler $queryHandler,
ModuleNameMapperInterface $moduleNameMapper
) {
parent::__construct($projectDir, $legacyDir, $legacySessionName, $defaultSessionName, $legacyScopeState);
$this->queryHandler = $queryHandler;
$this->moduleNameMapper = $moduleNameMapper;
}
/**
* @inheritDoc
*/
public function getHandlerKey(): string
{
return $this->getKey();
}
/**
* @inheritDoc
*/
public function getKey(): string
{
return self::KEY;
}
/**
* @inheritDoc
*/
public function getData(array $query): Statistic
{
[$module, $id, $criteria, $sort] = $this->extractContext($query);
if (empty($module) || $module !== 'accounts') {
return $this->getEmptySeriesResponse(self::KEY);
}
$this->init();
$this->startLegacyApp();
$legacyName = $this->moduleNameMapper->toLegacy($module);
$bean = $this->getBean($legacyName);
if (!$bean instanceof SugarBean) {
return $this->getEmptySeriesResponse(self::KEY);
}
$query = $this->queryHandler->getQuery($bean, $criteria, $sort);
$query = $this->generateQuery($query);
$result = $this->runQuery($query, $bean);
$nameField = 'month';
$valueField = 'value';
$groupingFields = 'name';
$months = $this->getMonths();
$series = $this->buildMultiSeries($result, $groupingFields, $nameField, $valueField, $months);
$chartOptions = new ChartOptions();
$chartOptions->yAxisTickFormatting = true;
$chartOptions->xAxisTicks = $months;
$statistic = $this->buildSeriesResponse(self::KEY, 'int', $series, $chartOptions);
$this->close();
return $statistic;
}
/**
* @param string $legacyName
* @return bool|SugarBean
*/
protected function getBean(string $legacyName)
{
return BeanFactory::newBean($legacyName);
}
/**
* @return array
*/
protected function getMonths(): array
{
return [1,2,3,4,5,6,7,8,9,10,11,12];
}
/**
* @param array $query
* @param $bean
* @return array
*/
protected function runQuery(array $query, $bean): array
{
// send limit -2 to not add a limit
return $this->queryHandler->runQuery($bean, $query);
}
/**
* @param array $query
* @return array
*/
protected function generateQuery(array $query): array
{
$query['select'] = 'SELECT COUNT(accounts.name) as value, EXTRACT(MONTH FROM accounts.date_entered) as month, accounts.account_type as name';
$query['where'] .= ' AND accounts.account_type is not null ';
$query['order_by'] = '';
$query['group_by'] = ' GROUP BY EXTRACT(MONTH FROM accounts.date_entered), accounts.account_type';
return $query;
}
}

View file

@ -0,0 +1,59 @@
<?php
namespace App\Tests\_mock\Mock\core\legacy\Statistics\Series;
use App\Legacy\Statistics\Series\AccountsNewByMonth;
use App\Tests\_mock\Helpers\core\legacy\Data\DBQueryResultsMocking;
use SugarBean;
/**
* Class AccountsNewByMonthMock
* @package Mock\Core\Legacy\Statistics\Series
*/
class AccountsNewByMonthMock extends AccountsNewByMonth
{
use DBQueryResultsMocking;
/**
* @var SugarBean
*/
public $bean;
/**
* @inheritDoc
*/
protected function getBean(string $legacyName)
{
return $this->bean;
}
/**
* @param SugarBean $bean
*/
public function setBean(SugarBean $bean): void
{
$this->bean = $bean;
}
protected function startLegacyApp(): void
{
}
/**
* @inheritDoc
*/
protected function runQuery(array $query, $bean): array
{
return $this->getAllMockQueryResults();
}
/**
* @inheritDoc
*/
protected function generateQuery(array $query): array
{
return [
'where'
];
}
}

View file

@ -0,0 +1,166 @@
<?php
namespace App\Tests\unit\core\legacy\Statistics\Series;
use App\Legacy\Data\FilterMapper\FilterMappers;
use App\Legacy\Data\RecordMapper;
use App\Legacy\ModuleNameMapperHandler;
use App\Legacy\Data\FilterMapper\LegacyFilterMapper;
use App\Tests\_mock\Mock\core\legacy\Data\ListDataQueryHandlerMock;
use App\Tests\_mock\Mock\core\legacy\Statistics\Series\AccountsNewByMonthMock;
use App\Tests\UnitTester;
use BeanFactory;
use Codeception\Test\Unit;
use EmptyIterator;
use Exception;
/**
* Class AccountsNewByMonthTest
* @package App\Tests
*/
class AccountsNewByMonthTest extends Unit
{
/**
* @var UnitTester
*/
protected $tester;
/**
* @var AccountsNewByMonthMock
*/
private $handler;
/**
* @throws Exception
*/
protected function _before(): void
{
$projectDir = $this->tester->getProjectDir();
$legacyDir = $this->tester->getLegacyDir();
$legacySessionName = $this->tester->getLegacySessionName();
$defaultSessionName = $this->tester->getDefaultSessionName();
$legacyScope = $this->tester->getLegacyScope();
$moduleNameMapper = new ModuleNameMapperHandler(
$projectDir,
$legacyDir,
$legacySessionName,
$defaultSessionName,
$legacyScope
);
$filterMappers = new FilterMappers(new EmptyIterator());
$legacyFilterMapper = new LegacyFilterMapper([], $filterMappers);
$recordMapper = new RecordMapper($moduleNameMapper);
$queryHandler = new ListDataQueryHandlerMock($legacyFilterMapper, $recordMapper);
$this->handler = new AccountsNewByMonthMock(
$projectDir,
$legacyDir,
$legacySessionName,
$defaultSessionName,
$legacyScope,
$queryHandler,
$moduleNameMapper
);
}
/**
* Test Unsupported context module
* @throws Exception
*/
public function testUnsupportedContextModule(): void
{
$this->handler->reset();
$this->handler->setBean(BeanFactory::newBean('Accounts'));
$result = $this->handler->getData(
[
'context' => [
'id' => '12345',
'modules' => 'contacts'
]
]
);
static::assertNotNull($result);
static::assertNotNull($result->getData());
static::assertNotNull($result->getMetadata());
static::assertIsArray($result->getData());
static::assertIsArray($result->getMetadata());
static::assertEquals('accounts-new-by-month', $result->getId());
static::assertArrayHasKey('type', $result->getMetadata());
static::assertEquals('series-statistic', $result->getMetadata()['type']);
static::assertArrayHasKey('dataType', $result->getMetadata());
static::assertEquals('int', $result->getMetadata()['dataType']);
static::assertArrayHasKey('multiSeries', $result->getData());
static::assertArrayHasKey('singleSeries', $result->getData());
static::assertEquals([], $result->getData()['multiSeries']);
static::assertEquals([], $result->getData()['singleSeries']);
}
/**
* Test get Total response
* @throws Exception
*/
public function testGetCreatedAccounts(): void
{
$this->handler->reset();
$this->handler->setBean(BeanFactory::newBean('Accounts'));
$rows = [
[
"name" => 'Customer',
"month" => '11',
"value" => '12'
]
];
$this->handler->setMockQueryResult($rows);
$expectedResult = [
0 => [
'name' => 'Customer',
'series' => [
['name' => 1, 'value' => '0'],
['name' => 2, 'value' => '0'],
['name' => 3, 'value' => '0'],
['name' => 4, 'value' => '0'],
['name' => 5, 'value' => '0'],
['name' => 6, 'value' => '0'],
['name' => 7, 'value' => '0'],
['name' => 8, 'value' => '0'],
['name' => 9, 'value' => '0'],
['name' => 10, 'value' => '0'],
['name' => 11, 'value' => '12'],
['name' => 12, 'value' => '0']
]
]
];
$result = $this->handler->getData(
[
'context' => [
'module' => 'accounts',
'id' => '12345',
]
]
);
static::assertNotNull($result);
static::assertNotNull($result->getData());
static::assertNotNull($result->getMetadata());
static::assertIsArray($result->getData());
static::assertIsArray($result->getMetadata());
static::assertArrayHasKey('multiSeries', $result->getData());
static::assertEquals($expectedResult, $result->getData()['multiSeries']);
static::assertEquals('accounts-new-by-month', $result->getId());
static::assertArrayHasKey('type', $result->getMetadata());
static::assertEquals('series-statistic', $result->getMetadata()['type']);
static::assertArrayHasKey('dataType', $result->getMetadata());
static::assertEquals('int', $result->getMetadata()['dataType']);
}
}