From e9b9819e7d7191ab88e7bcd2642bcc634eec9a3e Mon Sep 17 00:00:00 2001 From: Jack Anderson Date: Wed, 6 Jan 2021 08:56:43 +0000 Subject: [PATCH] Accounts Chart Implementation --- .../accounts/listview/sidebar_widgets.php | 39 ++++ .../Statistics/Series/AccountsNewByMonth.php | 158 +++++++++++++++++ .../Series/AccountsNewByMonthMock.php | 59 +++++++ .../Series/AccountsNewByMonthTest.php | 166 ++++++++++++++++++ 4 files changed, 422 insertions(+) create mode 100644 config/modules/accounts/listview/sidebar_widgets.php create mode 100644 core/legacy/Statistics/Series/AccountsNewByMonth.php create mode 100644 tests/_mock/Mock/core/legacy/Statistics/Series/AccountsNewByMonthMock.php create mode 100644 tests/unit/core/legacy/Statistics/Series/AccountsNewByMonthTest.php diff --git a/config/modules/accounts/listview/sidebar_widgets.php b/config/modules/accounts/listview/sidebar_widgets.php new file mode 100644 index 000000000..024901866 --- /dev/null +++ b/config/modules/accounts/listview/sidebar_widgets.php @@ -0,0 +1,39 @@ +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); diff --git a/core/legacy/Statistics/Series/AccountsNewByMonth.php b/core/legacy/Statistics/Series/AccountsNewByMonth.php new file mode 100644 index 000000000..42f6de115 --- /dev/null +++ b/core/legacy/Statistics/Series/AccountsNewByMonth.php @@ -0,0 +1,158 @@ +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; + } +} diff --git a/tests/_mock/Mock/core/legacy/Statistics/Series/AccountsNewByMonthMock.php b/tests/_mock/Mock/core/legacy/Statistics/Series/AccountsNewByMonthMock.php new file mode 100644 index 000000000..85f40e952 --- /dev/null +++ b/tests/_mock/Mock/core/legacy/Statistics/Series/AccountsNewByMonthMock.php @@ -0,0 +1,59 @@ +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' + ]; + } +} diff --git a/tests/unit/core/legacy/Statistics/Series/AccountsNewByMonthTest.php b/tests/unit/core/legacy/Statistics/Series/AccountsNewByMonthTest.php new file mode 100644 index 000000000..82c8a3827 --- /dev/null +++ b/tests/unit/core/legacy/Statistics/Series/AccountsNewByMonthTest.php @@ -0,0 +1,166 @@ +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']); + } +}