Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
264 changes: 264 additions & 0 deletions ProcessMaker/Http/Controllers/Api/Actions/Cases/DeleteCase.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,264 @@
<?php

namespace ProcessMaker\Http\Controllers\Api\Actions\Cases;

use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
use ProcessMaker\Models\CaseNumber;
use ProcessMaker\Models\CaseParticipated;
use ProcessMaker\Models\CaseStarted;
use ProcessMaker\Models\Comment;
use ProcessMaker\Models\InboxRule;
use ProcessMaker\Models\InboxRuleLog;
use ProcessMaker\Models\Media;
use ProcessMaker\Models\ProcessAbeRequestToken;
use ProcessMaker\Models\ProcessRequest;
use ProcessMaker\Models\ProcessRequestLock;
use ProcessMaker\Models\ProcessRequestToken;
use ProcessMaker\Models\ScheduledTask;
use ProcessMaker\Models\TaskDraft;

class DeleteCase
{
public function __invoke(string $caseNumber): void
{
$requestIds = $this->getRequestIds($caseNumber);

if ($requestIds === []) {
abort(404);
}

$tokenIds = $this->getRequestTokenIds($requestIds);

DB::transaction(function () use ($caseNumber, $requestIds, $tokenIds) {
$this->deleteInboxRuleLogs($tokenIds);
$this->deleteInboxRules($tokenIds);
$this->deleteProcessRequestLocks($requestIds, $tokenIds);
$this->deleteProcessAbeRequestTokens($requestIds, $tokenIds);
$this->deleteScheduledTasks($requestIds, $tokenIds);
$this->deleteEllucianEthosSyncTasks($tokenIds);
$draftIds = $this->getTaskDraftIds($tokenIds);
$this->deleteTaskDraftMedia($draftIds);
$this->deleteTaskDrafts($tokenIds);
$this->deleteComments($caseNumber, $requestIds, $tokenIds);
$this->deleteRequestMedia($requestIds);
$this->deleteCaseNumbers($requestIds);
$this->deleteCasesStarted($caseNumber);
$this->deleteCasesParticipated($caseNumber);
$this->deleteProcessRequestTokens($requestIds);
$this->deleteProcessRequests($requestIds);
});
}

private function getRequestIds(string $caseNumber): array
{
return ProcessRequest::query()
->where('case_number', $caseNumber)
->pluck('id')
->all();
}

private function getRequestTokenIds(array $requestIds): array
{
if ($requestIds === []) {
return [];
}

return ProcessRequestToken::query()
->whereIn('process_request_id', $requestIds)
->pluck('id')
->all();
}

private function getTaskDraftIds(array $tokenIds): array
{
if ($tokenIds === []) {
return [];
}

return TaskDraft::query()
->whereIn('task_id', $tokenIds)
->pluck('id')
->all();
}

private function deleteCasesStarted(string $caseNumber): void
{
CaseStarted::query()
->where('case_number', $caseNumber)
->delete();
}

private function deleteCasesParticipated(string $caseNumber): void
{
CaseParticipated::query()
->where('case_number', $caseNumber)
->delete();
}

private function deleteCaseNumbers(array $requestIds): void
{
if ($requestIds === []) {
return;
}

CaseNumber::query()
->whereIn('process_request_id', $requestIds)
->delete();
}

private function deleteProcessRequests(array $requestIds): void
{
if ($requestIds === []) {
return;
}

ProcessRequest::query()
->whereIn('id', $requestIds)
->get()
->each
->delete();
}

private function deleteProcessRequestTokens(array $requestIds): void
{
if ($requestIds === []) {
return;
}

ProcessRequestToken::query()
->whereIn('process_request_id', $requestIds)
->delete();
}

private function deleteProcessRequestLocks(array $requestIds, array $tokenIds): void
{
ProcessRequestLock::query()
->whereIn('process_request_id', $requestIds)
->delete();

if ($tokenIds !== []) {
ProcessRequestLock::query()
->whereIn('process_request_token_id', $tokenIds)
->delete();
}
}

private function deleteProcessAbeRequestTokens(array $requestIds, array $tokenIds): void
{
ProcessAbeRequestToken::query()
->whereIn('process_request_id', $requestIds)
->delete();

if ($tokenIds !== []) {
ProcessAbeRequestToken::query()
->whereIn('process_request_token_id', $tokenIds)
->delete();
}
}

private function deleteScheduledTasks(array $requestIds, array $tokenIds): void
{
ScheduledTask::query()
->whereIn('process_request_id', $requestIds)
->delete();

if ($tokenIds !== []) {
ScheduledTask::query()
->whereIn('process_request_token_id', $tokenIds)
->delete();
}
}

private function deleteInboxRules(array $tokenIds): void
{
if ($tokenIds === []) {
return;
}

InboxRule::query()
->whereIn('process_request_token_id', $tokenIds)
->get()
->each
->delete();
}

private function deleteInboxRuleLogs(array $tokenIds): void
{
if ($tokenIds === []) {
return;
}

InboxRuleLog::query()
->whereIn('process_request_token_id', $tokenIds)
->delete();
}

private function deleteEllucianEthosSyncTasks(array $tokenIds): void
{
if ($tokenIds === [] || !Schema::hasTable('ellucian_ethos_sync_global_task_list')) {
return;
}

DB::table('ellucian_ethos_sync_global_task_list')
->whereIn('process_request_token_id', $tokenIds)
->delete();
}

private function deleteTaskDrafts(array $tokenIds): void
{
if ($tokenIds === []) {
return;
}

TaskDraft::query()
->whereIn('task_id', $tokenIds)
->delete();
}

private function deleteTaskDraftMedia(array $draftIds): void
{
if ($draftIds === []) {
return;
}

Media::query()
->where('model_type', TaskDraft::class)
->whereIn('model_id', $draftIds)
->get()
->each
->delete();
}

private function deleteRequestMedia(array $requestIds): void
{
if ($requestIds === []) {
return;
}

Media::query()
->where('model_type', ProcessRequest::class)
->whereIn('model_id', $requestIds)
->get()
->each
->delete();
}

private function deleteComments(string $caseNumber, array $requestIds, array $tokenIds): void
{
Comment::query()
->where('case_number', $caseNumber)
->orWhere(function ($query) use ($requestIds, $tokenIds) {
$query->where('commentable_type', ProcessRequest::class)
->whereIn('commentable_id', $requestIds);

if ($tokenIds !== []) {
$query->orWhere(function ($nestedQuery) use ($tokenIds) {
$nestedQuery->where('commentable_type', ProcessRequestToken::class)
->whereIn('commentable_id', $tokenIds);
});
}
})
->delete();
}
}
58 changes: 52 additions & 6 deletions ProcessMaker/Http/Controllers/Api/CaseController.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

