diff --git a/SOLUTION.md b/SOLUTION.md index defe675..b1f1ed2 100755 --- a/SOLUTION.md +++ b/SOLUTION.md @@ -1,13 +1,34 @@ -SOLUTION -======== +#ADITIONAL FUNCTIONALITY +======================== + +-- Add another report that shows view percentage increase/decrease for a certain designer from previous year. + +Estimation +---------- +Estimated: 2 hours + + +#ADITIONAL FUNCTIONALITY +======================== + +-- Add a column that sums up all the views of a given year + +Estimation +---------- +Estimated: 0.5 hours + + +#ADITIONAL FUNCTIONALITY +======================== + +-- Add the option to only display a certain designer via user prompt Estimation ---------- -Estimated: n hours +Estimated: 0.5 hours -Spent: x hours +#SOLUTION COMMENTS +================== -Solution --------- -Comments on your solution +Spent: 2 and a half hours. Would have been less if I wasn't on a MAC :) But I got the hang of it pretty fast. \ No newline at end of file diff --git a/TESTCASES.md b/TESTCASES.md new file mode 100644 index 0000000..373e750 --- /dev/null +++ b/TESTCASES.md @@ -0,0 +1,18 @@ +Test case 1: +Input argument "year": 2014 +- Check if the displayed data is correct. +- Check if all the profile names are displayed and in the correct ascending order. +- Check if n/a is displayed where there is no data availiable. + +Test case 2: +Input argument "year": empty or int value is equal to 0 +- User is prompted with all the availiable year's that actually have populated records in the views table. +From user prompt select year 2014 and then proceed with the same checks as in Test case 1. + +Test case 3: +Input argument "year": invalid (example: 2008) +- Check if error message is displayed. + +Test case 4: +Input argument "year": -12312312 +- Check if it returns an exception. \ No newline at end of file diff --git a/src/Command/ReportYearlyCommand.php b/src/Command/ReportYearlyCommand.php index 97f026f..d88c07d 100755 --- a/src/Command/ReportYearlyCommand.php +++ b/src/Command/ReportYearlyCommand.php @@ -2,6 +2,7 @@ namespace BOF\Command; use Doctrine\DBAL\Driver\Connection; +use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; @@ -9,11 +10,25 @@ class ReportYearlyCommand extends ContainerAwareCommand { + + private static $outputHeaderMonths = [1,2,3,4,5,6,7,8,9,10,11,12]; + + private function getOutputHeaderMonths() + { + return self::$outputHeaderMonths; + } + + private function getViewsDataNotAvailiableString() + { + return "n/a"; + } + protected function configure() { $this ->setName('report:profiles:yearly') ->setDescription('Page views report') + ->addArgument('year', InputArgument::OPTIONAL, 'Please input the year you wish the report to be generated for.') ; } @@ -22,11 +37,81 @@ protected function execute(InputInterface $input, OutputInterface $output) /** @var $db Connection */ $io = new SymfonyStyle($input,$output); $db = $this->getContainer()->get('database_connection'); + + $inputYear = $input->getArgument('year'); + if (intval($inputYear) === 0) { + $displayDataValidYears = $db->query('SELECT YEAR(v.date) AS date_year FROM profiles p JOIN views v ON v.profile_id = p.profile_id WHERE v.views > "0" AND v.views IS NOT NULL GROUP BY YEAR(v.date) ORDER BY YEAR(v.date) DESC')->fetchAll(); + + $yearChoices = []; + foreach ($displayDataValidYears as $displayDataValidYear) { + $yearChoices[] = $displayDataValidYear['date_year']; + } + + if (count($yearChoices)) { + $inputYear = $io->choice('For which year would you like to display the report?', $yearChoices, $yearChoices[0]); + } else { + $io->caution("Error! There is no data availiable!"); + } + + } + + $profiles = $db->query('SELECT p.profile_name, MONTH(v.date) as date_month, SUM(v.views) AS sum_views FROM profiles p JOIN views v ON v.profile_id = p.profile_id WHERE v.date >= "'.$inputYear.'-01-01" AND v.date <= "'.$inputYear.'-12-31" GROUP BY p.profile_name, MONTH(v.date) ORDER BY p.profile_name ASC')->fetchAll(); + + $outputHeader = ['Profile '.$inputYear]; + foreach ($this->getOutputHeaderMonths() as $outputHeaderMonth) { + $outputHeader[] = date('M', strtotime("2019-".str_pad($outputHeaderMonth, 2, "0", STR_PAD_LEFT)."-01")); + } - $profiles = $db->query('SELECT profile_name FROM profiles')->fetchAll(); + $outputData = []; + foreach ($profiles as $profile) { + $this->newOutputDataProfileEntry($outputData, $profile['profile_name']); - // Show data in a table - headers, data - $io->table(['Profile'], $profiles); + if (!isset($outputData[$profile['profile_name']][$profile['date_month']])) { + $outputData[$profile['profile_name']][$profile['date_month']] = $profile['sum_views']; + } else { + $outputData[$profile['profile_name']][$profile['date_month']] += $profile['sum_views']; + } + + } + if (count($outputData) === 0) { + $io->caution("No data exists for the chosen year!"); + } else { + $this->checkOutputData($outputData); + + $io->table($outputHeader, $outputData); + } + + + } + + private function newOutputDataProfileEntry(&$outputData, $profileName) + { + if (!is_array($outputData) || trim($profileName) === "") { + return; + } + + if (!isset($outputData[$profileName])) { + $outputData[$profileName] = [ + 'profile_name' => $profileName, + ]; + + foreach ($this->getOutputHeaderMonths() as $outputHeaderMonth) { + $outputData[$profileName][$outputHeaderMonth] = 0; + } + } + } + + private function checkOutputData(&$outputData) + { + if (is_array($outputData) && count($outputData)) { + foreach ($outputData as $keyProfileName => $valData) { + foreach ($this->getOutputHeaderMonths() as $outputHeaderMonth) { + if (!isset($valData[$outputHeaderMonth]) || $valData[$outputHeaderMonth] === 0) { + $outputData[$keyProfileName][$outputHeaderMonth] = $this->getViewsDataNotAvailiableString(); + } + } + } + } } }