Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/multiple project trackers #55

Merged
merged 17 commits into from
Jan 6, 2024
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 0 additions & 8 deletions .env
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,6 @@ APP_ENV=dev
APP_SECRET=a9b5e0e75d9dcf0c01d86798c67a6399
###< symfony/framework-bundle ###

###> Jira connection ###
JIRA_PROJECT_TRACKER_URL=JIRA_PROJECT_TRACKER_URL
JIRA_PROJECT_TRACKER_USER=JIRA_PROJECT_TRACKER_USER
JIRA_PROJECT_TRACKER_TOKEN=JIRA_PROJECT_TRACKER_TOKEN
LEANTIME_PROJECT_TRACKER_URL=LEANTIME_PROJECT_TRACKER_URL
LEANTIME_PROJECT_TRACKER_TOKEN=LEANTIME_PROJECT_TRACKER_TOKEN
###< Jira connection ###

###> doctrine/doctrine-bundle ###
# Format described at https://www.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/configuration.html#connecting-using-a-url
# IMPORTANT: You MUST configure your server version, either here or in config/packages/doctrine.yaml
Expand Down
25 changes: 25 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,38 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* Added error check for invoice entries with 0 amounts
* Make sure all issues are selected in project billing period.
* Refactored error handling.
* Added support for multiple data providers
* Removed project creator for Jira.


* RELEASE NOTES:
* Change name APP_INVOICE_RECEIVER_ACCOUNT to APP_INVOICE_SUPPLIER_ACCOUNT in `.env.local`
* Set APP_INVOICE_DESCRIPTION_TEMPLATE in `.env.local`
* Set APP_INVOICE_RECEIVER_DEFAULT_ACCOUNT in `.env.local`
* Set APP_PROJECT_BILLING_DEFAULT_DESCRIPTION in `.env.local`
* Migrate to new DataProvider model. The purpose of this is to couple the previous Jira data synchronizations to a
data provider in the new model.
- Add a dataProvider for current Jira implementation with the command
```sh
bin/console app:project-tracker:create
```
- Run the following commands to set `data_provider_id` field in the database for existing synced entities.

Fill in the data from the `.env.local` values for the Jira connection:
- Name: Jira
- Url: JIRA_PROJECT_TRACKER_URL
- Secret: JIRA_PROJECT_TRACKER_USER:JIRA_PROJECT_TRACKER_TOKEN

NB! Replace 1 with the relevant DataProvider.id if it differs from 1.
```sh
bin/console doctrine:query:sql 'UPDATE account SET data_provider_id = 1';
bin/console doctrine:query:sql 'UPDATE client SET data_provider_id = 1';
bin/console doctrine:query:sql 'UPDATE issue SET data_provider_id = 1';
bin/console doctrine:query:sql 'UPDATE project SET data_provider_id = 1';
bin/console doctrine:query:sql 'UPDATE version SET data_provider_id = 1';
bin/console doctrine:query:sql 'UPDATE worklog SET data_provider_id = 1';
```


## [1.1.2]

Expand Down
4 changes: 4 additions & 0 deletions assets/styles/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,10 @@
@apply flex gap-3 mb-3;
}

.planning-form {
@apply flex gap-3 mb-3;
}

