Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
91e87f0
feat: add cases_started migration
devmiguelangel Sep 9, 2024
794c160
feat: add cases started model
devmiguelangel Sep 9, 2024
55d771c
feat: add new get_all_cases endpoint
devmiguelangel Sep 11, 2024
a1ca7a7
Merge branch 'feature/FOUR-18078' into FOUR-18603
devmiguelangel Sep 11, 2024
2fc73d7
fix cr observations
devmiguelangel Sep 12, 2024
caa509c
Merge pull request #7357 from ProcessMaker/FOUR-18603
caleeli Sep 12, 2024
d1313a2
feat: add cases_participated migration
devmiguelangel Sep 12, 2024
9d58af0
feat: add cases_participated model, factory
devmiguelangel Sep 12, 2024
1b66edf
feat: add get_in_progress, get_completed endpoints
devmiguelangel Sep 13, 2024
c2ee011
feat: add case repository
devmiguelangel Sep 13, 2024
5e23427
feat: add validation exception
devmiguelangel Sep 13, 2024
63de52c
Merge branch 'next' into feature/FOUR-18078
devmiguelangel Sep 16, 2024
eecbdf7
Merge branch 'feature/FOUR-18078' into FOUR-18604
devmiguelangel Sep 16, 2024
dfb39d4
Update enterprise package
ryancooley Sep 16, 2024
7b3b940
Version 4.11.2-RC3
ryancooley Sep 16, 2024
c2415e6
Version 4.11.2
ryancooley Sep 17, 2024
0936002
tests: case controller ep tests
devmiguelangel Sep 16, 2024
20f8998
Merge pull request #7372 from ProcessMaker/FOUR-18604
caleeli Sep 17, 2024
840dd24
Set elementDestination to null for 'taskSource' case
eiresendez Sep 18, 2024
60831c9
Merge pull request #7382 from ProcessMaker/bug/FOUR-19210
ryancooley Sep 19, 2024
1763205
Version 4.11.3
ryancooley Sep 19, 2024
04ace5a
Merge branch 'next' into feature/FOUR-18078
devmiguelangel Sep 19, 2024
4e7ee52
feat: populate case started main flow
devmiguelangel Sep 19, 2024
8c47c45
feat: populate case participate main flow
devmiguelangel Sep 20, 2024
e955c99
Merge pull request #7400 from ProcessMaker/FOUR-18599
caleeli Sep 20, 2024
88a0f4a
test: cases main flow
devmiguelangel Sep 24, 2024
1031a8f
fix: handle null case started
devmiguelangel Sep 25, 2024
387cf7d
fix: update cases migrations, fix CaseController test
devmiguelangel Sep 25, 2024
ef64c8f
fix: handle null case number
devmiguelangel Sep 25, 2024
52f3ac5
Merge pull request #7412 from ProcessMaker/FOUR-18600-B
caleeli Sep 25, 2024
2fbba85
feat: populate sub processes
devmiguelangel Sep 25, 2024
fec23b4
Change PDF validation condition
danloa Sep 25, 2024
eeec1e6
feat: ref common functions
devmiguelangel Sep 26, 2024
3c93fd4
test: populate case sub processes
devmiguelangel Sep 26, 2024
143664c
test: fix CaseStartedSubProcessTest setup
devmiguelangel Sep 26, 2024
1858009
fix: implement Last-Modified header with If-Modified-Since validation…
eiresendez Sep 26, 2024
64f71a0
Allow admin users to reassign any user task
nolanpro Sep 27, 2024
a168f7e
Revert "fix: implement Last-Modified header with If-Modified-Since va…
eiresendez Sep 27, 2024
d8186ea
feat: implement cache-busting with version parameter to ensure screen…
eiresendez Sep 27, 2024
e0638fd
Cast users and groups to array of strings
caleeli Sep 27, 2024
01dd406
Fix call to missing method
nolanpro Sep 27, 2024
319f16f
Merge pull request #7417 from ProcessMaker/bugfix/FOUR-19373
ryancooley Sep 29, 2024
d51708c
Merge pull request #7427 from ProcessMaker/bugfix/FOUR-19110
ryancooley Sep 29, 2024
e70586d
Merge pull request #7432 from ProcessMaker/bugfix/FOUR-19390
ryancooley Sep 29, 2024
7c1ff50
Merge pull request #7428 from ProcessMaker/bugix/FOUR-19002
ryancooley Sep 29, 2024
2196ed7
Merge pull request #7430 from ProcessMaker/FOUR-19402
ryancooley Sep 29, 2024
e9211d0
Update JS dependencies
ryancooley Sep 29, 2024
7e30220
Update enterprise package
ryancooley Sep 29, 2024
5d95bd9
Version 4.11.4-RC1
ryancooley Sep 29, 2024
fd3e202
fix: add cr suggestions
devmiguelangel Sep 30, 2024
da20d16
Version 4.11.4
ryancooley Sep 30, 2024
c6848dc
Merge pull request #7421 from ProcessMaker/FOUR-18601
caleeli Oct 1, 2024
01c07e9
Merge branch 'next' into feature/FOUR-18078
devmiguelangel Oct 1, 2024
eaf113b
feat: add cases sync artisan command
devmiguelangel Sep 30, 2024
e6a3edc
feat: add custom exception logs
devmiguelangel Sep 27, 2024
e92b52a
feat: add case sync repo
devmiguelangel Oct 1, 2024
6df43f6
case repository refactor
devmiguelangel Oct 1, 2024
c9572a6
test: case exception tests
devmiguelangel Oct 1, 2024
7055d40
fix: case exception handling and logging
devmiguelangel Oct 2, 2024
98b2610
FOUR-18605 Count the cases and requests by user and status (EP)
julceslauhub Oct 2, 2024
d7ea383
fix: use status active constant
devmiguelangel Oct 2, 2024
dcebace
Merge pull request #7445 from ProcessMaker/FOUR-18602
caleeli Oct 2, 2024
d418885
Merge pull request #7449 from ProcessMaker/FOUR-18605
caleeli Oct 2, 2024
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
204 changes: 204 additions & 0 deletions ProcessMaker/Http/Controllers/Api/V1_1/CaseController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
<?php

