Skip to content

Commit 80bb15d

Browse files
committed
Merge branch 'develop' into feature/1346
# Conflicts: # resources/views/processes/edit.blade.php
2 parents 1b75a62 + 9db2820 commit 80bb15d

23 files changed

Lines changed: 1893 additions & 1185 deletions

File tree

‎ProcessMaker/Http/Controllers/Admin/GroupController.php‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,8 @@ public function index()
2828
public function edit(Group $group)
2929
{
3030
$permissionNames = $group->permissions()->pluck('name')->toArray();
31-
$users = User::where('status', 'ACTIVE')->get();
3231
$all_permissions = Permission::all();
33-
return view('admin.groups.edit', compact('group', 'users', 'permissionNames', 'all_permissions'));
32+
return view('admin.groups.edit', compact('group', 'permissionNames', 'all_permissions'));
3433
}
3534

3635
public function show(Group $group)

‎ProcessMaker/Http/Controllers/Api/GroupMemberController.php‎

Lines changed: 170 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ class GroupMemberController extends Controller
2222
* @var array
2323
*/
2424
public $doNotSanitize = [
25-
//
25+
//
2626
];
2727

2828
/**
@@ -196,4 +196,173 @@ public function destroy(GroupMember $group_member)
196196
$group_member->delete();
197197
return response([], 204);
198198
}
199+
200+
/**
201+
* Display a listing of groups available
202+
*
203+
* @param \Illuminate\Http\Request $request
204+
* @return ApiCollection
205+
*
206+
* @OA\Get(
207+
* path="/group_members_available",
208+
* summary="Returns all groups available for a given member",
209+
* operationId="getGroupMembersAvailable",
210+
* tags={"Group Members"},
211+
* @OA\Parameter(
212+
* description="ID of group_members to return",
213+
* in="path",
214+
* name="member_id",
215+
* required=true,
216+
* @OA\Schema(
217+
* type="string",
218+
* )
219+
* ),
220+
* @OA\Parameter(
221+
* description="type of group_members to return",
222+
* in="path",
223+
* name="member_type",
224+
* required=true,
225+
* @OA\Schema(
226+
* type="string",
227+
* )
228+
* ),
229+
* @OA\Parameter(ref="#/components/parameters/filter"),
230+
* @OA\Parameter(ref="#/components/parameters/order_by"),
231+
* @OA\Parameter(ref="#/components/parameters/order_direction"),
232+
* @OA\Parameter(ref="#/components/parameters/per_page"),
233+
*
234+
* @OA\Response(
235+
* response=200,
236+
* description="list of groups available to be assigned as member",
237+
* @OA\JsonContent(
238+
* type="object",
239+
* @OA\Property(
240+
* property="data",
241+
* type="array",
242+
* @OA\Items(ref="#/components/schemas/group_members"),
243+
* ),
244+
* @OA\Property(
245+
* property="meta",
246+
* type="object",
247+
* allOf={@OA\Schema(ref="#/components/schemas/metadata")},
248+
* ),
249+
* ),
250+
* ),
251+
* )
252+
*/
253+
public function groupsAvailable(Request $request)
254+
{
255+
$member_id = $request->input('member_id', null);
256+
$member_type = $request->input('member_type', null);
257+
258+
$members = [];
259+
if ($member_id && $member_type) {
260+
//Load groups already assigned.
261+
$data = GroupMember::where('member_type', $member_type)
262+
->where('member_id', $member_id)
263+
->get();
264+
foreach ($data as $item) {
265+
array_push($members, $item->group_id);
266+
}
267+
}
268+
269+
$query = Group::where('status', 'ACTIVE')
270+
->whereNotIn('id', $members);
271+
272+
$filter = $request->input('filter', '');
273+
if (!empty($filter)) {
274+
//filter by name group
275+
$filter = '%' . $filter . '%';
276+
$query->where(function ($query) use ($filter) {
277+
$query->Where('name', 'like', $filter);
278+
});
279+
}
280+
$response =
281+
$query->orderBy(
282+
$request->input('order_by', 'name'),
283+
$request->input('order_direction', 'ASC')
284+
)->paginate($request->input('per_page', 10));
285+
286+
return new ApiCollection($response);
287+
}
288+
289+
/**
290+
* Display a listing of users available
291+
*
292+
* @param \Illuminate\Http\Request $request
293+
* @return ApiCollection
294+
*
295+
* @OA\Get(
296+
* path="/user_members_available",
297+
* summary="Returns all users available for a given member",
298+
* operationId="getUserMembersAvailable",
299+
* tags={"Group Members"},
300+
* @OA\Parameter(
301+
* description="ID of group to return",
302+
* in="path",
303+
* name="group_id",
304+
* required=true,
305+
* @OA\Schema(
306+
* type="string",
307+
* )
308+
* ),
309+
* @OA\Parameter(ref="#/components/parameters/filter"),
310+
* @OA\Parameter(ref="#/components/parameters/order_by"),
311+
* @OA\Parameter(ref="#/components/parameters/order_direction"),
312+
* @OA\Parameter(ref="#/components/parameters/per_page"),
313+
*
314+
* @OA\Response(
315+
* response=200,
316+
* description="list of users available to be assigned as member",
317+
* @OA\JsonContent(
318+
* type="object",
319+
* @OA\Property(
320+
* property="data",
321+
* type="array",
322+
* @OA\Items(ref="#/components/schemas/group_members"),
323+
* ),
324+
* @OA\Property(
325+
* property="meta",
326+
* type="object",
327+
* allOf={@OA\Schema(ref="#/components/schemas/metadata")},
328+
* ),
329+
* ),
330+
* ),
331+
* )
332+
*/
333+
public function usersAvailable(Request $request)
334+
{
335+
$groupId = $request->input('group_id', null);
336+
337+
$members = [];
338+
if ($groupId) {
339+
//Load user members already assigned.
340+
$data = GroupMember::where('member_type', User::class)
341+
->where('group_id', $groupId)
342+
->get();
343+
foreach ($data as $item) {
344+
array_push($members, $item->member_id);
345+
}
346+
}
347+
348+
$query = User::where('status', 'ACTIVE')
349+
->whereNotIn('id', $members);
350+
351+
$filter = $request->input('filter', '');
352+
if (!empty($filter)) {
353+
//filter by name group
354+
$filter = '%' . $filter . '%';
355+
$query->where(function ($query) use ($filter) {
356+
$query->Where('firstname', 'like', $filter)
357+
->orWhere('lastname', 'like', $filter);
358+
});
359+
}
360+
$response =
361+
$query->orderBy(
362+
$request->input('order_by', 'firstname'),
363+
$request->input('order_direction', 'ASC')
364+
)->paginate($request->input('per_page', 10));
365+
366+
return new ApiCollection($response);
367+
}
199368
}