.sticky-row {
position: sticky;
bottom: 0;
Expand Down
10 changes: 0 additions & 10 deletions config/packages/framework.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,6 @@ framework:
php_errors:
log: true

http_client:
scoped_clients:
jira.project.tracker.api:
base_uri: '%env(JIRA_PROJECT_TRACKER_URL)%'
auth_basic: '%env(JIRA_PROJECT_TRACKER_USER)%:%env(JIRA_PROJECT_TRACKER_TOKEN)%'
leantime.project.tracker.api:
base_uri: '%env(LEANTIME_PROJECT_TRACKER_URL)%'
headers:
x-api-key: '%env(LEANTIME_PROJECT_TRACKER_TOKEN)%'

when@test:
framework:
test: true
Expand Down
18 changes: 3 additions & 15 deletions config/services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,25 +32,13 @@ services:
- '../src/DependencyInjection/'
- '../src/Entity/'
- '../src/Kernel.php'

# Select active project tracker implementation
App\Service\ProjectTrackerInterface: '@App\Service\LeantimeApiService'
# App\Service\ProjectTrackerInterface: '@App\Service\JiraApiService'
- '../src/Service/JiraApiService.php'
- '../src/Service/LeantimeApiService.php'

# add more service definitions when explicit configuration is needed
# please note that last definitions always *replace* previous ones
App\Service\JiraApiService:
App\Service\DataProviderService:
arguments:
$customFieldMappings: '%app.jira_custom_fields%'
$defaultBoard: '%env(JIRA_API_SERVICE_DEFAULT_BOARD)%'
$jiraUrl: '%env(JIRA_PROJECT_TRACKER_URL)%'
$weekGoalLow: '%env(float:APP_WEEK_GOAL_LOW)%'
$weekGoalHigh: '%env(float:APP_WEEK_GOAL_HIGH)%'
$sprintNameRegex: '%env(API_SERVICE_SPRINT_NAME_REGEX)%'

App\Service\LeantimeApiService:
arguments:
$leantimeUrl: '%env(LEANTIME_PROJECT_TRACKER_URL)%'
$sprintNameRegex: '%env(API_SERVICE_SPRINT_NAME_REGEX)%'
$weekGoalLow: '%env(float:APP_WEEK_GOAL_LOW)%'
$weekGoalHigh: '%env(float:APP_WEEK_GOAL_HIGH)%'
33 changes: 33 additions & 0 deletions migrations/Version20231218114856.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

declare(strict_types=1);

namespace DoctrineMigrations;

use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;

/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20231218114856 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}

public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('CREATE TABLE project_tracker (id INT AUTO_INCREMENT NOT NULL, name VARCHAR(255) NOT NULL, url VARCHAR(255) DEFAULT NULL, basic_auth VARCHAR(255) DEFAULT NULL, class VARCHAR(255) NOT NULL, created_by VARCHAR(255) DEFAULT NULL, updated_by VARCHAR(255) DEFAULT NULL, created_at DATETIME NOT NULL, updated_at DATETIME NOT NULL, UNIQUE INDEX UNIQ_3A7D26CA5E237E06 (name), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB');
$this->addSql('ALTER TABLE issue ADD created_by VARCHAR(255) DEFAULT NULL, ADD updated_by VARCHAR(255) DEFAULT NULL, ADD created_at DATETIME NOT NULL, ADD updated_at DATETIME NOT NULL');
}

public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('DROP TABLE project_tracker');
$this->addSql('ALTER TABLE issue DROP created_by, DROP updated_by, DROP created_at, DROP updated_at');
}
}
33 changes: 33 additions & 0 deletions migrations/Version20240104081158.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

declare(strict_types=1);

namespace DoctrineMigrations;

use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;

/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20240104081158 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}

public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('CREATE TABLE data_provider (id INT AUTO_INCREMENT NOT NULL, name VARCHAR(255) NOT NULL, url VARCHAR(255) DEFAULT NULL, secret VARCHAR(255) DEFAULT NULL, class VARCHAR(255) NOT NULL, enable_client_sync TINYINT(1) NOT NULL, enable_account_sync TINYINT(1) NOT NULL, created_by VARCHAR(255) DEFAULT NULL, updated_by VARCHAR(255) DEFAULT NULL, created_at DATETIME NOT NULL, updated_at DATETIME NOT NULL, UNIQUE INDEX UNIQ_581ABA405E237E06 (name), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB');
$this->addSql('DROP TABLE project_tracker');
}

public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('CREATE TABLE project_tracker (id INT AUTO_INCREMENT NOT NULL, name VARCHAR(255) CHARACTER SET utf8mb4 NOT NULL COLLATE `utf8mb4_unicode_ci`, url VARCHAR(255) CHARACTER SET utf8mb4 DEFAULT NULL COLLATE `utf8mb4_unicode_ci`, basic_auth VARCHAR(255) CHARACTER SET utf8mb4 DEFAULT NULL COLLATE `utf8mb4_unicode_ci`, class VARCHAR(255) CHARACTER SET utf8mb4 NOT NULL COLLATE `utf8mb4_unicode_ci`, created_by VARCHAR(255) CHARACTER SET utf8mb4 DEFAULT NULL COLLATE `utf8mb4_unicode_ci`, updated_by VARCHAR(255) CHARACTER SET utf8mb4 DEFAULT NULL COLLATE `utf8mb4_unicode_ci`, created_at DATETIME NOT NULL, updated_at DATETIME NOT NULL, UNIQUE INDEX UNIQ_3A7D26CA5E237E06 (name), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB COMMENT = \'\' ');
$this->addSql('DROP TABLE data_provider');
}
}
31 changes: 31 additions & 0 deletions migrations/Version20240104084117.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

