Fix phpstan errors, improve automated test.
parent
624b895fd6
commit
99d16c3a72
|
@ -36,7 +36,8 @@
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"cs": "phpcs --colors --standard=PSR12",
|
"cs": "phpcs --colors --standard=PSR12",
|
||||||
"cbf": "phpcbf"
|
"cbf": "phpcbf",
|
||||||
|
"phpstan": "phpstan analyze -l 5 src"
|
||||||
},
|
},
|
||||||
"config": {
|
"config": {
|
||||||
"allow-plugins": {
|
"allow-plugins": {
|
||||||
|
|
|
@ -27,6 +27,7 @@ use function explode;
|
||||||
use function is_array;
|
use function is_array;
|
||||||
use function is_null;
|
use function is_null;
|
||||||
use function is_string;
|
use function is_string;
|
||||||
|
use function PHPUnit\Framework\throwException;
|
||||||
use function readline;
|
use function readline;
|
||||||
use function strpos;
|
use function strpos;
|
||||||
use function strtolower;
|
use function strtolower;
|
||||||
|
@ -42,13 +43,15 @@ class InvoiceCommand extends Command
|
||||||
{
|
{
|
||||||
use SelectReportTrait;
|
use SelectReportTrait;
|
||||||
|
|
||||||
protected $csv;
|
protected ReportCsvInterface $csv;
|
||||||
|
|
||||||
protected $config;
|
protected ConfigurationInterface $config;
|
||||||
|
|
||||||
protected $youtrack;
|
protected YoutrackInterface $trackingService;
|
||||||
|
|
||||||
protected $pdfExport;
|
protected PdfExportInterface $pdfExport;
|
||||||
|
|
||||||
|
protected MailerInterface $mailer;
|
||||||
|
|
||||||
protected const TYPE_WORK = 1;
|
protected const TYPE_WORK = 1;
|
||||||
protected const TYPE_EXPENSE = 2;
|
protected const TYPE_EXPENSE = 2;
|
||||||
|
@ -185,11 +188,11 @@ class InvoiceCommand extends Command
|
||||||
if ($out = $input->getOption('output')) {
|
if ($out = $input->getOption('output')) {
|
||||||
$this->pdfExport->setOutput($out);
|
$this->pdfExport->setOutput($out);
|
||||||
}
|
}
|
||||||
$output_path = $this->pdfExport->fromDefaultDataToPdf($nice_data);
|
$output_path = $this->pdfExport->fromDefaultDataToPdf($nice_data) ?: sys_get_temp_dir();
|
||||||
// Notify the user where the file was generated to.
|
// Notify the user where the file was generated to.
|
||||||
$output->writeln("The file was generated at <info>${output_path}</info>.");
|
$output->writeln("The file was generated at <info>${output_path}</info>.");
|
||||||
}
|
}
|
||||||
if ($input->getOption('send') && $output_path) {
|
if ($input->getOption('send') && isset($output_path)) {
|
||||||
// @TODO If no output path print an error.
|
// @TODO If no output path print an error.
|
||||||
// Send email to configured address.
|
// Send email to configured address.
|
||||||
if ($recipients = $input->getOption('recipients')) {
|
if ($recipients = $input->getOption('recipients')) {
|
||||||
|
@ -273,7 +276,7 @@ class InvoiceCommand extends Command
|
||||||
$rows[] = new TableSeparator();
|
$rows[] = new TableSeparator();
|
||||||
// @TODO Check rate in final result.
|
// @TODO Check rate in final result.
|
||||||
// $rows[] = [$this->translator->trans('Sum'), $totalHours, $config['price'], $totalPrice];
|
// $rows[] = [$this->translator->trans('Sum'), $totalHours, $config['price'], $totalPrice];
|
||||||
$rows[] = ['Sum', $totalHours, $config['price'], $totalPrice];
|
$rows[] = ['Sum', $totalHours, NULL, $totalPrice];
|
||||||
|
|
||||||
$table->setRows($rows);
|
$table->setRows($rows);
|
||||||
return $table;
|
return $table;
|
||||||
|
@ -326,7 +329,7 @@ class InvoiceCommand extends Command
|
||||||
return $output;
|
return $output;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getCustomWorkOrExpenses($custom, $type)
|
protected function getCustomWorkOrExpenses(mixed $custom, int $type)
|
||||||
{
|
{
|
||||||
$output = [];
|
$output = [];
|
||||||
if (is_string($custom)) {
|
if (is_string($custom)) {
|
||||||
|
@ -343,6 +346,9 @@ class InvoiceCommand extends Command
|
||||||
$message_name = 'Enter expenses name or leave empty to stop: ';
|
$message_name = 'Enter expenses name or leave empty to stop: ';
|
||||||
$message_value = 'Enter expenses value: ';
|
$message_value = 'Enter expenses value: ';
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
throw new \Exception('Unknown type of custom data.');
|
||||||
|
}
|
||||||
while ($continue) {
|
while ($continue) {
|
||||||
$name = readline($message_name);
|
$name = readline($message_name);
|
||||||
$value = (float) readline($message_value);
|
$value = (float) readline($message_value);
|
||||||
|
|
|
@ -22,11 +22,11 @@ class ReportCommand extends Command
|
||||||
{
|
{
|
||||||
use SelectReportTrait;
|
use SelectReportTrait;
|
||||||
|
|
||||||
protected $trackingService;
|
protected YoutrackInterface $trackingService;
|
||||||
|
|
||||||
protected $config;
|
protected ConfigurationInterface $config;
|
||||||
|
|
||||||
protected $csv;
|
protected ReportCsvInterface $csv;
|
||||||
|
|
||||||
// phpcs:ignore
|
// phpcs:ignore
|
||||||
public function __construct(ConfigurationInterface $configuration, YoutrackInterface $tracking_service, ReportCsvInterface $csv, ?string $name = null)
|
public function __construct(ConfigurationInterface $configuration, YoutrackInterface $tracking_service, ReportCsvInterface $csv, ?string $name = null)
|
||||||
|
|
|
@ -114,8 +114,8 @@ class CsvReport implements CsvReportInterface
|
||||||
$rows[] = [
|
$rows[] = [
|
||||||
'Gesamt netto',
|
'Gesamt netto',
|
||||||
number_format($totalHours, 2, ',', '.'),
|
number_format($totalHours, 2, ',', '.'),
|
||||||
number_format($config['price'], 2, ',', '.'),
|
NULL,
|
||||||
number_format($totalPrice, 2, ',', '.')
|
number_format($totalPrice, 2, ',', '.'),
|
||||||
];
|
];
|
||||||
$rows[] = [null, null, 'Gessamt brutto', number_format($totalPrice, 2, ',', '.')];
|
$rows[] = [null, null, 'Gessamt brutto', number_format($totalPrice, 2, ',', '.')];
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,8 @@ namespace RprtCli\Utils\CsvReport;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles creating report data from csv file downloaded from youtrack service.
|
* Handles creating report data from csv file downloaded from youtrack service.
|
||||||
|
*
|
||||||
|
* @deprecated Use ReportCsv instead.
|
||||||
*/
|
*/
|
||||||
interface CsvReportInterface
|
interface CsvReportInterface
|
||||||
{
|
{
|
||||||
|
|
|
@ -98,11 +98,11 @@ class ReportCsv implements ReportCsvInterface
|
||||||
{
|
{
|
||||||
[$rows, $totalHours, $totalPrice, $add_separator] = [[], 0, 0, false];
|
[$rows, $totalHours, $totalPrice, $add_separator] = [[], 0, 0, false];
|
||||||
$projectsConfig = $this->configurationService->get('projects');
|
$projectsConfig = $this->configurationService->get('projects');
|
||||||
|
// @TODO Remove unnecessary header after check.
|
||||||
// $header = $this->configurationService->get('export.labels', null);
|
// $header = $this->configurationService->get('export.labels', null);
|
||||||
$header = null;
|
// if (is_array($header)) {
|
||||||
if (is_array($header)) {
|
// $rows[] = $header;
|
||||||
$rows[] = $header;
|
// }
|
||||||
}
|
|
||||||
// First only list work invoice elements.
|
// First only list work invoice elements.
|
||||||
foreach ($data as $key => $invoice_element) {
|
foreach ($data as $key => $invoice_element) {
|
||||||
if ($invoice_element instanceof WorkInvoiceElementInterface) {
|
if ($invoice_element instanceof WorkInvoiceElementInterface) {
|
||||||
|
@ -186,7 +186,10 @@ class ReportCsv implements ReportCsvInterface
|
||||||
return $rows;
|
return $rows;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function generateReportTable(string $filePath)
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function generateReportTable(string $filePath): array
|
||||||
{
|
{
|
||||||
// ticket-id, ticket-name, time-spent
|
// ticket-id, ticket-name, time-spent
|
||||||
$data = $this->parseReportData($filePath);
|
$data = $this->parseReportData($filePath);
|
||||||
|
|
|
@ -48,4 +48,6 @@ interface ReportCsvInterface
|
||||||
* Parsed data from csv report.
|
* Parsed data from csv report.
|
||||||
*/
|
*/
|
||||||
public function arangeDataForDefaultPdfExport(array $data): array;
|
public function arangeDataForDefaultPdfExport(array $data): array;
|
||||||
|
|
||||||
|
public function generateReportTable(string $filePath): array;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,17 @@ namespace RprtCli\Utils\Mailer;
|
||||||
/**
|
/**
|
||||||
* Methods for symfony (swift)mailer service.
|
* Methods for symfony (swift)mailer service.
|
||||||
*/
|
*/
|
||||||
interface MailerInterface
|
interface MailerInterface {
|
||||||
{
|
|
||||||
|
/**
|
||||||
|
* Recipients for message.
|
||||||
|
*
|
||||||
|
* @param string[] $to
|
||||||
|
*/
|
||||||
|
public function setRecipients(array $to): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends default mail.
|
||||||
|
*/
|
||||||
|
public function sendDefaultMail(string $output): void;
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,6 +46,8 @@ class MailerService implements MailerInterface
|
||||||
|
|
||||||
protected $email;
|
protected $email;
|
||||||
|
|
||||||
|
protected string $password;
|
||||||
|
|
||||||
public function __construct(ConfigurationInterface $config, PdfExportInterface $pdf)
|
public function __construct(ConfigurationInterface $config, PdfExportInterface $pdf)
|
||||||
{
|
{
|
||||||
$this->config = $config;
|
$this->config = $config;
|
||||||
|
|
|
@ -69,6 +69,7 @@ class PdfExportService implements PdfExportInterface
|
||||||
$table = '<table><thead><tr class="tr-header">';
|
$table = '<table><thead><tr class="tr-header">';
|
||||||
$header = array_shift($data);
|
$header = array_shift($data);
|
||||||
$classes = '';
|
$classes = '';
|
||||||
|
$rows = [];
|
||||||
foreach ($header as $index => $cell) {
|
foreach ($header as $index => $cell) {
|
||||||
$table .= "<th class=\"th-{$index}\">{$cell}</th>";
|
$table .= "<th class=\"th-{$index}\">{$cell}</th>";
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,4 +40,9 @@ interface YoutrackInterface
|
||||||
public function setReportName(?string $report_name = null): void;
|
public function setReportName(?string $report_name = null): void;
|
||||||
|
|
||||||
public function getReportName(): ?string;
|
public function getReportName(): ?string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears cache for youtrack report.
|
||||||
|
*/
|
||||||
|
public function clearReportCache(string $report_id): int;
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,9 @@ class ReportCommandTest extends TestCase {
|
||||||
|
|
||||||
protected const INVOICE_OUTPUT_PDF = __DIR__ . '/../data/output/Invoice-test.pdf';
|
protected const INVOICE_OUTPUT_PDF = __DIR__ . '/../data/output/Invoice-test.pdf';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run report and invoice command with file option parameter. Check if pdf was generated.
|
||||||
|
*/
|
||||||
public function testExecute() {
|
public function testExecute() {
|
||||||
$builder = new ContainerBuilder();
|
$builder = new ContainerBuilder();
|
||||||
$builder->addDefinitions(__DIR__ . '/../test-dependencies.php');
|
$builder->addDefinitions(__DIR__ . '/../test-dependencies.php');
|
||||||
|
@ -60,29 +63,25 @@ class ReportCommandTest extends TestCase {
|
||||||
$this->assertStringContainsString('21-03.csv', $output);
|
$this->assertStringContainsString('21-03.csv', $output);
|
||||||
$this->assertStringEqualsFile(self::REPORT_OUTPUT_FILE, $output);
|
$this->assertStringEqualsFile(self::REPORT_OUTPUT_FILE, $output);
|
||||||
|
|
||||||
|
if (file_exists(self::INVOICE_OUTPUT_PDF)) {
|
||||||
|
unlink(self::INVOICE_OUTPUT_PDF);
|
||||||
|
}
|
||||||
$invoiceCommand = $application->find('invoice');
|
$invoiceCommand = $application->find('invoice');
|
||||||
$invoiceCommandTester = new CommandTester($invoiceCommand);
|
$invoiceCommandTester = new CommandTester($invoiceCommand);
|
||||||
$invoiceCommandTester->execute([
|
$invoiceCommandTester->execute([
|
||||||
'--file' => self::INPUT_CSV_FILE,
|
'--file' => self::INPUT_CSV_FILE,
|
||||||
'--pdf' => TRUE,
|
'--pdf' => TRUE,
|
||||||
|
'--output' => self::INVOICE_OUTPUT_PDF,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$invoiceCommandTester->assertCommandIsSuccessful();
|
$invoiceCommandTester->assertCommandIsSuccessful();
|
||||||
|
|
||||||
// the output of the command in the console
|
// the output of the command in the console
|
||||||
$invoice_output = $invoiceCommandTester->getDisplay();
|
$invoice_output = $invoiceCommandTester->getDisplay();
|
||||||
var_dump($invoice_output);
|
// var_dump($invoice_output);
|
||||||
$this->assertStringContainsString('21-03.csv', $invoice_output);
|
$this->assertStringContainsString('21-03.csv', $invoice_output);
|
||||||
$this->assertStringEqualsFile(self::INVOICE_OUTPUT_FILE, $invoice_output);
|
$this->assertStringEqualsFile(self::INVOICE_OUTPUT_FILE, $invoice_output);
|
||||||
|
$this->assertFileExists(self::INVOICE_OUTPUT_PDF);
|
||||||
// $invoiceCommandTester->execute([
|
|
||||||
// '--file' => self::INPUT_CSV_FILE,
|
|
||||||
// '--pdf'
|
|
||||||
// ]);
|
|
||||||
// $invoice_output = $invoiceCommandTester->getDisplay();
|
|
||||||
// var_dump($invoice_output);
|
|
||||||
// $this->assertFileExists();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,3 +9,4 @@ report: /home/lio/Projects/drunomix/rprt-cli/app/tests/Kernel/../data/21-03.csv
|
||||||
+-----------------------------+--------+-------+----------+
|
+-----------------------------+--------+-------+----------+
|
||||||
| Gessamt brutto | 4.505,35 |
|
| Gessamt brutto | 4.505,35 |
|
||||||
+-----------------------------+--------+-------+----------+
|
+-----------------------------+--------+-------+----------+
|
||||||
|
The file was generated at /home/lio/Projects/drunomix/rprt-cli/app/tests/Kernel/../data/output/Invoice-test.pdf.
|
||||||
|
|
12
todo.txt
12
todo.txt
|
@ -1,5 +1,4 @@
|
||||||
TODO:
|
TODO:
|
||||||
- nice report selection
|
|
||||||
- clean up the config (default reports)
|
- clean up the config (default reports)
|
||||||
- Improve readme
|
- Improve readme
|
||||||
- abstract baseCommand with some input params
|
- abstract baseCommand with some input params
|
||||||
|
@ -8,13 +7,9 @@ TODO:
|
||||||
- in dependencies.php find subdependencies.php
|
- in dependencies.php find subdependencies.php
|
||||||
- Create interface for 3rd party service integration and abstract class
|
- Create interface for 3rd party service integration and abstract class
|
||||||
- Create factory to add correct service of a 3rd party service to the Command
|
- Create factory to add correct service of a 3rd party service to the Command
|
||||||
- separator constant
|
|
||||||
------------------------
|
------------------------
|
||||||
- add plugin system for time tracking service
|
- add plugin system for time tracking service
|
||||||
- add tests
|
|
||||||
------------------------
|
------------------------
|
||||||
- question helper: https://symfony.com/doc/current/components/console/helpers/questionhelper.html
|
|
||||||
- psr-12 code check and add phpstan https://phpstan.org/user-guide/getting-started
|
|
||||||
- phing for build automation
|
- phing for build automation
|
||||||
- add ddev for dockerization
|
- add ddev for dockerization
|
||||||
|
|
||||||
|
@ -32,6 +27,7 @@ OPTIONAL:
|
||||||
- youtrack
|
- youtrack
|
||||||
- jira
|
- jira
|
||||||
- kimai
|
- kimai
|
||||||
|
- build phar without most of the fonts
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -44,4 +40,8 @@ DONE:
|
||||||
- upload a phar file on repo
|
- upload a phar file on repo
|
||||||
- create release
|
- create release
|
||||||
- clear report cache
|
- clear report cache
|
||||||
|
- nice report selection
|
||||||
|
- separator constant
|
||||||
|
- add tests
|
||||||
|
- psr-12 code check and add phpstan https://phpstan.org/user-guide/getting-started
|
||||||
|
- question helper: https://symfony.com/doc/current/components/console/helpers/questionhelper.html
|
||||||
|
|
Loading…
Reference in New Issue