‎ProcessMaker/Http/Controllers/Api/ProcessController.php‎

Lines changed: 5 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -243,25 +243,6 @@ public function update(Request $request, Process $process)
243243
);
244244
$process->versions()->create($original_attributes);
245245

246-
//If we are specifying start assignments...
247-
if ($request->has('start_request')) {
248-
//Adding method to users array
249-
$startUsers = [];
250-
foreach ($request->input('start_request')['users'] as $item) {
251-
$startUsers[$item] = ['method' => 'START'];
252-
}
253-
254-
//Adding method to groups array
255-
$startGroups = [];
256-
foreach ($request->input('start_request')['groups'] as $item) {
257-
$startGroups[$item] = ['method' => 'START'];
258-
}
259-
260-
//Syncing users and groups that can start this process
261-
$process->usersCanStart()->sync($startUsers, ['method' => 'START']);
262-
$process->groupsCanStart()->sync($startGroups, ['method' => 'START']);
263-
}
264-
265246
//If we are specifying cancel assignments...
266247
if ($request->has('cancel_request')) {
267248
//Adding method to users array
@@ -446,9 +427,11 @@ public function startProcesses(Request $request)
446427
->orderBy(...$orderBy)
447428
->get();
448429

449-
$processes = $processes->filter(function($process) {
450-
return Auth::user()->can('start', $process);
451-
});
430+
foreach($processes as $key => $process) {
431+
if (count($process->events) === 0) {
432+
$processes->forget($key);
433+
}
434+
};
452435

453436
return new ApiCollection($processes);
454437
}

‎ProcessMaker/Http/Resources/Process.php‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ public function toArray($request)
2121
$array['category'] = new ProcessCategory($this->category);
2222
}
2323
if (in_array('events', $include)) {
24-
$array['events'] = $this->getStartEvents();
24+
$array['events'] = $this->getStartEvents(true);
2525
}
2626
return $array;
2727
}

‎ProcessMaker/Models/Process.php‎

Lines changed: 54 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use Illuminate\Database\Eloquent\Model;
66
use Illuminate\Database\Eloquent\SoftDeletes;
7+
use Illuminate\Support\Facades\Auth;
78
use Illuminate\Support\Facades\Storage;
89
use Illuminate\Validation\Rule;
910
use ProcessMaker\AssignmentRules\PreviousTaskAssignee;
@@ -14,6 +15,7 @@
1415
use ProcessMaker\Nayra\Contracts\Bpmn\ServiceTaskInterface;
1516
use ProcessMaker\Nayra\Contracts\Storage\BpmnDocumentInterface;
1617
use ProcessMaker\Nayra\Storage\BpmnDocument;
18+
use ProcessMaker\Traits\ProcessStartEventAssignmentsTrait;
1719
use ProcessMaker\Traits\ProcessTaskAssignmentsTrait;
1820
use ProcessMaker\Traits\SerializeToIso8601;
1921
use Spatie\MediaLibrary\HasMedia\HasMedia;
@@ -54,6 +56,7 @@ class Process extends Model implements HasMedia
5456
use SerializeToIso8601;
5557
use SoftDeletes;
5658
use ProcessTaskAssignmentsTrait;
59+
use ProcessStartEventAssignmentsTrait;
5760