declare(strict_types=1);

namespace DoctrineMigrations;

use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;

/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20240104084117 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}

public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE data_provider CHANGE enable_client_sync enable_client_sync TINYINT(1) DEFAULT NULL, CHANGE enable_account_sync enable_account_sync TINYINT(1) DEFAULT NULL');
}

public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE data_provider CHANGE enable_client_sync enable_client_sync TINYINT(1) NOT NULL, CHANGE enable_account_sync enable_account_sync TINYINT(1) NOT NULL');
}
}
65 changes: 65 additions & 0 deletions migrations/Version20240104091908.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<?php

declare(strict_types=1);

namespace DoctrineMigrations;

use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;

/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20240104091908 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}

public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE account ADD data_provider_id INT DEFAULT NULL');
$this->addSql('ALTER TABLE account ADD CONSTRAINT FK_7D3656A4F593F7E0 FOREIGN KEY (data_provider_id) REFERENCES data_provider (id)');
$this->addSql('CREATE INDEX IDX_7D3656A4F593F7E0 ON account (data_provider_id)');
$this->addSql('ALTER TABLE client ADD data_provider_id INT DEFAULT NULL');
$this->addSql('ALTER TABLE client ADD CONSTRAINT FK_C7440455F593F7E0 FOREIGN KEY (data_provider_id) REFERENCES data_provider (id)');
$this->addSql('CREATE INDEX IDX_C7440455F593F7E0 ON client (data_provider_id)');
$this->addSql('ALTER TABLE issue ADD data_provider_id INT DEFAULT NULL');
$this->addSql('ALTER TABLE issue ADD CONSTRAINT FK_12AD233EF593F7E0 FOREIGN KEY (data_provider_id) REFERENCES data_provider (id)');
$this->addSql('CREATE INDEX IDX_12AD233EF593F7E0 ON issue (data_provider_id)');
$this->addSql('ALTER TABLE project ADD data_provider_id INT DEFAULT NULL');
$this->addSql('ALTER TABLE project ADD CONSTRAINT FK_2FB3D0EEF593F7E0 FOREIGN KEY (data_provider_id) REFERENCES data_provider (id)');
$this->addSql('CREATE INDEX IDX_2FB3D0EEF593F7E0 ON project (data_provider_id)');
$this->addSql('ALTER TABLE version ADD data_provider_id INT DEFAULT NULL');
$this->addSql('ALTER TABLE version ADD CONSTRAINT FK_BF1CD3C3F593F7E0 FOREIGN KEY (data_provider_id) REFERENCES data_provider (id)');
$this->addSql('CREATE INDEX IDX_BF1CD3C3F593F7E0 ON version (data_provider_id)');
$this->addSql('ALTER TABLE worklog ADD data_provider_id INT DEFAULT NULL');
$this->addSql('ALTER TABLE worklog ADD CONSTRAINT FK_524AFE2EF593F7E0 FOREIGN KEY (data_provider_id) REFERENCES data_provider (id)');
$this->addSql('CREATE INDEX IDX_524AFE2EF593F7E0 ON worklog (data_provider_id)');
}

