API endpoints to delete customer/project/activity (#5181)
* added service methods with events to delete customer, project, activity * added API endpoints to delete customer, project, activity * added tests for new API endpoints
This commit is contained in:
@@ -9,6 +9,7 @@
|
||||
|
||||
namespace App\API;
|
||||
|
||||
use App\Activity\ActivityService;
|
||||
use App\Entity\Activity;
|
||||
use App\Entity\ActivityRate;
|
||||
use App\Entity\User;
|
||||
@@ -46,7 +47,8 @@ final class ActivityController extends BaseApiController
|
||||
private readonly ViewHandlerInterface $viewHandler,
|
||||
private readonly ActivityRepository $repository,
|
||||
private readonly EventDispatcherInterface $dispatcher,
|
||||
private readonly ActivityRateRepository $activityRateRepository
|
||||
private readonly ActivityRateRepository $activityRateRepository,
|
||||
private readonly ActivityService $activityService
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -208,6 +210,25 @@ final class ActivityController extends BaseApiController
|
||||
return $this->viewHandler->handle($view);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete an existing activity
|
||||
*
|
||||
* [DANGER] This will also delete ALL linked timesheets.
|
||||
* Maybe use `PATCH` instead and mark it as inactive with `visible=false`?
|
||||
*/
|
||||
#[IsGranted('delete', 'activity')]
|
||||
#[OA\Delete(responses: [new OA\Response(response: 204, description: 'Delete one activity')])]
|
||||
#[OA\Parameter(name: 'id', description: 'Activity ID to delete', in: 'path', required: true)]
|
||||
#[Route(path: '/{id}', name: 'delete_activity', requirements: ['id' => '\d+'], methods: ['DELETE'])]
|
||||
public function deleteAction(Activity $activity): Response
|
||||
{
|
||||
$this->activityService->deleteActivity($activity);
|
||||
|
||||
$view = new View(null, Response::HTTP_NO_CONTENT);
|
||||
|
||||
return $this->viewHandler->handle($view);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of a meta-field for an existing activity
|
||||
*/
|
||||
|
||||
@@ -46,7 +46,8 @@ final class CustomerController extends BaseApiController
|
||||
private readonly ViewHandlerInterface $viewHandler,
|
||||
private readonly CustomerRepository $repository,
|
||||
private readonly EventDispatcherInterface $dispatcher,
|
||||
private readonly CustomerRateRepository $customerRateRepository
|
||||
private readonly CustomerRateRepository $customerRateRepository,
|
||||
private readonly CustomerService $customerService,
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -185,6 +186,25 @@ final class CustomerController extends BaseApiController
|
||||
return $this->viewHandler->handle($view);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete an existing customer
|
||||
*
|
||||
* [DANGER] This will also delete ALL linked projects, project activities and timesheets.
|
||||
* Maybe use `PATCH` instead and mark it as inactive with `visible=false`?
|
||||
*/
|
||||
#[IsGranted('delete', 'customer')]
|
||||
#[OA\Delete(responses: [new OA\Response(response: 204, description: 'Delete one customer')])]
|
||||
#[OA\Parameter(name: 'id', description: 'Customer ID to delete', in: 'path', required: true)]
|
||||
#[Route(path: '/{id}', name: 'delete_customer', requirements: ['id' => '\d+'], methods: ['DELETE'])]
|
||||
public function deleteAction(Customer $customer): Response
|
||||
{
|
||||
$this->customerService->deleteCustomer($customer);
|
||||
|
||||
$view = new View(null, Response::HTTP_NO_CONTENT);
|
||||
|
||||
return $this->viewHandler->handle($view);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of a meta-field for an existing customer
|
||||
*/
|
||||
|
||||
@@ -240,6 +240,25 @@ final class ProjectController extends BaseApiController
|
||||
return $this->viewHandler->handle($view);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete an existing project
|
||||
*
|
||||
* [DANGER] This will also delete ALL linked activities and timesheets.
|
||||
* Maybe use `PATCH` instead and mark it as inactive with `visible=false`?
|
||||
*/
|
||||
#[IsGranted('delete', 'project')]
|
||||
#[OA\Delete(responses: [new OA\Response(response: 204, description: 'Delete one project')])]
|
||||
#[OA\Parameter(name: 'id', description: 'Project ID to delete', in: 'path', required: true)]
|
||||
#[Route(path: '/{id}', name: 'delete_project', requirements: ['id' => '\d+'], methods: ['DELETE'])]
|
||||
public function deleteAction(Project $project): Response
|
||||
{
|
||||
$this->projectService->deleteProject($project);
|
||||
|
||||
$view = new View(null, Response::HTTP_NO_CONTENT);
|
||||
|
||||
return $this->viewHandler->handle($view);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of a meta-field for an existing project
|
||||
*/
|
||||
|
||||
@@ -15,6 +15,7 @@ use App\Entity\Project;
|
||||
use App\Event\ActivityCreateEvent;
|
||||
use App\Event\ActivityCreatePostEvent;
|
||||
use App\Event\ActivityCreatePreEvent;
|
||||
use App\Event\ActivityDeleteEvent;
|
||||
use App\Event\ActivityMetaDefinitionEvent;
|
||||
use App\Event\ActivityUpdatePostEvent;
|
||||
use App\Event\ActivityUpdatePreEvent;
|
||||
@@ -69,8 +70,13 @@ class ActivityService
|
||||
return $activity;
|
||||
}
|
||||
|
||||
public function deleteActivity(Activity $activity): void
|
||||
{
|
||||
$this->dispatcher->dispatch(new ActivityDeleteEvent($activity));
|
||||
$this->repository->deleteActivity($activity);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Activity $activity
|
||||
* @param string[] $groups
|
||||
* @throws ValidationFailedException
|
||||
*/
|
||||
|
||||
@@ -14,6 +14,7 @@ use App\Entity\Customer;
|
||||
use App\Event\CustomerCreateEvent;
|
||||
use App\Event\CustomerCreatePostEvent;
|
||||
use App\Event\CustomerCreatePreEvent;
|
||||
use App\Event\CustomerDeleteEvent;
|
||||
use App\Event\CustomerMetaDefinitionEvent;
|
||||
use App\Event\CustomerUpdatePostEvent;
|
||||
use App\Event\CustomerUpdatePreEvent;
|
||||
@@ -73,6 +74,12 @@ final class CustomerService
|
||||
return $customer;
|
||||
}
|
||||
|
||||
public function deleteCustomer(Customer $customer): void
|
||||
{
|
||||
$this->dispatcher->dispatch(new CustomerDeleteEvent($customer));
|
||||
$this->repository->deleteCustomer($customer);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $groups
|
||||
* @throws ValidationFailedException
|
||||
|
||||
17
src/Event/ActivityDeleteEvent.php
Normal file
17
src/Event/ActivityDeleteEvent.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Kimai time-tracking app.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace App\Event;
|
||||
|
||||
/**
|
||||
* Triggered right before a activity will be deleted.
|
||||
*/
|
||||
final class ActivityDeleteEvent extends AbstractActivityEvent
|
||||
{
|
||||
}
|
||||
17
src/Event/CustomerDeleteEvent.php
Normal file
17
src/Event/CustomerDeleteEvent.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Kimai time-tracking app.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace App\Event;
|
||||
|
||||
/**
|
||||
* Triggered right before a customer will be deleted.
|
||||
*/
|
||||
final class CustomerDeleteEvent extends AbstractCustomerEvent
|
||||
{
|
||||
}
|
||||
17
src/Event/ProjectDeleteEvent.php
Normal file
17
src/Event/ProjectDeleteEvent.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Kimai time-tracking app.
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace App\Event;
|
||||
|
||||
/**
|
||||
* Triggered right before a project will be deleted.
|
||||
*/
|
||||
final class ProjectDeleteEvent extends AbstractProjectEvent
|
||||
{
|
||||
}
|
||||
@@ -15,6 +15,7 @@ use App\Entity\Project;
|
||||
use App\Event\ProjectCreateEvent;
|
||||
use App\Event\ProjectCreatePostEvent;
|
||||
use App\Event\ProjectCreatePreEvent;
|
||||
use App\Event\ProjectDeleteEvent;
|
||||
use App\Event\ProjectMetaDefinitionEvent;
|
||||
use App\Event\ProjectUpdatePostEvent;
|
||||
use App\Event\ProjectUpdatePreEvent;
|
||||
@@ -77,8 +78,13 @@ final class ProjectService
|
||||
return $project;
|
||||
}
|
||||
|
||||
public function deleteProject(Project $project): void
|
||||
{
|
||||
$this->dispatcher->dispatch(new ProjectDeleteEvent($project));
|
||||
$this->repository->deleteProject($project);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Project $project
|
||||
* @param string[] $groups
|
||||
* @throws ValidationFailedException
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user