namespace ProcessMaker\Http\Controllers\Api;

use Illuminate\Http\JsonResponse;
use ProcessMaker\Http\Controllers\Api\Actions\Cases\DeleteCase;
use ProcessMaker\Http\Controllers\Controller;
use ProcessMaker\Models\Process;
use ProcessMaker\Models\ProcessRequest;
Expand All @@ -12,7 +14,7 @@ class CaseController extends Controller
/**
* Get stage information for cases
*/
public function getStagePerCase($case_number = null)
public function getStagePerCase(?string $case_number = null): JsonResponse
{
if (!empty($case_number)) {
$responseData = $this->getSpecificCaseStages($case_number);
Expand All @@ -31,12 +33,56 @@ public function getStagePerCase($case_number = null)
return response()->json($responseData);
}

/**
* Delete a case and its related requests.
*
* @param string $case_number
* @return JsonResponse
*
* @OA\Delete(
* path="/cases/{case_number}",
* summary="Delete a case and its related requests",
* operationId="deleteCase",
* tags={"Cases"},
* @OA\Parameter(
* description="Case number to delete",
* in="path",
* name="case_number",
* required=true,
* @OA\Schema(type="string")
* ),
* @OA\Response(
* response=204,
* description="success"
* ),
* @OA\Response(
* response=401,
* description="Unauthorized"
* ),
* @OA\Response(response=404, ref="#/components/responses/404"),
* @OA\Response(
* response=409,
* description="Conflict"
* ),
* @OA\Response(
* response=500,
* description="Internal Server Error"
* ),
* )
*/
public function destroy(string $case_number): JsonResponse
{
(new DeleteCase)($case_number);

return response()->json([], 204);
}

/**
* Get specific case stages information
* @param string $caseNumber The unique identifier of the case to retrieve stages for
* @return array
*/
private function getSpecificCaseStages($caseNumber)
private function getSpecificCaseStages(string $caseNumber): array
{
$allRequests = ProcessRequest::where('case_number', $caseNumber)->get();
// Check if any requests were found
Expand Down Expand Up @@ -75,7 +121,7 @@ private function getSpecificCaseStages($caseNumber)
* @param string|null $status The status to set for the stages
* @return array
*/
private function getDefaultCaseStages($status = null)
private function getDefaultCaseStages(?string $status = null): array
{
return [
[
Expand All @@ -100,7 +146,7 @@ private function getDefaultCaseStages($status = null)
* @param string $stageName The name of the stage ('In Progress' or 'Completed')
* @return string The mapped status
*/
private function mapStatus($status, $stageName)
private function mapStatus(?string $status, string $stageName): string
{
if ($status === 'COMPLETED') {
return 'Done';
Expand All @@ -120,11 +166,11 @@ private function mapStatus($status, $stageName)
/**
* Get the stages summary based on the provided request.
*
* @param $requestId
* @param ProcessRequest $request
* @return array An array of stage results, each containing the stage ID, name, status,
* and completion date.
*/
private function getStagesSummary(ProcessRequest $request)
private function getStagesSummary(ProcessRequest $request): array
{
$requestId = $request->id;
$processId = $request->process_id;
Expand Down
4 changes: 3 additions & 1 deletion ProcessMaker/Models/InboxRule.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,9 @@ class InboxRule extends ProcessMakerModel
protected static function booted()
{
static::deleting(function (InboxRule $inboxRule) {
$inboxRule->savedSearch()->delete();
if (class_exists(SavedSearch::class)) {
$inboxRule->savedSearch()->delete();
}
});
}

Expand Down
Loading
Loading