namespace ProcessMaker\Http\Controllers\Api\V1_1;

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\Request;
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
{
/**
* Default fields used in the query select statement.
*/
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',
];

const DEFAULT_SORT_DIRECTION = 'asc';

/**
* 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] ?? self::DEFAULT_SORT_DIRECTION;

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, $search);
} else {
$q->orWhereFullText($field, $search . '*', ['mode' => 'boolean']);
}
}
});
}
}
}
35 changes: 35 additions & 0 deletions ProcessMaker/Http/Requests/GetAllCasesRequest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

namespace ProcessMaker\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;
use ProcessMaker\Rules\SortBy;

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', new SortBy],
'filterBy' => 'sometimes|array',
'search' => 'sometimes|string',
'pageSize' => 'sometimes|integer|min:1',
'page' => 'sometimes|integer|min:1',
];
}
}
37 changes: 37 additions & 0 deletions ProcessMaker/Http/Resources/V1_1/CaseResource.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

namespace ProcessMaker\Http\Resources\V1_1;

use ProcessMaker\Http\Resources\ApiResource;

class CaseResource extends ApiResource
{
/**
* Default fields that will be included in the response.
*/
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;
}
}
55 changes: 55 additions & 0 deletions ProcessMaker/Models/CaseStarted.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php

namespace ProcessMaker\Models;

use Database\Factories\CaseStartedFactory;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Casts\AsArrayObject;
use Illuminate\Database\Eloquent\Factories\Factory;
use ProcessMaker\Models\ProcessMakerModel;

class CaseStarted extends ProcessMakerModel
{
use HasFactory;

protected $table = 'cases_started';

protected $fillable = [
'case_number',
'user_id',
'case_title',
'case_title_formatted',
'case_status',
'processes',
'requests',
'request_tokens',
'tasks',
'participants',
'initiated_at',
'completed_at',
'keywords',
];

protected $casts = [
'processes' => AsArrayObject::class,
'requests' => AsArrayObject::class,
'request_tokens' => AsArrayObject::class,
'tasks' => AsArrayObject::class,
'participants' => AsArrayObject::class,
'initiated_at' => 'datetime',
'completed_at' => 'datetime',
];

protected static function newFactory(): Factory
{
return CaseStartedFactory::new();
}

/**
* Get the user that owns the case.
*/
public function user()
{
return $this->belongsTo(User::class);
}
}
25 changes: 25 additions & 0 deletions ProcessMaker/Rules/SortBy.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

namespace ProcessMaker\Rules;

use Closure;
use Illuminate\Contracts\Validation\ValidationRule;

class SortBy implements ValidationRule
{
/**
* Run the validation rule.
*
* @param \Closure(string): \Illuminate\Translation\PotentiallyTranslatedString $fail
*/
public function validate(string $attribute, mixed $value, Closure $fail): void
{
$items = explode(',', $value);

foreach ($items as $item) {
if (!preg_match('/^[a-zA-Z_]+:(asc|desc)$/', $item)) {
$fail("The $attribute must be a comma-separated list of field:asc|desc.");
}
}
}
}
Loading