public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE client DROP FOREIGN KEY FK_C7440455F593F7E0');
$this->addSql('DROP INDEX IDX_C7440455F593F7E0 ON client');
$this->addSql('ALTER TABLE client DROP data_provider_id');
$this->addSql('ALTER TABLE worklog DROP FOREIGN KEY FK_524AFE2EF593F7E0');
$this->addSql('DROP INDEX IDX_524AFE2EF593F7E0 ON worklog');
$this->addSql('ALTER TABLE worklog DROP data_provider_id');
$this->addSql('ALTER TABLE account DROP FOREIGN KEY FK_7D3656A4F593F7E0');
$this->addSql('DROP INDEX IDX_7D3656A4F593F7E0 ON account');
$this->addSql('ALTER TABLE account DROP data_provider_id');
$this->addSql('ALTER TABLE issue DROP FOREIGN KEY FK_12AD233EF593F7E0');
$this->addSql('DROP INDEX IDX_12AD233EF593F7E0 ON issue');
$this->addSql('ALTER TABLE issue DROP data_provider_id');
$this->addSql('ALTER TABLE project DROP FOREIGN KEY FK_2FB3D0EEF593F7E0');
$this->addSql('DROP INDEX IDX_2FB3D0EEF593F7E0 ON project');
$this->addSql('ALTER TABLE project DROP data_provider_id');
$this->addSql('ALTER TABLE version DROP FOREIGN KEY FK_BF1CD3C3F593F7E0');
$this->addSql('DROP INDEX IDX_BF1CD3C3F593F7E0 ON version');
$this->addSql('ALTER TABLE version DROP data_provider_id');
}
}
35 changes: 35 additions & 0 deletions migrations/Version20240104092346.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

declare(strict_types=1);

namespace DoctrineMigrations;

use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;

/**
* Auto-generated Migration: Please modify to your needs!
*/
final class Version20240104092346 extends AbstractMigration
{
public function getDescription(): string
{
return '';
}

public function up(Schema $schema): void
{
// this up() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE account DROP source');
$this->addSql('ALTER TABLE issue DROP source');
$this->addSql('ALTER TABLE worklog DROP source');
}

public function down(Schema $schema): void
{
// this down() migration is auto-generated, please modify it to your needs
$this->addSql('ALTER TABLE worklog ADD source VARCHAR(255) NOT NULL');
$this->addSql('ALTER TABLE account ADD source VARCHAR(255) NOT NULL');
$this->addSql('ALTER TABLE issue ADD source VARCHAR(255) NOT NULL');
}
}
55 changes: 55 additions & 0 deletions src/Command/DataProviderCreateCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php

namespace App\Command;

use App\Service\DataProviderService;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\Question;
use Symfony\Component\Console\Style\SymfonyStyle;

#[AsCommand(
name: 'app:project-tracker:create',
description: 'Create a new Project Tracker',
)]
class DataProviderCreateCommand extends Command
{
public function __construct(
private readonly DataProviderService $dataProviderService,
) {
parent::__construct($this->getName());
}

protected function configure(): void
{
}

protected function execute(InputInterface $input, OutputInterface $output): int
{
$io = new SymfonyStyle($input, $output);

$name = $io->ask('Name');
$url = $io->ask('URL');
$secret = $io->ask('Secret');
$question = new Question('Implementation class');
$question->setAutocompleterValues(DataProviderService::IMPLEMENTATIONS);
$class = $io->askQuestion($question);

$dataProvider = $this->dataProviderService->createDataProvider($name, $class, $url, $secret, false, false);

$text = "Created the following data provider\n\n";
$text .= 'ID: '.$dataProvider->getId()."\n";
$text .= 'Name: '.$dataProvider->getName()."\n";
$text .= 'URL: '.$dataProvider->getUrl()."\n";
$text .= "Secret: ****\n";
$text .= 'Class: '.$dataProvider->getClass()."\n";
$text .= 'Enable client sync: '.$dataProvider->isEnableClientSync()."\n";
$text .= 'Enable account sync: '.$dataProvider->isEnableAccountSync()."\n";

$io->info($text);

return Command::SUCCESS;
}
}
6 changes: 3 additions & 3 deletions src/Command/MigrateCustomersCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace App\Command;

use App\Service\DataProviderService;
use App\Service\DataSynchronizationService;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
Expand All @@ -15,7 +15,7 @@
)]
class MigrateCustomersCommand extends Command
{
public function __construct(private readonly DataProviderService $dataProviderService)
public function __construct(private readonly DataSynchronizationService $dataSynchronizationService)
{
parent::__construct($this->getName());
}
Expand All @@ -29,7 +29,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
$io = new SymfonyStyle($input, $output);

if ($io->confirm('Are you sure?')) {
$this->dataProviderService->migrateCustomers();
$this->dataSynchronizationService->migrateCustomers();
}

$io->success('invoice.customerAccountId migrated to invoice.client');
Expand Down
Loading
Loading