Initial commit of the monthly report command.

master
Lio Novelli 2021-04-04 22:41:15 +02:00
commit c833741939
7 changed files with 1377 additions and 0 deletions

1
.gitignore vendored 100644
View File

@ -0,0 +1 @@
/app/vendor

65
README.org 100644
View File

@ -0,0 +1,65 @@
* Report cli
Automate generating invoices.
** Usage
** Install/Getting started
Get ~.phar~ file, run configuration wizzard.
** Specs
A simple Console Command that prints out monthly report from youtrack.
Simple configuration:
- authentication token value
- project categories
- hourly wage
- folder for reports
** Components
- report service - provides a csv of a report
- local csv file read (provided via argument)
- youtrack api request (with [[https://docs.guzzlephp.org/en/stable/][Guzzle]] and [[https://github.com/cybercog/youtrack-rest-php][Youtrack API php client]] )
- Authentication: https://www.jetbrains.com/help/youtrack/devportal/Manage-Permanent-Token.html#obtain-permanent-token
- API documentation: https://www.jetbrains.com/help/youtrack/devportal/youtrack-rest-api.html
- parse report
- compute hours per configured project categories from report
- output a table
- Create an invoice
- send the invoice (to Wolfgang)
** Motivation
- practice php
- automatization of repetitive task
- is it worth it? according to xkcd table - you should spend 1 day for
automating a monthly task that takes 30 minutes. That would be if only
I'd be using this app. If it get's picked up, by 5 others - it is worth
5 days of development.
- remove errors from reports
** Plan
1. Basic structure of the cli-app
1. App preparation
- nice specifications
- composer project
- autoloading & dependency injection
2. Report service
- read a local csv file
3. Parse report
- read configuration (project categories, hourly wage)
- simple table output
2. First round of enhancements
1. Tests
2. youtrack request
3. create composer package, create executable
3. Second round of enhancements
1. Invoice output
2. configuration wizard
** Learning
- https://www.youtube.com/watch?v=aCqM9YnjTe0
- Choices (~new ChoiceQuestion~)
- ~addOption('config')~

32
app/composer.json 100644
View File

@ -0,0 +1,32 @@
{
"name": "lio/rprt-cli",
"description": "Automate invoicing from youtrack service.",
"type": "project",
"keywords": ["cli", "report"],
"readme": "README.org",
"time": "2021-04-04",
"license": "GPL-3.0-or-later",
"authors": [
{
"name": "Lio Novelli",
"email": "lio.novelli@radiostudent.si",
"role": "Developer"
}
],
"require": {
"symfony/console": "^5.2",
"guzzlehttp/guzzle": "^7.3",
"php-di/php-di": "^6.3"
},
"repositories": [
{
"type": "vcs",
"url": "https://git.nixnet.xyz/l3/rprt"
}
],
"autoload": {
"psr-4": {
"RprtCli\\": "src"
}
}
}

1202
app/composer.lock generated 100644

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,11 @@
<?php
use function DI\create;
use function DI\get;
use RprtCli\Commands\RprtCommand;
return [
RprtCommand::class => DI\create(
)
];

18
app/rprt.php 100755
View File

@ -0,0 +1,18 @@
#!/usr/bin/env php
<?php
use Symfony\Component\Console\Application;
use RprtCli\Commands\RprtCommand;
use DI\ContainerBuilder;
require __DIR__ . '/vendor/autoload.php';
$builder = new ContainerBuilder();
$builder->addDefinitions('dependencies.php');
$container = $builder->build();
$application = new Application();
$rprtCommand = $container->get(RprtCommand::class);
$application->add($rprtCommand);
$application->run();

View File

@ -0,0 +1,48 @@
<?php
// src/Commands/RprtCommand.php;
namespace RprtCli\Commands;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Helper\Table;
use Symfony\Component\Console\Helper\TableSeparator;
class RprtCommand extends Command {
//public function __construct() {
// }
/**
* Get configuration.
*/
protected function configure(): void {
$this->setName('rprt');
$this->setDescription('Generate monthly report');
}
protected function execute(InputInterface $input, OutputInterface $output): int {
$this->dummyOutput($input, $output);
return Command::SUCCESS;
}
protected function dummyOutput(InputInterface $input, OutputInterface $output): void {
$output->writeln('I will output a nice table.');
$table = New Table($output);
$table->setHeaders(['Project', 'Hours', 'Price']);
$table->setRows([
['LDP', 100, 2600],
['WV', 50, 1300],
new TableSeparator(),
['Zusamen', 150, 3900],
]);
// $table->setStyle('borderless');
$table->render();
}
}