EventsReportCommand.php 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. <?php
  2. declare(strict_types = 1);
  3. namespace Avolver\CompanyEventsKitchen\Command;
  4. use Avolver\CompanyEventsKitchen\Application;
  5. use Avolver\CompanyEventsKitchen\Event\CompanyEvent;
  6. use Avolver\CompanyEventsKitchen\Repository\EventsRepository;
  7. use Avolver\CompanyEventsKitchen\Transformer\MonthEventsReportTransformer;
  8. use MongoDB\BSON\ObjectId;
  9. use Gregwar\GnuPlot\GnuPlot;
  10. use Symfony\Component\Console\Command\Command;
  11. use Symfony\Component\Console\Helper\Table;
  12. use Symfony\Component\Console\Input\InputInterface;
  13. use Symfony\Component\Console\Input\InputOption;
  14. use Symfony\Component\Console\Output\OutputInterface;
  15. /**
  16. * Команда для получения отчёта по событиям для конкретной компании
  17. *
  18. * @method Application getApplication
  19. *
  20. * @package Avolver\CompanyEventsKitchen\Command
  21. */
  22. class EventsReportCommand extends Command
  23. {
  24. private const FORMAT_TABLE = 'table';
  25. private const FORMAT_GRAPH = 'graph';
  26. /**
  27. * {@inheritdoc}
  28. */
  29. protected function configure(): void
  30. {
  31. $formats = implode(', ', [self::FORMAT_TABLE, self::FORMAT_GRAPH]);
  32. $this
  33. ->setName('events-report')
  34. ->setDescription('Создание случайных событий для каждой компании')
  35. ->addOption('company-id', null, InputOption::VALUE_REQUIRED, 'ID компании')
  36. ->addOption('month', null, InputOption::VALUE_OPTIONAL, 'Месяц')
  37. ->addOption('year', null, InputOption::VALUE_REQUIRED, 'Год')
  38. ->addOption('format', null, InputOption::VALUE_OPTIONAL, 'Тип вывода: ' . $formats, self::FORMAT_TABLE);
  39. }
  40. /**
  41. * {@inheritdoc}
  42. */
  43. protected function execute(InputInterface $input, OutputInterface $output)
  44. {
  45. $eventsRepo = new EventsRepository(
  46. $this->getApplication()->getClickhouseClient()
  47. );
  48. if (!$input->getOption('company-id')) {
  49. throw new \InvalidArgumentException('Не указан идентификатор компании');
  50. }
  51. $today = new \DateTime();
  52. $month = $input->getOption('month') ?: (int) $today->format('m');
  53. $year = $input->getOption('year') ?: (int) $today->format('Y');
  54. $result = $eventsRepo->findEventsByCompanyId(
  55. new ObjectId($input->getOption('company-id')),
  56. $month,
  57. $year
  58. );
  59. $result = MonthEventsReportTransformer::transform($result);
  60. switch ($input->getOption('format')) {
  61. case self::FORMAT_TABLE:
  62. $this->renderTable($output, $result);
  63. break;
  64. case self::FORMAT_GRAPH:
  65. $this->renderGraph($result);
  66. break;
  67. default:
  68. throw new \InvalidArgumentException('Некорректный формат вывода');
  69. }
  70. }
  71. /**
  72. * Вывод таблицы с событиями
  73. *
  74. * @param OutputInterface $output
  75. * @param array $result
  76. */
  77. private function renderTable(OutputInterface $output, array $result): void
  78. {
  79. $eventTypes = CompanyEvent::keys();
  80. $rows = [];
  81. foreach ($result as $date => $counts) {
  82. $row = [$date];
  83. foreach ($eventTypes as $eventType) {
  84. $row[] = $counts[$eventType] ?? '0';
  85. }
  86. $rows[] = $row;
  87. }
  88. $table = new Table($output);
  89. $table
  90. ->setHeaders(array_merge(['Дата'], $eventTypes))
  91. ->setRows($rows);
  92. $table->render();
  93. }
  94. /**
  95. * Сохранение графика
  96. *
  97. * @param array $result
  98. */
  99. public function renderGraph(array $result)
  100. {
  101. $eventTypes = CompanyEvent::keys();
  102. $plot = (new GnuPlot())
  103. ->setXTimeFormat('%Y-%m-%d')
  104. ->setXLabel('Дата')
  105. ->setYLabel('Количество')
  106. ->setWidth(640);
  107. foreach ($eventTypes as $eventIndex => $eventType) {
  108. $plot->setTitle($eventIndex, $eventType);
  109. }
  110. foreach ($result as $date => $counts) {
  111. foreach ($eventTypes as $eventIndex => $eventType) {
  112. $plot->push($date, $counts[$eventType] ?? '0', $eventIndex);
  113. }
  114. }
  115. echo $plot->get();
  116. }
  117. }