5861
/**
5962
* The attributes that aren't mass assignable.
@@ -244,19 +247,27 @@ public function user()
244247
/**
245248
* Get the users who can start this process
246249
*
250+
* @param string|null $node If null get START from any node
247251
*/
248-
public function usersCanStart()
252+
public function usersCanStart($node = null)
249253
{
250-
return $this->morphedByMany('ProcessMaker\Models\User', 'processable')->wherePivot('method', 'START');
254+
$relationship = $this->morphedByMany('ProcessMaker\Models\User', 'processable')
255+
->wherePivot('method', 'START');
256+
$relationship = $node === null ? $relationship : $relationship->wherePivot('node', $node);
257+
return $relationship;
251258
}
252259

253260
/**
254261
* Get the groups who can start this process
255262
*
263+
* @param string|null $node If null get START from any node
256264
*/
257-
public function groupsCanStart()
265+
public function groupsCanStart($node = null)
258266
{
259-
return $this->morphedByMany('ProcessMaker\Models\Group', 'processable')->wherePivot('method', 'START');
267+
$relationship = $this->morphedByMany('ProcessMaker\Models\Group', 'processable')
268+
->wherePivot('method', 'START');
269+
$relationship = $node === null ? $relationship : $relationship->wherePivot('node', $node);
270+
return $relationship;
260271
}
261272

262273
/**
@@ -580,17 +591,54 @@ private function getConsolidatedUsers($group_id, array &$users)
580591
*
581592
* @return array
582593
*/
583-
public function getStartEvents()
594+
public function getStartEvents($filterWithPermissions = false)
584595
{
596+
$user = Auth::user();
597+
$isAdmin = $user ? $user->is_administrator : false;
598+
$permissions = $filterWithPermissions && !$isAdmin ? $this->getStartEventPermissions() : [];
599+
$nofilter = $isAdmin || !$filterWithPermissions;
585600
$definitions = $this->getDefinitions();
586601
$response = [];
587602
$startEvents = $definitions->getElementsByTagNameNS(BpmnDocument::BPMN_MODEL, 'startEvent');
588603
foreach ($startEvents as $startEvent) {
589-
$response[] = $startEvent->getBpmnElementInstance()->getProperties();
604+
if ($nofilter || ($user && isset($permissions[$startEvent->getAttribute('id')]) && in_array($user->id, $permissions[$startEvent->getAttribute('id')]))) {
605+
$response[] = $startEvent->getBpmnElementInstance()->getProperties();
606+
}
590607
}
591608
return $response;
592609
}
593610

611+
/**
612+
* Get permissions by start event.
613+
*
614+
* @return array
615+
*/
616+
private function getStartEventPermissions()
617+
{
618+
$permissions = [];
619+
foreach($this->usersCanStart()->withPivot('node')->get() as $user) {
620+
$permissions[$user->pivot->node][$user->id] = $user->id;
621+
}
622+
foreach($this->groupsCanStart()->withPivot('node')->get() as $group) {
623+
$users = [];
624+
$this->getConsolidatedUsers($group->id, $users);
625+
isset($permissions[$group->pivot->node]) ?: $permissions[$group->pivot->node] = [];
626+
$permissions[$group->pivot->node] = $permissions[$group->pivot->node] + $users;
627+
}
628+
return $permissions;
629+
}
630+
631+
/**
632+
* Update BPMN content and reset bpmnDefinitions
633+
*
634+
* @param string $value
635+
*/
636+
public function setBpmnAttribute($value)
637+
{
638+
$this->bpmnDefinitions = null;
639+
$this->attributes['bpmn'] = $value;
640+
}
641+
594642
/**
595643
* Process events relationship.
596644
*

‎ProcessMaker/Models/ProcessEvents.php‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public function addEagerConstraints(array $models)
4444
*/
4545
public function getResults()
4646
{
47-
return $this->parent->getStartEvents();
47+
return $this->parent->getStartEvents(true);
4848
}
4949

5050
/**
@@ -70,7 +70,7 @@ public function initRelation(array $models, $relation)
7070
public function match(array $models, Collection $results, $relation)
7171
{
7272
foreach ($models as $model) {
73-
$events = collect($model->getStartEvents());
73+
$events = collect($model->getStartEvents(true));
7474
$model->setRelation($relation, $events);
7575
}
7676
return $models;

‎ProcessMaker/Policies/ProcessPolicy.php‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use ProcessMaker\Models\User;
66
use ProcessMaker\Models\Process;
77
use Illuminate\Auth\Access\HandlesAuthorization;
8+
use Illuminate\Http\Request;
89

910
class ProcessPolicy
1011
{
@@ -35,11 +36,11 @@ public function start(User $user, Process $process)
3536
{
3637
$groupIds = $user->groups->pluck('id');
3738

38-
if ($process->groupsCanStart->whereIn('id', $groupIds)->count()) {
39+
if ($process->groupsCanStart(request()->query('event'))->whereIn('id', $groupIds)->count()) {
3940
return true;
4041
}
4142

42-
if ($process->usersCanStart->where('id', $user->id)->count()) {
43+
if ($process->usersCanStart(request()->query('event'))->where('id', $user->id)->count()) {
4344
return true;
4445
}
4546

0 commit comments

Comments
 (0)