config = $configuration; // @TODO generalize tracking service. $this->trackingService = $tracking_service; $this->csv = $csv; parent::__construct($name); } protected function configure() :void { $this->setName('report'); $this->setDescription('Get a time-tracking report into command line.'); $this->addOption( 'report', 'r', InputOption::VALUE_OPTIONAL, 'Select a report from list of your reports' ); $this->addOption( 'time-range', 't', InputOption::VALUE_REQUIRED, 'Calculates report from tracking service work items directly for time range' ); } protected function execute(InputInterface $input, OutputInterface $output) :int { if ($timeRange = $input->getOption('time-range')) { // @TODO: Implement time range option: // - Request workTime items from tracking service // - Filter them, join by issue, project ... if ($output->isVerbose()) { $output->writeln("Time range: {$timeRange}"); } $output->writeln('This option is not supported yet.'); return Command::FAILURE; } $reports = $this->trackingService->listReports(); // Could just parse a csv file or actually get workItems from youtrack ... if ($input->hasParameterOption('--report') || $input->hasParameterOption('-r')) { if ($report = $input->getOption('report')) { $this->trackingService->setReportId($report); } else { $count = 1; foreach ($reports as $id => $name) { $output->writeln("[{$count}] {$name} ({$id})"); $count++; } $output->writeln("[{$count}] None (null)"); $report = readline('Select id of the report: '); // Asume people are literate. if (!in_array($report, array_keys($reports) )) { $output->writeln('Non-existing report. Exiting.'); return Command::SUCCESS; } $this->trackingService->setReportId($report); } } elseif ($report = $this->config->get('tracking_service.youtrack.report.default')) { $this->trackingService->setReportId($report); } // Currently we only support csv download. $report_id = $this->trackingService->getReportId(); $report_name = $reports[$report_id]; // Code duplication. $cache_clear_status = $this->trackingService->clearReportCache($report_id); if ($output->isVerbose()) { $output->writeln("Report cache cleared, status: {$cache_clear_status}"); } $file = $this->trackingService->downloadReport($report_id); if ($output->isVerbose()) { $output->writeln("Csv file downloaded to: {$file}"); } $output->writeln("report: {$report_name}"); $data = $this->csv->generateReportTable($file); $table = $this->buildTable($output, $data); $table->render(); return Command::SUCCESS; } /** * Builds table from the report csv data. * * @TODO: Code duplication with InvoiceCommand::getTable. */ protected function buildTable(OutputInterface $output, array $rows): Table { $table = new Table($output); $table->setHeaders([ 'Ticket Id', 'Name', 'Time', 'Estimation', ]); foreach ($rows as $key => $row) { if (!$row) { $rows[$key] = new TableSeparator(); } elseif (is_array($row) && is_null($row[0]) && is_null($row[2])) { // Check which elements in array are null. $rows[$key] = [new TableCell($row[1], ['colspan' => 2]), new TableCell((string) $row[3], ['colspan' => 2])]; } } $table->setRows($rows); return $table; } }