-
Notifications
You must be signed in to change notification settings - Fork 209
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add new get_all_cases endpoint
- Loading branch information
1 parent
794c160
commit 55d771c
Showing
7 changed files
with
370 additions
and
1 deletion.
There are no files selected for viewing
200 changes: 200 additions & 0 deletions
200
ProcessMaker/Http/Controllers/Api/V1_1/CaseController.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,200 @@ | ||
<?php | ||
|
||
namespace ProcessMaker\Http\Controllers\Api\V1_1; | ||
|
||
use Illuminate\Database\Eloquent\Builder; | ||
use Illuminate\Http\Request; | ||
use Illuminate\Http\Response; | ||
use ProcessMaker\Http\Controllers\Controller; | ||
use ProcessMaker\Http\Requests\GetAllCasesRequest; | ||
use ProcessMaker\Http\Resources\V1_1\CaseResource; | ||
use ProcessMaker\Models\CaseStarted; | ||
|
||
class CaseController extends Controller | ||
{ | ||
protected $defaultFields = [ | ||
'case_number', | ||
'user_id', | ||
'case_title', | ||
'case_title_formatted', | ||
'case_status', | ||
'processes', | ||
'requests', | ||
'request_tokens', | ||
'tasks', | ||
'participants', | ||
'initiated_at', | ||
'completed_at', | ||
]; | ||
|
||
protected $sortableFields = [ | ||
'case_number', | ||
'initiated_at', | ||
'completed_at', | ||
]; | ||
|
||
protected $filterableFields = [ | ||
'case_number', | ||
'case_title', | ||
'case_status', | ||
'processes', | ||
'requests', | ||
'request_tokens', | ||
'tasks', | ||
'participants', | ||
'initiated_at', | ||
'completed_at', | ||
]; | ||
|
||
protected $searchableFields = [ | ||
'case_number', | ||
'case_title', | ||
]; | ||
|
||
protected $dateFields = [ | ||
'initiated_at', | ||
'completed_at', | ||
'created_at', | ||
'updated_at', | ||
]; | ||
|
||
/** | ||
* Get a list of all started cases. | ||
* | ||
* @param Request $request | ||
* | ||
* @queryParam userId int Filter by user ID. | ||
* @queryParam status string Filter by case status. | ||
* @queryParam sortBy string Sort by field:asc,field2:desc,... | ||
* @queryParam filterBy array Filter by field=value&field2=value2&... | ||
* @queryParam search string Search by case number or case title. | ||
* @queryParam pageSize int Number of items per page. | ||
* @queryParam page int Page number. | ||
* | ||
* @return array | ||
*/ | ||
public function getAllCases(GetAllCasesRequest $request): array | ||
{ | ||
$pageSize = $request->get('pageSize', 15); | ||
|
||
$query = CaseStarted::select($this->defaultFields); | ||
|
||
$this->filters($request, $query); | ||
|
||
$pagination = CaseResource::collection($query->paginate($pageSize)); | ||
|
||
return [ | ||
'data' => $pagination->items(), | ||
'meta' => [ | ||
'total' => $pagination->total(), | ||
'perPage' => $pagination->perPage(), | ||
'currentPage' => $pagination->currentPage(), | ||
'lastPage' => $pagination->lastPage(), | ||
], | ||
]; | ||
} | ||
|
||
/** | ||
* Apply filters to the query. | ||
* | ||
* @param Request $request | ||
* @param Builder $query | ||
* | ||
* @return void | ||
*/ | ||
private function filters(Request $request, Builder $query): void | ||
{ | ||
if ($request->has('userId')) { | ||
$query->where('user_id', $request->get('userId')); | ||
} | ||
|
||
if ($request->has('status')) { | ||
$query->where('case_status', $request->get('status')); | ||
} | ||
|
||
$this->search($request, $query); | ||
$this->filterBy($request, $query); | ||
$this->sortBy($request, $query); | ||
} | ||
|
||
/** | ||
* Sort the query. | ||
* | ||
* @param Request $request: Query parameter format: sortBy=field:asc,field2:desc,... | ||
* @param Builder $query | ||
* | ||
* @return void | ||
*/ | ||
private function sortBy(Request $request, Builder $query): void | ||
{ | ||
$sort = explode(',', $request->get('sortBy')); | ||
|
||
foreach ($sort as $value) { | ||
if (!preg_match('/^[a-zA-Z_]+:(asc|desc)$/', $value)) { | ||
continue; | ||
} | ||
|
||
$sort = explode(':', $value); | ||
$field = $sort[0]; | ||
$order = $sort[1] ?? 'asc'; | ||
|
||
if (in_array($field, $this->sortableFields)) { | ||
$query->orderBy($field, $order); | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* Filter the query. | ||
* | ||
* @param Request $request: Query parameter format: filterBy[field]=value&filterBy[field2]=value2&... | ||
* @param Builder $query | ||
* @param array $dateFields List of date fields in current model | ||
* | ||
* @return void | ||
*/ | ||
private function filterBy(Request $request, Builder $query): void | ||
{ | ||
if ($request->has('filterBy')) { | ||
$filterByValue = $request->get('filterBy'); | ||
|
||
foreach ($filterByValue as $key => $value) { | ||
if (!in_array($key, $this->filterableFields)) { | ||
continue; | ||
} | ||
|
||
if (in_array($key, $this->dateFields)) { | ||
$query->whereDate($key, $value); | ||
continue; | ||
} | ||
|
||
$query->where($key, $value); | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* Search by case number or case title. | ||
* @param Request $request: Query parameter format: search=keyword | ||
* @param Builder $query | ||
* | ||
* @return void | ||
*/ | ||
private function search(Request $request, Builder $query): void | ||
{ | ||
if ($request->has('search')) { | ||
$search = $request->get('search'); | ||
|
||
$query->where(function ($q) use ($search) { | ||
foreach ($this->searchableFields as $field) { | ||
if ($field === 'case_number') { | ||
$q->orWhere($field, 'like', "%$search%"); | ||
} else { | ||
$q->orWhereFullText($field, $search . '*', ['mode' => 'boolean']); | ||
} | ||
} | ||
}); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
<?php | ||
|
||
namespace ProcessMaker\Http\Requests; | ||
|
||
use Illuminate\Foundation\Http\FormRequest; | ||
|
||
class GetAllCasesRequest extends FormRequest | ||
{ | ||
/** | ||
* Determine if the user is authorized to make this request. | ||
*/ | ||
public function authorize(): bool | ||
{ | ||
return true; | ||
} | ||
|
||
/** | ||
* Get the validation rules that apply to the request. | ||
* | ||
* @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string> | ||
*/ | ||
public function rules(): array | ||
{ | ||
return [ | ||
'userId' => 'sometimes|integer', | ||
'status' => 'sometimes|in:in_progress,completed', | ||
'sortBy' => 'sometimes|string', | ||
'filterBy' => 'sometimes|array', | ||
'search' => 'sometimes|string', | ||
'pageSize' => 'sometimes|integer|min:1', | ||
'page' => 'sometimes|integer|min:1', | ||
]; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
<?php | ||
|
||
namespace ProcessMaker\Http\Resources\V1_1; | ||
|
||
use ProcessMaker\Http\Resources\ApiResource; | ||
|
||
class CaseResource extends ApiResource | ||
{ | ||
protected static $defaultFields = [ | ||
'case_number', | ||
'user_id', | ||
'case_title', | ||
'case_title_formatted', | ||
'case_status', | ||
'processes', | ||
'requests', | ||
'request_tokens', | ||
'tasks', | ||
'participants', | ||
'initiated_at', | ||
'completed_at', | ||
]; | ||
|
||
public function toArray($request): array | ||
{ | ||
$data = []; | ||
|
||
foreach (static::$defaultFields as $field) { | ||
$data[$field] = $this->$field; | ||
} | ||
|
||
return $data; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
<?php | ||
|
||
namespace Database\Factories; | ||
|
||
use Illuminate\Database\Eloquent\Factories\Factory; | ||
use ProcessMaker\Models\CaseStarted; | ||
|
||
/** | ||
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\ProcessMaker\Models\CaseStarted> | ||
*/ | ||
class CaseStartedFactory extends Factory | ||
{ | ||
protected $model = CaseStarted::class; | ||
|
||
/** | ||
* Define the model's default state. | ||
* | ||
* @return array<string, mixed> | ||
*/ | ||
public function definition(): array | ||
{ | ||
return [ | ||
'case_number' => fake()->unique()->randomNumber(), | ||
'user_id' => fake()->randomElement([1, 3]), | ||
'case_title' => fake()->words(3, true), | ||
'case_title_formatted' => fake()->words(3, true), | ||
'case_status' => fake()->randomElement(['in_progress', 'completed']), | ||
'processes' => array_map(function() { | ||
return [ | ||
'id' => fake()->randomNumber(), | ||
'name' => fake()->words(2, true), | ||
]; | ||
}, range(1, 3)), | ||
'requests' => [ | ||
[ | ||
'id' => fake()->randomNumber(), | ||
'name' => fake()->words(2, true), | ||
'parent_request' => fake()->randomNumber(), | ||
], | ||
[ | ||
'id' => fake()->randomNumber(), | ||
'name' => fake()->words(3, true), | ||
'parent_request' => fake()->randomNumber(), | ||
], | ||
], | ||
'request_tokens' => fake()->randomElement([fake()->randomNumber(), fake()->randomNumber(), fake()->randomNumber()]), | ||
'tasks' => [ | ||
[ | ||
'id' => fake()->numerify('node_####'), | ||
'name' => fake()->words(4, true), | ||
], | ||
[ | ||
'id' => fake()->numerify('node_####'), | ||
'name' => fake()->words(3, true), | ||
], | ||
[ | ||
'id' => fake()->numerify('node_####'), | ||
'name' => fake()->words(2, true), | ||
], | ||
], | ||
'participants' => [ | ||
[ | ||
'id' => fake()->randomNumber(), | ||
'name' => fake()->name(), | ||
], | ||
[ | ||
'id' => fake()->randomNumber(), | ||
'name' => fake()->name(), | ||
], | ||
[ | ||
'id' => fake()->randomNumber(), | ||
'name' => fake()->name(), | ||
], | ||
], | ||
'initiated_at' => fake()->dateTime(), | ||
'completed_at' => fake()->dateTime(), | ||
'keywords' => '', | ||
]; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.