diff --git a/config/api_platform/CommandTaskSchedule.yaml b/config/api_platform/CommandTaskSchedule.yaml new file mode 100644 index 0000000..2f90cb9 --- /dev/null +++ b/config/api_platform/CommandTaskSchedule.yaml @@ -0,0 +1,32 @@ +resources: + App\Entity\CommandTaskSchedule: + processor: App\State\Processor\CommandTaskScheduleProcessor + input: App\Dto\Input\CommandTaskScheduleInput + output: App\Dto\Output\CommandTaskScheduleOutput + normalizationContext: + groups: ['default', 'command-task-schedule:read'] + denormalizationContext: + groups: ['command-task-schedule:write'] + operations: + ApiPlatform\Metadata\GetCollection: + provider: App\State\Provider\CommandTaskScheduleProvider + filters: + - 'api_platform.filter.command_task_schedule.order' + - 'api_platform.filter.command_task_schedule.search' + - 'api_platform.filter.command_task_schedule.boolean' + + ApiPlatform\Metadata\Get: + provider: App\State\Provider\CommandTaskScheduleProvider + ApiPlatform\Metadata\Put: + provider: App\State\Provider\CommandTaskScheduleProvider + ApiPlatform\Metadata\Patch: + provider: App\State\Provider\CommandTaskScheduleProvider + ApiPlatform\Metadata\Post: ~ + ApiPlatform\Metadata\Delete: ~ + +properties: + App\Entity\CommandTaskSchedule: + id: + identifier: false + uuid: + identifier: true \ No newline at end of file diff --git a/config/api_platform/CommandTaskScript.yaml b/config/api_platform/CommandTaskScript.yaml new file mode 100644 index 0000000..cadc386 --- /dev/null +++ b/config/api_platform/CommandTaskScript.yaml @@ -0,0 +1,32 @@ +resources: + App\Entity\CommandTaskScript: + processor: App\State\Processor\CommandTaskScriptProcessor + input: App\Dto\Input\CommandTaskScriptInput + output: App\Dto\Output\CommandTaskScriptOutput + normalizationContext: + groups: ['default', 'command-task-script:read'] + denormalizationContext: + groups: ['command-task-script:write'] + operations: + ApiPlatform\Metadata\GetCollection: + provider: App\State\Provider\CommandTaskScriptProvider + filters: + - 'api_platform.filter.command_task_script.order' + - 'api_platform.filter.command_task_script.search' + - 'api_platform.filter.command_task_script.boolean' + + ApiPlatform\Metadata\Get: + provider: App\State\Provider\CommandTaskScriptProvider + ApiPlatform\Metadata\Put: + provider: App\State\Provider\CommandTaskScriptProvider + ApiPlatform\Metadata\Patch: + provider: App\State\Provider\CommandTaskScriptProvider + ApiPlatform\Metadata\Post: ~ + ApiPlatform\Metadata\Delete: ~ + +properties: + App\Entity\CommandTaskScript: + id: + identifier: false + uuid: + identifier: true \ No newline at end of file diff --git a/config/services.yaml b/config/services.yaml index fbf0dc6..5ece707 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -156,3 +156,13 @@ services: bind: $collectionProvider: '@api_platform.doctrine.orm.state.collection_provider' $itemProvider: '@api_platform.doctrine.orm.state.item_provider' + + App\State\Provider\CommandTaskScheduleProvider: + bind: + $collectionProvider: '@api_platform.doctrine.orm.state.collection_provider' + $itemProvider: '@api_platform.doctrine.orm.state.item_provider' + + App\State\Provider\CommandTaskScriptProvider: + bind: + $collectionProvider: '@api_platform.doctrine.orm.state.collection_provider' + $itemProvider: '@api_platform.doctrine.orm.state.item_provider' diff --git a/migrations/Version20250421122715.php b/migrations/Version20250421122715.php new file mode 100644 index 0000000..f7cb306 --- /dev/null +++ b/migrations/Version20250421122715.php @@ -0,0 +1,31 @@ +addSql('ALTER TABLE command_task ADD parameters LONGTEXT DEFAULT NULL COMMENT \'(DC2Type:array)\''); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('ALTER TABLE command_task DROP parameters'); + } +} diff --git a/migrations/Version20250422092348.php b/migrations/Version20250422092348.php new file mode 100644 index 0000000..85eefb7 --- /dev/null +++ b/migrations/Version20250422092348.php @@ -0,0 +1,35 @@ +addSql('ALTER TABLE network_settings ADD pxe_template_id INT DEFAULT NULL'); + $this->addSql('ALTER TABLE network_settings ADD CONSTRAINT FK_48869B543BD7665C FOREIGN KEY (pxe_template_id) REFERENCES pxe_template (id)'); + $this->addSql('CREATE INDEX IDX_48869B543BD7665C ON network_settings (pxe_template_id)'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('ALTER TABLE network_settings DROP FOREIGN KEY FK_48869B543BD7665C'); + $this->addSql('DROP INDEX IDX_48869B543BD7665C ON network_settings'); + $this->addSql('ALTER TABLE network_settings DROP pxe_template_id'); + } +} diff --git a/migrations/Version20250422140927.php b/migrations/Version20250422140927.php new file mode 100644 index 0000000..a871594 --- /dev/null +++ b/migrations/Version20250422140927.php @@ -0,0 +1,31 @@ +addSql('ALTER TABLE command_task ADD name VARCHAR(255) NOT NULL'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('ALTER TABLE command_task DROP name'); + } +} diff --git a/migrations/Version20250423070720.php b/migrations/Version20250423070720.php new file mode 100644 index 0000000..c896641 --- /dev/null +++ b/migrations/Version20250423070720.php @@ -0,0 +1,31 @@ +addSql('ALTER TABLE command_task DROP datetime'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('ALTER TABLE command_task ADD datetime DATETIME NOT NULL'); + } +} diff --git a/migrations/Version20250423071243.php b/migrations/Version20250423071243.php new file mode 100644 index 0000000..f2170cd --- /dev/null +++ b/migrations/Version20250423071243.php @@ -0,0 +1,35 @@ +addSql('ALTER TABLE command_task ADD organizational_unit_id INT DEFAULT NULL'); + $this->addSql('ALTER TABLE command_task ADD CONSTRAINT FK_F3D475A8FB84408A FOREIGN KEY (organizational_unit_id) REFERENCES organizational_unit (id)'); + $this->addSql('CREATE INDEX IDX_F3D475A8FB84408A ON command_task (organizational_unit_id)'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('ALTER TABLE command_task DROP FOREIGN KEY FK_F3D475A8FB84408A'); + $this->addSql('DROP INDEX IDX_F3D475A8FB84408A ON command_task'); + $this->addSql('ALTER TABLE command_task DROP organizational_unit_id'); + } +} diff --git a/migrations/Version20250423092037.php b/migrations/Version20250423092037.php new file mode 100644 index 0000000..5855b79 --- /dev/null +++ b/migrations/Version20250423092037.php @@ -0,0 +1,33 @@ +addSql('CREATE TABLE command_task_schedule (id INT AUTO_INCREMENT NOT NULL, command_task_id INT NOT NULL, uuid CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', migration_id VARCHAR(255) DEFAULT NULL, created_at DATETIME NOT NULL, updated_at DATETIME NOT NULL, created_by VARCHAR(255) DEFAULT NULL, updated_by VARCHAR(255) DEFAULT NULL, recurrence_type VARCHAR(255) NOT NULL, start_time DATETIME NOT NULL, recurrence_details JSON DEFAULT NULL COMMENT \'(DC2Type:json)\', UNIQUE INDEX UNIQ_3BEA77AD17F50A6 (uuid), INDEX IDX_3BEA77A62DC5265 (command_task_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB'); + $this->addSql('ALTER TABLE command_task_schedule ADD CONSTRAINT FK_3BEA77A62DC5265 FOREIGN KEY (command_task_id) REFERENCES command_task (id)'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('ALTER TABLE command_task_schedule DROP FOREIGN KEY FK_3BEA77A62DC5265'); + $this->addSql('DROP TABLE command_task_schedule'); + } +} diff --git a/migrations/Version20250427110103.php b/migrations/Version20250427110103.php new file mode 100644 index 0000000..fb167da --- /dev/null +++ b/migrations/Version20250427110103.php @@ -0,0 +1,45 @@ +addSql('CREATE TABLE command_task_scripts (id INT AUTO_INCREMENT NOT NULL, command_task_id INT NOT NULL, uuid CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', migration_id VARCHAR(255) DEFAULT NULL, created_at DATETIME NOT NULL, updated_at DATETIME NOT NULL, created_by VARCHAR(255) DEFAULT NULL, updated_by VARCHAR(255) DEFAULT NULL, content VARCHAR(255) NOT NULL, execution_order INT NOT NULL, UNIQUE INDEX UNIQ_E8950142D17F50A6 (uuid), INDEX IDX_E895014262DC5265 (command_task_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB'); + $this->addSql('ALTER TABLE command_task_scripts ADD CONSTRAINT FK_E895014262DC5265 FOREIGN KEY (command_task_id) REFERENCES command_task (id)'); + $this->addSql('ALTER TABLE command_task_command_group DROP FOREIGN KEY FK_C43618BD62DC5265'); + $this->addSql('ALTER TABLE command_task_command_group DROP FOREIGN KEY FK_C43618BDC7B800D6'); + $this->addSql('ALTER TABLE command_task_command DROP FOREIGN KEY FK_BB417CA862DC5265'); + $this->addSql('ALTER TABLE command_task_command DROP FOREIGN KEY FK_BB417CA833E1689A'); + $this->addSql('DROP TABLE command_task_command_group'); + $this->addSql('DROP TABLE command_task_command'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('CREATE TABLE command_task_command_group (command_task_id INT NOT NULL, command_group_id INT NOT NULL, INDEX IDX_C43618BD62DC5265 (command_task_id), INDEX IDX_C43618BDC7B800D6 (command_group_id), PRIMARY KEY(command_task_id, command_group_id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB COMMENT = \'\' '); + $this->addSql('CREATE TABLE command_task_command (command_task_id INT NOT NULL, command_id INT NOT NULL, INDEX IDX_BB417CA862DC5265 (command_task_id), INDEX IDX_BB417CA833E1689A (command_id), PRIMARY KEY(command_task_id, command_id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB COMMENT = \'\' '); + $this->addSql('ALTER TABLE command_task_command_group ADD CONSTRAINT FK_C43618BD62DC5265 FOREIGN KEY (command_task_id) REFERENCES command_task (id) ON DELETE CASCADE'); + $this->addSql('ALTER TABLE command_task_command_group ADD CONSTRAINT FK_C43618BDC7B800D6 FOREIGN KEY (command_group_id) REFERENCES command_group (id) ON DELETE CASCADE'); + $this->addSql('ALTER TABLE command_task_command ADD CONSTRAINT FK_BB417CA862DC5265 FOREIGN KEY (command_task_id) REFERENCES command_task (id) ON DELETE CASCADE'); + $this->addSql('ALTER TABLE command_task_command ADD CONSTRAINT FK_BB417CA833E1689A FOREIGN KEY (command_id) REFERENCES command (id) ON DELETE CASCADE'); + $this->addSql('ALTER TABLE command_task_scripts DROP FOREIGN KEY FK_E895014262DC5265'); + $this->addSql('DROP TABLE command_task_scripts'); + } +} diff --git a/migrations/Version20250427125746.php b/migrations/Version20250427125746.php new file mode 100644 index 0000000..9679d89 --- /dev/null +++ b/migrations/Version20250427125746.php @@ -0,0 +1,37 @@ +addSql('CREATE TABLE command_task_script (id INT AUTO_INCREMENT NOT NULL, command_task_id INT NOT NULL, uuid CHAR(36) NOT NULL COMMENT \'(DC2Type:uuid)\', migration_id VARCHAR(255) DEFAULT NULL, created_at DATETIME NOT NULL, updated_at DATETIME NOT NULL, created_by VARCHAR(255) DEFAULT NULL, updated_by VARCHAR(255) DEFAULT NULL, content VARCHAR(255) NOT NULL, execution_order INT NOT NULL, UNIQUE INDEX UNIQ_22BF0112D17F50A6 (uuid), INDEX IDX_22BF011262DC5265 (command_task_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB'); + $this->addSql('ALTER TABLE command_task_script ADD CONSTRAINT FK_22BF011262DC5265 FOREIGN KEY (command_task_id) REFERENCES command_task (id)'); + $this->addSql('ALTER TABLE command_task_scripts DROP FOREIGN KEY FK_E895014262DC5265'); + $this->addSql('DROP TABLE command_task_scripts'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('CREATE TABLE command_task_scripts (id INT AUTO_INCREMENT NOT NULL, command_task_id INT NOT NULL, uuid CHAR(36) CHARACTER SET utf8mb4 NOT NULL COLLATE `utf8mb4_unicode_ci` COMMENT \'(DC2Type:uuid)\', migration_id VARCHAR(255) CHARACTER SET utf8mb4 DEFAULT NULL COLLATE `utf8mb4_unicode_ci`, created_at DATETIME NOT NULL, updated_at DATETIME NOT NULL, 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`, content VARCHAR(255) CHARACTER SET utf8mb4 NOT NULL COLLATE `utf8mb4_unicode_ci`, execution_order INT NOT NULL, INDEX IDX_E895014262DC5265 (command_task_id), UNIQUE INDEX UNIQ_E8950142D17F50A6 (uuid), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB COMMENT = \'\' '); + $this->addSql('ALTER TABLE command_task_scripts ADD CONSTRAINT FK_E895014262DC5265 FOREIGN KEY (command_task_id) REFERENCES command_task (id)'); + $this->addSql('ALTER TABLE command_task_script DROP FOREIGN KEY FK_22BF011262DC5265'); + $this->addSql('DROP TABLE command_task_script'); + } +} diff --git a/migrations/Version20250428065311.php b/migrations/Version20250428065311.php new file mode 100644 index 0000000..b1d3eec --- /dev/null +++ b/migrations/Version20250428065311.php @@ -0,0 +1,31 @@ +addSql('ALTER TABLE command_task_schedule ADD execution_date DATE NOT NULL, ADD execution_time TIME NOT NULL, DROP start_time'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('ALTER TABLE command_task_schedule ADD start_time DATETIME NOT NULL, DROP execution_date, DROP execution_time'); + } +} diff --git a/migrations/Version20250428065937.php b/migrations/Version20250428065937.php new file mode 100644 index 0000000..d74c6e4 --- /dev/null +++ b/migrations/Version20250428065937.php @@ -0,0 +1,31 @@ +addSql('ALTER TABLE command_task_schedule ADD enabled TINYINT(1) NOT NULL'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('ALTER TABLE command_task_schedule DROP enabled'); + } +} diff --git a/migrations/Version20250428070851.php b/migrations/Version20250428070851.php new file mode 100644 index 0000000..36da43e --- /dev/null +++ b/migrations/Version20250428070851.php @@ -0,0 +1,31 @@ +addSql('ALTER TABLE command_task_schedule CHANGE execution_date execution_date DATE DEFAULT NULL, CHANGE execution_time execution_time TIME DEFAULT NULL'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('ALTER TABLE command_task_schedule CHANGE execution_date execution_date DATE NOT NULL, CHANGE execution_time execution_time TIME NOT NULL'); + } +} diff --git a/migrations/Version20250429065612.php b/migrations/Version20250429065612.php new file mode 100644 index 0000000..5f64e24 --- /dev/null +++ b/migrations/Version20250429065612.php @@ -0,0 +1,31 @@ +addSql('ALTER TABLE command_task ADD last_execution DATETIME DEFAULT NULL, ADD next_execution DATETIME DEFAULT NULL'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('ALTER TABLE command_task DROP last_execution, DROP next_execution'); + } +} diff --git a/migrations/Version20250429091808.php b/migrations/Version20250429091808.php new file mode 100644 index 0000000..d81868d --- /dev/null +++ b/migrations/Version20250429091808.php @@ -0,0 +1,31 @@ +addSql('ALTER TABLE command_task ADD scope VARCHAR(255) NOT NULL'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('ALTER TABLE command_task DROP scope'); + } +} diff --git a/migrations/Version20250430052434.php b/migrations/Version20250430052434.php new file mode 100644 index 0000000..3dbfe8f --- /dev/null +++ b/migrations/Version20250430052434.php @@ -0,0 +1,31 @@ +addSql('ALTER TABLE command_task_script ADD type VARCHAR(255) NOT NULL'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('ALTER TABLE command_task_script DROP type'); + } +} diff --git a/migrations/Version20250430053742.php b/migrations/Version20250430053742.php new file mode 100644 index 0000000..fc079dc --- /dev/null +++ b/migrations/Version20250430053742.php @@ -0,0 +1,31 @@ +addSql('ALTER TABLE command_task_script ADD parameters LONGTEXT DEFAULT NULL COMMENT \'(DC2Type:array)\''); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('ALTER TABLE command_task_script DROP parameters'); + } +} diff --git a/migrations/Version20250430054513.php b/migrations/Version20250430054513.php new file mode 100644 index 0000000..9a8c368 --- /dev/null +++ b/migrations/Version20250430054513.php @@ -0,0 +1,31 @@ +addSql('ALTER TABLE command_task_script CHANGE content content VARCHAR(255) DEFAULT NULL'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('ALTER TABLE command_task_script CHANGE content content VARCHAR(255) NOT NULL'); + } +} diff --git a/migrations/Version20250430094459.php b/migrations/Version20250430094459.php new file mode 100644 index 0000000..7e63dd4 --- /dev/null +++ b/migrations/Version20250430094459.php @@ -0,0 +1,31 @@ +addSql('ALTER TABLE command_task DROP status'); + } + + public function down(Schema $schema): void + { + // this down() migration is auto-generated, please modify it to your needs + $this->addSql('ALTER TABLE command_task ADD status VARCHAR(255) NOT NULL'); + } +} diff --git a/src/Dto/Input/CommandTaskInput.php b/src/Dto/Input/CommandTaskInput.php index c7e08e7..71a2cd1 100644 --- a/src/Dto/Input/CommandTaskInput.php +++ b/src/Dto/Input/CommandTaskInput.php @@ -6,6 +6,7 @@ use ApiPlatform\Metadata\ApiProperty; use App\Dto\Output\ClientOutput; use App\Dto\Output\CommandGroupOutput; use App\Dto\Output\CommandOutput; +use App\Dto\Output\OrganizationalUnitOutput; use App\Entity\CommandTask; use App\Model\CommandTaskStatus; use phpDocumentor\Reflection\Types\Boolean; @@ -14,25 +15,12 @@ use Symfony\Component\Validator\Constraints as Assert; final class CommandTaskInput { - /** - * @var CommandOutput[] - */ #[Groups(['command-task:write'])] #[ApiProperty( - description: 'Los comandos de la tarea', - example: 'Comandos de la tarea', + description: 'El nombre de la tarea', + example: 'Tarea 1', )] - public array $commands = []; - - /** - * @var CommandGroupOutput[] - */ - #[Groups(['command-task:write'])] - #[ApiProperty( - description: 'Los grupos de comandos de la tarea', - example: 'Grupos de comandos de la tarea', - )] - public array $commandGroups = []; + public ?string $name = null; /** * @var ClientOutput[] @@ -44,38 +32,37 @@ final class CommandTaskInput )] public array $clients = []; - #[Assert\NotBlank(message: 'validators.command_task.datetime.not_blank')] - #[Groups(['command-task:write'])] - #[ApiProperty( - description: 'La fecha y hora de la tarea', - example: '2021-10-01T00:00:00+00:00', - )] - public ?\DateTimeInterface $dateTime = null; - #[Groups(['command-task:write'])] #[ApiProperty( description: 'Los comentarios de la tarea', - example: 'Comentarios de la tarea', + example: 'Ambito de la tarea', )] public ?string $notes = null; + #[Groups(['command-task:write'])] + #[ApiProperty( + description: 'El ambito de la tarea', + example: 'Comentarios de la tarea', + )] + public ?string $scope = null; + + #[Groups(['command-task:write'])] + public ?OrganizationalUnitOutput $organizationalUnit = null; + + #[Groups(['command-task:write'])] + #[ApiProperty( + description: 'Los parĂ¡metros de la tarea', + example: 'ParĂ¡metros de la tarea', + )] + public ?array $content = null; + public function __construct(?CommandTask $commandTask = null) { if (!$commandTask) { return; } - if ($commandTask->getCommands()) { - foreach ($commandTask->getCommands() as $command) { - $this->commands[] = new CommandOutput($command); - } - } - - if ($commandTask->getCommandGroups()) { - foreach ($commandTask->getCommandGroups() as $commandGroup) { - $this->commandGroups[] = new CommandGroupOutput($commandGroup); - } - } + $this->name = $commandTask->getName(); if ($commandTask->getClients()) { foreach ($commandTask->getClients() as $client) { @@ -83,37 +70,33 @@ final class CommandTaskInput } } - $this->dateTime = $commandTask->getDatetime(); + $this->organizationalUnit = new OrganizationalUnitOutput($commandTask->getOrganizationalUnit()); $this->notes = $commandTask->getNotes(); + $this->scope = $commandTask->getScope(); + $this->content = $commandTask->getParameters(); } + /** + * @throws \Exception + */ public function createOrUpdateEntity(?CommandTask $commandTask = null): CommandTask { if (!$commandTask) { $commandTask = new CommandTask(); } - foreach ($this->commands as $command) { - $commandsToAdd[] = $command->getEntity(); - } - - $commandTask->setCommands( $commandsToAdd ?? [] ); - - foreach ($this->commandGroups as $commandGroup) { - $commandGroupsToAdd[] = $commandGroup->getEntity(); - } - - $commandTask->setCommandGroups( $commandGroupsToAdd ?? [] ); + $commandTask->setName($this->name); foreach ($this->clients as $client) { $clientsToAdd[] = $client->getEntity(); } + $commandTask->setOrganizationalUnit($this->organizationalUnit->getEntity()); $commandTask->setClients( $clientsToAdd ?? [] ); - - $commandTask->setDatetime($this->dateTime); - $commandTask->setStatus(CommandTaskStatus::PENDING); $commandTask->setNotes($this->notes); + $commandTask->setParameters($this->content); + $commandTask->setScope($this->scope); + $commandTask->setNextExecution($commandTask->calculateNextExecutionDate()); return $commandTask; } diff --git a/src/Dto/Input/CommandTaskScheduleInput.php b/src/Dto/Input/CommandTaskScheduleInput.php new file mode 100644 index 0000000..6aee8b2 --- /dev/null +++ b/src/Dto/Input/CommandTaskScheduleInput.php @@ -0,0 +1,66 @@ +commandTask = new CommandTaskOutput($commandTaskSchedule->getCommandTask()); + $this->recurrenceType = $commandTaskSchedule->getRecurrenceType(); + $this->executionDate = $commandTaskSchedule->getExecutionDate(); + $this->executionTime = $commandTaskSchedule->getExecutionTime(); + $this->recurrenceDetails = $commandTaskSchedule->getRecurrenceDetails(); + $this->enabled = $commandTaskSchedule->isEnabled(); + } + + /** + * @throws \Exception + */ + public function createOrUpdateEntity(?CommandTaskSchedule $commandTaskSchedule = null): CommandTaskSchedule + { + if (!$commandTaskSchedule) { + $commandTaskSchedule = new CommandTaskSchedule(); + } + + if ($this->commandTask) { + $commandTaskSchedule->setCommandTask($this->commandTask->getEntity()); + } + $commandTaskSchedule->setRecurrenceType($this->recurrenceType); + $commandTaskSchedule->setExecutionTime($this->executionTime); + $commandTaskSchedule->setExecutionDate($this->executionDate); + $commandTaskSchedule->setRecurrenceDetails($this->recurrenceDetails); + $commandTaskSchedule->setEnabled($this->enabled); + + return $commandTaskSchedule; + } + + +} \ No newline at end of file diff --git a/src/Dto/Input/CommandTaskScriptInput.php b/src/Dto/Input/CommandTaskScriptInput.php new file mode 100644 index 0000000..8eb8583 --- /dev/null +++ b/src/Dto/Input/CommandTaskScriptInput.php @@ -0,0 +1,57 @@ +content = $commandTaskScript->getContent(); + $this->type = $commandTaskScript->getType(); + $this->order = $commandTaskScript->getExecutionOrder(); + $this->parameters = $commandTaskScript->getParameters(); + $this->commandTask = new CommandTaskOutput($commandTaskScript->getCommandTask()); + } + + public function createOrUpdateEntity(?CommandTaskScript $commandTaskScript = null): CommandTaskScript + { + if (!$commandTaskScript) { + $commandTaskScript = new CommandTaskScript(); + } + + if ($this->commandTask) { + $commandTaskScript->setCommandTask($this->commandTask->getEntity()); + } + $commandTaskScript->setType($this->type); + $commandTaskScript->setParameters($this->parameters); + $commandTaskScript->setContent($this->content); + $commandTaskScript->setExecutionOrder($this->order); + + return $commandTaskScript; + } +} \ No newline at end of file diff --git a/src/Dto/Output/CommandTaskOutput.php b/src/Dto/Output/CommandTaskOutput.php index 76c519c..b687016 100644 --- a/src/Dto/Output/CommandTaskOutput.php +++ b/src/Dto/Output/CommandTaskOutput.php @@ -13,22 +13,25 @@ use Symfony\Component\Serializer\Annotation\Groups; final class CommandTaskOutput extends AbstractOutput { #[Groups(['command-task:read'])] - public array $commands = []; - - #[Groups(['command-task:read'])] - public array $commandGroups = []; + public ?string $name = null; #[Groups(['command-task:read'])] public array $clients = []; #[Groups(['command-task:read'])] - public \DateTimeInterface $dateTime; + public ?OrganizationalUnitOutput $organizationalUnit = null; + + #[Groups(['command-task:read'])] + public ?\DateTimeInterface $lastExecution = null; + + #[Groups(['command-task:read'])] + public ?\DateTimeInterface $nextExecution = null; #[Groups(['command-task:read'])] public ?string $notes = null; #[Groups(['command-task:read'])] - public ?string $status = null; + public ?string $scope = null; #[Groups(['command-task:read'])] public \DateTime $createdAt; @@ -41,21 +44,17 @@ final class CommandTaskOutput extends AbstractOutput { parent::__construct($commandTask); - $this->commands = $commandTask->getCommands()->map( - fn(Command $command) => new CommandOutput($command) - )->toArray(); - - $this->commandGroups = $commandTask->getCommandGroups()->map( - fn(CommandGroup $commandGroup) => new CommandGroupOutput($commandGroup) - )->toArray(); + $this->name = $commandTask->getName(); $this->clients = $commandTask->getClients()->map( fn(Client $client) => new ClientOutput($client) )->toArray(); - $this->dateTime = $commandTask->getDateTime(); + $this->organizationalUnit = new OrganizationalUnitOutput($commandTask->getOrganizationalUnit()); $this->notes = $commandTask->getNotes(); - $this->status = $commandTask->getStatus(); + $this->scope = $commandTask->getScope(); + $this->lastExecution = $commandTask->getLastExecution(); + $this->nextExecution = $commandTask->getNextExecution(); $this->createdAt = $commandTask->getCreatedAt(); $this->createdBy = $commandTask->getCreatedBy(); } diff --git a/src/Dto/Output/CommandTaskScheduleOutput.php b/src/Dto/Output/CommandTaskScheduleOutput.php new file mode 100644 index 0000000..45dcd02 --- /dev/null +++ b/src/Dto/Output/CommandTaskScheduleOutput.php @@ -0,0 +1,41 @@ +recurrenceType = $commandTaskSchedule->getRecurrenceType(); + $this->executionTime = $commandTaskSchedule->getExecutionTime(); + $this->executionDate = $commandTaskSchedule->getExecutionDate(); + $this->recurrenceDetails = $commandTaskSchedule->getRecurrenceDetails(); + $this->enabled = $commandTaskSchedule->isEnabled(); + } +} \ No newline at end of file diff --git a/src/Dto/Output/CommandTaskScriptOutput.php b/src/Dto/Output/CommandTaskScriptOutput.php new file mode 100644 index 0000000..1354ffc --- /dev/null +++ b/src/Dto/Output/CommandTaskScriptOutput.php @@ -0,0 +1,42 @@ +content = $commandTaskScript->getContent(); + $this->order = $commandTaskScript->getExecutionOrder(); + $this->type = $commandTaskScript->getType(); + $this->parameters = $commandTaskScript->getParameters(); + $this->commandTaskOutput = new CommandTaskOutput($commandTaskScript->getCommandTask()); + } +} \ No newline at end of file diff --git a/src/Entity/Command.php b/src/Entity/Command.php index 0fea5cf..ab5d4bb 100644 --- a/src/Entity/Command.php +++ b/src/Entity/Command.php @@ -29,12 +29,6 @@ class Command extends AbstractEntity #[ORM\ManyToMany(targetEntity: CommandGroup::class, mappedBy: 'commands')] private Collection $commandGroups; - /** - * @var Collection - */ - #[ORM\ManyToMany(targetEntity: CommandTask::class, mappedBy: 'commands')] - private Collection $commandTasks; - #[ORM\Column(nullable: true)] private ?bool $parameters = null; @@ -42,7 +36,6 @@ class Command extends AbstractEntity { parent::__construct(); $this->commandGroups = new ArrayCollection(); - $this->commandTasks = new ArrayCollection(); } public function getScript(): ?string diff --git a/src/Entity/CommandTask.php b/src/Entity/CommandTask.php index b742212..f572155 100644 --- a/src/Entity/CommandTask.php +++ b/src/Entity/CommandTask.php @@ -11,122 +11,51 @@ use Doctrine\ORM\Mapping as ORM; #[ORM\Entity(repositoryClass: CommandTaskRepository::class)] class CommandTask extends AbstractEntity { - /** - * @var Collection - */ - #[ORM\ManyToMany(targetEntity: Command::class, inversedBy: 'commandTasks')] - private Collection $commands; - - /** - * @var Collection - */ - #[ORM\ManyToMany(targetEntity: CommandGroup::class, inversedBy: 'commandTasks')] - private Collection $commandGroups; - - #[ORM\Column(type: Types::DATETIME_MUTABLE)] - private ?\DateTimeInterface $datetime = null; + use NameableTrait; #[ORM\Column(length: 255, nullable: true)] private ?string $notes = null; - #[ORM\Column(length: 255)] - private ?string $status = null; - /** * @var Collection */ #[ORM\ManyToMany(targetEntity: Client::class)] private Collection $clients; + #[ORM\Column(type: Types::ARRAY, nullable: true)] + private ?array $parameters = null; + + #[ORM\ManyToOne] + private ?OrganizationalUnit $organizationalUnit = null; + + /** + * @var Collection + */ + #[ORM\OneToMany(mappedBy: 'commandTask', targetEntity: CommandTaskSchedule::class, cascade: ['persist'], orphanRemoval: true)] + private Collection $commandTaskSchedules; + + /** + * @var Collection + */ + #[ORM\OneToMany(mappedBy: 'commandTask', targetEntity: CommandTaskScript::class, cascade: ['persist'], orphanRemoval: true)] + private Collection $commandTaskScripts; + + #[ORM\Column(type: Types::DATETIME_MUTABLE, nullable: true)] + private ?\DateTimeInterface $lastExecution = null; + + #[ORM\Column(type: Types::DATETIME_MUTABLE, nullable: true)] + private ?\DateTimeInterface $nextExecution = null; + + #[ORM\Column(length: 255)] + private ?string $scope = null; + public function __construct() { parent::__construct(); - $this->commands = new ArrayCollection(); - $this->commandGroups = new ArrayCollection(); $this->clients = new ArrayCollection(); - } - - /** - * @return Collection - */ - public function getCommands(): Collection - { - return $this->commands; - } - - public function setCommands(array $commands): static - { - $this->commands->clear(); - - foreach ($commands as $command){ - $this->addCommand($command); - } - - return $this; - } - - public function addCommand(Command $command): static - { - if (!$this->commands->contains($command)) { - $this->commands->add($command); - } - - return $this; - } - - public function removeCommand(Command $command): static - { - $this->commands->removeElement($command); - - return $this; - } - - /** - * @return Collection - */ - public function getCommandGroups(): Collection - { - return $this->commandGroups; - } - - public function setCommandGroups(array $commandGroups): static - { - $this->commandGroups->clear(); - - foreach ($commandGroups as $commandGroup){ - $this->addCommandGroup($commandGroup); - } - - return $this; - } - - public function addCommandGroup(CommandGroup $commandGroup): static - { - if (!$this->commandGroups->contains($commandGroup)) { - $this->commandGroups->add($commandGroup); - } - - return $this; - } - - public function removeCommandGroup(CommandGroup $commandGroup): static - { - $this->commandGroups->removeElement($commandGroup); - - return $this; - } - - public function getDatetime(): ?\DateTimeInterface - { - return $this->datetime; - } - - public function setDatetime(\DateTimeInterface $datetime): static - { - $this->datetime = $datetime; - - return $this; + $this->commandTaskSchedules = new ArrayCollection(); + $this->commandTaskScripts = new ArrayCollection(); } public function getNotes(): ?string @@ -141,18 +70,6 @@ class CommandTask extends AbstractEntity return $this; } - public function getStatus(): ?string - { - return $this->status; - } - - public function setStatus(string $status): static - { - $this->status = $status; - - return $this; - } - /** * @return Collection */ @@ -187,4 +104,200 @@ class CommandTask extends AbstractEntity return $this; } + + public function getParameters(): ?array + { + return $this->parameters; + } + + public function setParameters(?array $parameters): static + { + $this->parameters = $parameters; + + return $this; + } + + public function getOrganizationalUnit(): ?OrganizationalUnit + { + return $this->organizationalUnit; + } + + public function setOrganizationalUnit(?OrganizationalUnit $organizationalUnit): static + { + $this->organizationalUnit = $organizationalUnit; + + return $this; + } + + /** + * @return Collection + */ + public function getCommandTaskSchedules(): Collection + { + return $this->commandTaskSchedules; + } + + public function addCommandTaskSchedule(CommandTaskSchedule $commandTaskSchedule): static + { + if (!$this->commandTaskSchedules->contains($commandTaskSchedule)) { + $this->commandTaskSchedules->add($commandTaskSchedule); + $commandTaskSchedule->setCommandTask($this); + } + + return $this; + } + + public function removeCommandTaskSchedule(CommandTaskSchedule $commandTaskSchedule): static + { + if ($this->commandTaskSchedules->removeElement($commandTaskSchedule)) { + // set the owning side to null (unless already changed) + if ($commandTaskSchedule->getCommandTask() === $this) { + $commandTaskSchedule->setCommandTask(null); + } + } + + return $this; + } + + /** + * @return Collection + */ + public function getCommandTaskScripts(): Collection + { + return $this->commandTaskScripts; + } + + public function addCommandTaskScript(CommandTaskScript $commandTaskScript): static + { + if (!$this->commandTaskScripts->contains($commandTaskScript)) { + $this->commandTaskScripts->add($commandTaskScript); + $commandTaskScript->setCommandTask($this); + } + + return $this; + } + + public function removeCommandTaskScript(CommandTaskScript $commandTaskScript): static + { + if ($this->commandTaskScripts->removeElement($commandTaskScript)) { + // set the owning side to null (unless already changed) + if ($commandTaskScript->getCommandTask() === $this) { + $commandTaskScript->setCommandTask(null); + } + } + + return $this; + } + + public function getLastExecution(): ?\DateTimeInterface + { + return $this->lastExecution; + } + + public function setLastExecution(?\DateTimeInterface $lastExecution): static + { + $this->lastExecution = $lastExecution; + + return $this; + } + + public function getNextExecution(): ?\DateTimeInterface + { + return $this->nextExecution; + } + + public function setNextExecution(?\DateTimeInterface $nextExecution): static + { + $this->nextExecution = $nextExecution; + + return $this; + } + + /** + * @throws \Exception + */ + public function calculateNextExecutionDate(): ?\DateTimeInterface + { + $now = new \DateTime(); + $closestDateTime = null; + + foreach ($this->getCommandTaskSchedules() as $schedule) { + $type = $schedule->getRecurrenceType(); + $executionTime = $schedule->getExecutionTime(); + + if ($type === 'none') { + $execDate = $schedule->getExecutionDate(); + if ($execDate !== null && $execDate > $now) { + if ($executionTime !== null) { + $execDateTime = \DateTime::createFromFormat( + 'Y-m-d H:i:s', + $execDate->format('Y-m-d') . ' ' . $executionTime->format('H:i:s') + ); + } else { + $execDateTime = $execDate; + } + + if ($closestDateTime === null || $execDateTime < $closestDateTime) { + $closestDateTime = $execDateTime; + } + } + } else { + $details = $schedule->getRecurrenceDetails(); + if ($details === null) { + continue; + } + + $init = (new \DateTime($details['initDate'] ?? 'now'))->setTime(0, 0); + $end = (new \DateTime($details['endDate'] ?? '+1 year'))->setTime(0, 0); + + $validDays = array_map('mb_strtolower', $details['daysOfWeek'] ?? []); + $validMonths = array_map('mb_strtolower', $details['months'] ?? []); + + $current = (new \DateTime())->setTime(0, 0); + + while ($current <= $end) { + if ($current < $init) { + $current->modify('+1 day'); + continue; + } + + $translatedDay = mb_strtolower($current->format('l')); + $translatedMonth = mb_strtolower($current->format('F')); + + if (in_array($translatedDay, $validDays, true) && in_array($translatedMonth, $validMonths, true)) { + if ($executionTime !== null) { + $execDateTime = \DateTime::createFromFormat( + 'Y-m-d H:i:s', + $current->format('Y-m-d') . ' ' . $executionTime->format('H:i:s') + ); + } else { + $execDateTime = clone $current; + } + + if ($execDateTime > $now && ($closestDateTime === null || $execDateTime < $closestDateTime)) { + $closestDateTime = $execDateTime; + } + + break; + } + + $current->modify('+1 day'); + } + } + } + + return $closestDateTime; + } + + public function getScope(): ?string + { + return $this->scope; + } + + public function setScope(string $scope): static + { + $this->scope = $scope; + + return $this; + } } diff --git a/src/Entity/CommandTaskSchedule.php b/src/Entity/CommandTaskSchedule.php new file mode 100644 index 0000000..b0698fd --- /dev/null +++ b/src/Entity/CommandTaskSchedule.php @@ -0,0 +1,89 @@ +recurrenceType; + } + + public function setRecurrenceType(string $recurrenceType): static + { + $this->recurrenceType = $recurrenceType; + + return $this; + } + + public function getRecurrenceDetails(): ?array + { + return $this->recurrenceDetails; + } + + public function setRecurrenceDetails(?array $recurrenceDetails): static + { + $this->recurrenceDetails = $recurrenceDetails; + + return $this; + } + + public function getCommandTask(): ?CommandTask + { + return $this->commandTask; + } + + public function setCommandTask(?CommandTask $commandTask): static + { + $this->commandTask = $commandTask; + + return $this; + } + + public function getExecutionTime(): ?\DateTimeInterface + { + return $this->executionTime; + } + + public function setExecutionTime(?\DateTimeInterface $executionTime): static + { + $this->executionTime = $executionTime; + + return $this; + } + + public function getExecutionDate(): ?\DateTimeInterface + { + return $this->executionDate; + } + + public function setExecutionDate(?\DateTimeInterface $executionDate): static + { + $this->executionDate = $executionDate; + + return $this; + } +} diff --git a/src/Entity/CommandTaskScript.php b/src/Entity/CommandTaskScript.php new file mode 100644 index 0000000..028e3c5 --- /dev/null +++ b/src/Entity/CommandTaskScript.php @@ -0,0 +1,92 @@ +id; + } + + public function getContent(): ?string + { + return $this->content; + } + + public function setContent(?string $content): static + { + $this->content = $content; + + return $this; + } + + public function getExecutionOrder(): ?int + { + return $this->executionOrder; + } + + public function setExecutionOrder(int $executionOrder): static + { + $this->executionOrder = $executionOrder; + + return $this; + } + + public function getCommandTask(): ?CommandTask + { + return $this->commandTask; + } + + public function setCommandTask(?CommandTask $commandTask): static + { + $this->commandTask = $commandTask; + + return $this; + } + + public function getType(): ?string + { + return $this->type; + } + + public function setType(string $type): static + { + $this->type = $type; + + return $this; + } + + public function getParameters(): ?array + { + return $this->parameters; + } + + public function setParameters(?array $parameters): static + { + $this->parameters = $parameters; + + return $this; + } +} diff --git a/src/Factory/CommandTaskFactory.php b/src/Factory/CommandTaskFactory.php index 91d2d09..c1375f3 100644 --- a/src/Factory/CommandTaskFactory.php +++ b/src/Factory/CommandTaskFactory.php @@ -3,6 +3,7 @@ namespace App\Factory; use App\Entity\CommandTask; +use App\Model\OrganizationalUnitTypes; use App\Repository\CommandTaskRepository; use Zenstruck\Foundry\ModelFactory; use Zenstruck\Foundry\Persistence\PersistentProxyObjectFactory; @@ -38,8 +39,9 @@ final class CommandTaskFactory extends ModelFactory { return [ 'createdAt' => self::faker()->dateTime(), - 'datetime' => self::faker()->dateTime(), - 'status' => self::faker()->text(255), + 'name' => self::faker()->text(255), + 'organizationalUnit' => OrganizationalUnitFactory::createOne(['type' => OrganizationalUnitTypes::ORGANIZATIONAL_UNIT])->_save(), + 'scope' => 'organizational-unit', 'updatedAt' => self::faker()->dateTime() ]; } diff --git a/src/Repository/CommandTaskScheduleRepository.php b/src/Repository/CommandTaskScheduleRepository.php new file mode 100644 index 0000000..1495bdd --- /dev/null +++ b/src/Repository/CommandTaskScheduleRepository.php @@ -0,0 +1,18 @@ + + */ +class CommandTaskScheduleRepository extends AbstractRepository +{ + public function __construct(ManagerRegistry $registry) + { + parent::__construct($registry, CommandTaskSchedule::class); + } +} diff --git a/src/Repository/CommandTaskScriptRepository.php b/src/Repository/CommandTaskScriptRepository.php new file mode 100644 index 0000000..ce498b8 --- /dev/null +++ b/src/Repository/CommandTaskScriptRepository.php @@ -0,0 +1,18 @@ + + */ +class CommandTaskScriptRepository extends AbstractRepository +{ + public function __construct(ManagerRegistry $registry) + { + parent::__construct($registry, CommandTaskScript::class); + } +} diff --git a/src/State/Processor/CommandTaskProcessor.php b/src/State/Processor/CommandTaskProcessor.php index fe39109..affab05 100644 --- a/src/State/Processor/CommandTaskProcessor.php +++ b/src/State/Processor/CommandTaskProcessor.php @@ -18,8 +18,7 @@ readonly class CommandTaskProcessor implements ProcessorInterface { public function __construct( private CommandTaskRepository $commandTaskRepository, - private ValidatorInterface $validator, - private CreateTraceService $createTraceService + private ValidatorInterface $validator ) { } @@ -56,7 +55,6 @@ readonly class CommandTaskProcessor implements ProcessorInterface $task = $data->createOrUpdateEntity($entity); $this->validator->validate($task); $this->commandTaskRepository->save($task); - $this->createTraceService->__invoke($task); return new CommandTaskOutput($task); } diff --git a/src/State/Processor/CommandTaskScheduleProcessor.php b/src/State/Processor/CommandTaskScheduleProcessor.php new file mode 100644 index 0000000..2a26017 --- /dev/null +++ b/src/State/Processor/CommandTaskScheduleProcessor.php @@ -0,0 +1,70 @@ +processCreateOrUpdate($data, $operation, $uriVariables, $context); + case $operation instanceof Delete: + return $this->processDelete($data, $operation, $uriVariables, $context); + } + } + + /** + * @throws \Exception + */ + private function processCreateOrUpdate($data, Operation $operation, array $uriVariables = [], array $context = []): CommandTaskScheduleOutput + { + if (!($data instanceof CommandTaskScheduleInput)) { + throw new \Exception(sprintf('data is not instance of %s', CommandTaskScheduleInput::class)); + } + + $entity = null; + if (isset($uriVariables['uuid'])) { + $entity = $this->commandTaskScheduleRepository->findOneByUuid($uriVariables['uuid']); + } + + $task = $data->createOrUpdateEntity($entity); + $this->validator->validate($task); + $this->commandTaskScheduleRepository->save($task); + + return new CommandTaskScheduleOutput($task); + } + + private function processDelete($data, Operation $operation, array $uriVariables = [], array $context = []): null + { + $user = $this->commandTaskScheduleRepository->findOneByUuid($uriVariables['uuid']); + $this->commandTaskScheduleRepository->delete($user); + + return null; + } +} \ No newline at end of file diff --git a/src/State/Processor/CommandTaskScriptProcessor.php b/src/State/Processor/CommandTaskScriptProcessor.php new file mode 100644 index 0000000..7a16f7b --- /dev/null +++ b/src/State/Processor/CommandTaskScriptProcessor.php @@ -0,0 +1,70 @@ +processCreateOrUpdate($data, $operation, $uriVariables, $context); + case $operation instanceof Delete: + return $this->processDelete($data, $operation, $uriVariables, $context); + } + } + + /** + * @throws \Exception + */ + private function processCreateOrUpdate($data, Operation $operation, array $uriVariables = [], array $context = []): CommandTaskScriptOutput + { + if (!($data instanceof CommandTaskScriptInput)) { + throw new \Exception(sprintf('data is not instance of %s', CommandTaskScriptInput::class)); + } + + $entity = null; + if (isset($uriVariables['uuid'])) { + $entity = $this->commandTaskScriptRepository->findOneByUuid($uriVariables['uuid']); + } + + $task = $data->createOrUpdateEntity($entity); + $this->validator->validate($task); + $this->commandTaskScriptRepository->save($task); + + return new CommandTaskScriptOutput($task); + } + + private function processDelete($data, Operation $operation, array $uriVariables = [], array $context = []): null + { + $user = $this->commandTaskScriptRepository->findOneByUuid($uriVariables['uuid']); + $this->commandTaskScriptRepository->delete($user); + + return null; + } +} \ No newline at end of file diff --git a/src/State/Provider/CommandTaskScheduleProvider.php b/src/State/Provider/CommandTaskScheduleProvider.php new file mode 100644 index 0000000..de2b6a9 --- /dev/null +++ b/src/State/Provider/CommandTaskScheduleProvider.php @@ -0,0 +1,71 @@ +provideCollection($operation, $uriVariables, $context); + case $operation instanceof Patch: + case $operation instanceof Put: + return $this->provideInput($operation, $uriVariables, $context); + case $operation instanceof Get: + return $this->provideItem($operation, $uriVariables, $context); + } + } + + private function provideCollection(Operation $operation, array $uriVariables = [], array $context = []): object|array|null + { + $paginator = $this->collectionProvider->provide($operation, $uriVariables, $context); + + $items = new \ArrayObject(); + foreach ($paginator->getIterator() as $item){ + $items[] = new CommandTaskScheduleOutput($item); + } + + return new TraversablePaginator($items, $paginator->getCurrentPage(), $paginator->getItemsPerPage(), $paginator->getTotalItems()); + } + + public function provideItem(Operation $operation, array $uriVariables = [], array $context = []): object|array|null + { + $item = $this->itemProvider->provide($operation, $uriVariables, $context); + + if (!$item) { + throw new NotFoundHttpException('Command task not found'); + } + + return new CommandTaskScheduleOutput($item); + } + + public function provideInput(Operation $operation, array $uriVariables = [], array $context = []): object|array|null + { + if (isset($uriVariables['uuid'])) { + $item = $this->itemProvider->provide($operation, $uriVariables, $context); + + return $item !== null ? new CommandTaskScheduleInput($item) : null; + } + + return new CommandTaskScheduleInput(); + } +} diff --git a/src/State/Provider/CommandTaskScriptProvider.php b/src/State/Provider/CommandTaskScriptProvider.php new file mode 100644 index 0000000..92b0d41 --- /dev/null +++ b/src/State/Provider/CommandTaskScriptProvider.php @@ -0,0 +1,72 @@ +provideCollection($operation, $uriVariables, $context); + case $operation instanceof Patch: + case $operation instanceof Put: + return $this->provideInput($operation, $uriVariables, $context); + case $operation instanceof Get: + return $this->provideItem($operation, $uriVariables, $context); + } + } + + private function provideCollection(Operation $operation, array $uriVariables = [], array $context = []): object|array|null + { + $paginator = $this->collectionProvider->provide($operation, $uriVariables, $context); + + $items = new \ArrayObject(); + foreach ($paginator->getIterator() as $item){ + $items[] = new CommandTaskScriptOutput($item); + } + + return new TraversablePaginator($items, $paginator->getCurrentPage(), $paginator->getItemsPerPage(), $paginator->getTotalItems()); + } + + public function provideItem(Operation $operation, array $uriVariables = [], array $context = []): object|array|null + { + $item = $this->itemProvider->provide($operation, $uriVariables, $context); + + if (!$item) { + throw new NotFoundHttpException('Command task not found'); + } + + return new CommandTaskScriptOutput($item); + } + + public function provideInput(Operation $operation, array $uriVariables = [], array $context = []): object|array|null + { + if (isset($uriVariables['uuid'])) { + $item = $this->itemProvider->provide($operation, $uriVariables, $context); + + return $item !== null ? new CommandTaskScriptInput($item) : null; + } + + return new CommandTaskScriptInput(); + } +} diff --git a/tests/Functional/CommandGroupTest.php b/tests/Functional/CommandGroupTest.php deleted file mode 100644 index de5faef..0000000 --- a/tests/Functional/CommandGroupTest.php +++ /dev/null @@ -1,127 +0,0 @@ - self::USER_ADMIN, 'roles'=> [UserGroupPermissions::ROLE_SUPER_ADMIN]]); - - CommandGroupFactory::createMany(10); - - $this->createClientWithCredentials()->request('GET', '/command-groups'); - $this->assertResponseStatusCodeSame(Response::HTTP_OK); - $this->assertResponseHeaderSame('content-type', 'application/ld+json; charset=utf-8'); - $this->assertJsonContains([ - '@context' => '/contexts/CommandGroup', - '@id' => '/command-groups', - '@type' => 'hydra:Collection', - 'hydra:totalItems' => 10, - ]); - } - - /** - * @throws RedirectionExceptionInterface - * @throws DecodingExceptionInterface - * @throws ClientExceptionInterface - * @throws TransportExceptionInterface - * @throws ServerExceptionInterface - */ - public function testCreateCommandGroup(): void - { - UserFactory::createOne(['username' => self::USER_ADMIN, 'roles'=> [UserGroupPermissions::ROLE_SUPER_ADMIN]]); - - CommandFactory::createOne(['name' => self::CMD_CREATE]); - $commandIri = $this->findIriBy(Command::class, ['name' => self::CMD_CREATE]); - - $this->createClientWithCredentials()->request('POST', '/command-groups',['json' => [ - 'name' => self::CMD_GROUP_CREATE, - 'commands' => [ - $commandIri - ] - ]]); - - $this->assertResponseStatusCodeSame(201); - $this->assertResponseHeaderSame('content-type', 'application/ld+json; charset=utf-8'); - $this->assertJsonContains([ - '@context' => '/contexts/CommandGroupOutput', - '@type' => 'CommandGroup', - 'name' => self::CMD_GROUP_CREATE, - ]); - } - - /** - * @throws RedirectionExceptionInterface - * @throws DecodingExceptionInterface - * @throws ClientExceptionInterface - * @throws TransportExceptionInterface - * @throws ServerExceptionInterface - */ - public function testUpdateCommandGroup(): void - { - UserFactory::createOne(['username' => self::USER_ADMIN, 'roles'=> [UserGroupPermissions::ROLE_SUPER_ADMIN]]); - - CommandGroupFactory::createOne(['name' => self::CMD_GROUP_CREATE]); - $iri = $this->findIriBy(CommandGroup::class, ['name' => self::CMD_GROUP_CREATE]); - - $this->createClientWithCredentials()->request('PUT', $iri, ['json' => [ - 'name' => self::CMD_GROUP_UPDATE, - ]]); - - $this->assertResponseIsSuccessful(); - $this->assertJsonContains([ - '@id' => $iri, - 'name' => self::CMD_GROUP_UPDATE - ]); - } - - /** - * @throws TransportExceptionInterface - * @throws ServerExceptionInterface - * @throws RedirectionExceptionInterface - * @throws DecodingExceptionInterface - * @throws ClientExceptionInterface - */ - public function testDeleteCommandGroup(): void - { - UserFactory::createOne(['username' => self::USER_ADMIN, 'roles'=> [UserGroupPermissions::ROLE_SUPER_ADMIN]]); - - CommandGroupFactory::createOne(['name' => self::CMD_GROUP_DELETE]); - $iri = $this->findIriBy(CommandGroup::class, ['name' => self::CMD_GROUP_DELETE]); - - $this->createClientWithCredentials()->request('DELETE', $iri); - $this->assertResponseStatusCodeSame(204); - $this->assertNull( - static::getContainer()->get('doctrine')->getRepository(CommandGroup::class)->findOneBy(['name' => self::CMD_GROUP_DELETE]) - ); - } -} \ No newline at end of file diff --git a/tests/Functional/CommandTaskTest.php b/tests/Functional/CommandTaskTest.php index 49b9555..5653ec2 100644 --- a/tests/Functional/CommandTaskTest.php +++ b/tests/Functional/CommandTaskTest.php @@ -4,9 +4,12 @@ namespace Functional; use App\Entity\Command; use App\Entity\CommandTask; +use App\Entity\OrganizationalUnit; use App\Factory\CommandFactory; use App\Factory\CommandTaskFactory; +use App\Factory\OrganizationalUnitFactory; use App\Factory\UserFactory; +use App\Model\OrganizationalUnitTypes; use App\Model\UserGroupPermissions; use Symfony\Component\HttpFoundation\Response; use Symfony\Contracts\HttpClient\Exception\ClientExceptionInterface; @@ -59,17 +62,13 @@ class CommandTaskTest extends AbstractTest { UserFactory::createOne(['username' => self::USER_ADMIN, 'roles'=> [UserGroupPermissions::ROLE_SUPER_ADMIN]]); - CommandFactory::createOne(['name' => self::CMD_CREATE]); - $commandIri = $this->findIriBy(Command::class, ['name' => self::CMD_CREATE]); - - $date = new \DateTimeImmutable(); + OrganizationalUnitFactory::createOne(['type' => OrganizationalUnitTypes::ORGANIZATIONAL_UNIT]); + $ouIri = $this->findIriBy(OrganizationalUnit::class, ['type' => OrganizationalUnitTypes::ORGANIZATIONAL_UNIT]); $this->createClientWithCredentials()->request('POST', '/command-tasks',['json' => [ - 'dateTime' => $date->format('Y-m-d H:i:s'), - 'notes' => self::CMD_TASK_CREATE, - 'commands' => [ - $commandIri - ] + 'name' => self::CMD_TASK_CREATE, + 'organizationalUnit' => $ouIri, + 'scope' => 'organizational-unit', ]]); $this->assertResponseStatusCodeSame(201); @@ -77,7 +76,8 @@ class CommandTaskTest extends AbstractTest $this->assertJsonContains([ '@context' => '/contexts/CommandTaskOutput', '@type' => 'CommandTask', - 'notes' => self::CMD_TASK_CREATE, + 'name' => self::CMD_TASK_CREATE, + 'scope' => 'organizational-unit', ]); } @@ -92,17 +92,23 @@ class CommandTaskTest extends AbstractTest { UserFactory::createOne(['username' => self::USER_ADMIN, 'roles'=> [UserGroupPermissions::ROLE_SUPER_ADMIN]]); - CommandTaskFactory::createOne(['notes' => self::CMD_TASK_CREATE]); - $iri = $this->findIriBy(CommandTask::class, ['notes' => self::CMD_TASK_CREATE]); + CommandTaskFactory::createOne(['name' => self::CMD_TASK_CREATE]); + $iri = $this->findIriBy(CommandTask::class, ['name' => self::CMD_TASK_CREATE]); + + OrganizationalUnitFactory::createOne(['type' => OrganizationalUnitTypes::ORGANIZATIONAL_UNIT]); + $ouIri = $this->findIriBy(OrganizationalUnit::class, ['type' => OrganizationalUnitTypes::ORGANIZATIONAL_UNIT]); $this->createClientWithCredentials()->request('PUT', $iri, ['json' => [ - 'notes' => self::CMD_TASK_UPDATE, + 'name' => self::CMD_TASK_UPDATE, + 'organizationalUnit' => $ouIri, + 'scope' => 'organizational-unit', ]]); $this->assertResponseIsSuccessful(); $this->assertJsonContains([ '@id' => $iri, - 'notes' => self::CMD_TASK_UPDATE + 'name' => self::CMD_TASK_UPDATE, + 'scope' => 'organizational-unit', ]); } @@ -117,13 +123,15 @@ class CommandTaskTest extends AbstractTest { UserFactory::createOne(['username' => self::USER_ADMIN, 'roles'=> [UserGroupPermissions::ROLE_SUPER_ADMIN]]); - CommandTaskFactory::createOne(['notes' => self::CMD_TASK_DELETE]); - $iri = $this->findIriBy(CommandTask::class, ['notes' => self::CMD_TASK_DELETE]); + $ou = OrganizationalUnitFactory::createOne(['type' => OrganizationalUnitTypes::ORGANIZATIONAL_UNIT]); + + CommandTaskFactory::createOne(['name' => self::CMD_TASK_DELETE, 'organizationalUnit' => $ou, 'scope' => 'organizational-unit']); + $iri = $this->findIriBy(CommandTask::class, ['name' => self::CMD_TASK_DELETE]); $this->createClientWithCredentials()->request('DELETE', $iri); $this->assertResponseStatusCodeSame(204); $this->assertNull( - static::getContainer()->get('doctrine')->getRepository(CommandTask::class)->findOneBy(['notes' => self::CMD_TASK_DELETE]) + static::getContainer()->get('doctrine')->getRepository(CommandTask::class)->findOneBy(['name' => self::CMD_TASK_DELETE]) ); } } \ No newline at end of file