Repository navigation
Expand file tree
/
Copy pathCasesController.php
More file actions
274 lines (249 loc) · 10.2 KB
/
Copy pathCasesController.php
File metadata and controls
274 lines (249 loc) · 10.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
<?php
namespace ProcessMaker\Http\Controllers;
use Illuminate\Support\Facades\Auth;
use ProcessMaker\Events\ModelerStarting;
use ProcessMaker\Events\ScreenBuilderStarting;
use ProcessMaker\Http\Controllers\Controller;
use ProcessMaker\Http\Controllers\Process\ModelerController;
use ProcessMaker\Managers\ModelerManager;
use ProcessMaker\Managers\ScreenBuilderManager;
use ProcessMaker\Models\ProcessRequest;
use ProcessMaker\Models\Screen;
use ProcessMaker\Package\PackageComments\PackageServiceProvider;
use ProcessMaker\ProcessTranslations\ScreenTranslation;
use ProcessMaker\Traits\ProcessMapTrait;
class CasesController extends Controller
{
use ProcessMapTrait;
/**
* Get the list of requests.
*
* @param string|null $type One of `all|in_progress|completed` (constrained by the route).
*
* @return \Illuminate\View\View|\Illuminate\Contracts\View
*/
public function index($type = null)
{
// The "All cases" tab exposes every case in the platform regardless
// of the user's relationship to it, so it is gated by the
// `view-all_cases` permission. The other tabs (My cases, In progress,
// Completed) are scoped to the user and need no gate.
// Admins bypass this check via Gate::before in AuthServiceProvider.
if ($type === 'all' && !Auth::user()->can('view-all_cases')) {
abort(403);
}
$manager = app(ScreenBuilderManager::class);
event(new ScreenBuilderStarting($manager, 'FORM'));
$currentUser = Auth::user()->only(['id', 'username', 'fullname', 'firstname', 'lastname', 'avatar']);
// This is a temporary API the engine team will provide the new
return view('cases.casesMain', compact('currentUser', 'manager'));
}
/**
* Cases Detail
*
* @param ProcessRequest $request
*
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function show($case_number)
{
// Load event ScreenBuilderStarting
$manager = app(ScreenBuilderManager::class);
event(new ScreenBuilderStarting($manager, 'FORM'));
// Load event ModelerStarting
$managerModeler = app(ModelerManager::class);
event(new ModelerStarting($managerModeler));
// "Initialload.js" file causes an issue related to SVG in the modeler
// The other scripts are not needed in the case detail
$scriptsDisabled = ['package-slideshow', 'package-process-optimization', 'package-ab-testing', 'package-testing', 'initialLoad'];
$managerModelerScripts = array_filter($managerModeler->getScriptWithParams(), function ($script) use ($scriptsDisabled) {
foreach ($scriptsDisabled as $enabledScript) {
if (strpos($script['src'], $enabledScript) !== false) {
return false;
}
}
return true;
});
// Get all the request related to this case number
$allRequests = ProcessRequest::where('case_number', $case_number)->get();
if ($allRequests->isEmpty()) {
abort(404);
}
$parentRequest = null;
$requestCount = $allRequests->count();
// Search the parent request parent_request_id and load $request
foreach ($allRequests as $request) {
if (is_null($request->parent_request_id)) {
$parentRequest = $request;
break;
}
}
$request = $parentRequest ?: $allRequests->first();
$request->participants;
$request->user;
// Load the data and key values
$request->summary = $request->summary();
// Load the screen configured in "Cancel Screen"
if ($request->status === 'CANCELED' && $request->process->cancel_screen_id) {
$request->summary_screen = $request->process->cancelScreen;
} else {
$request->summary_screen = $request->getSummaryScreen();
}
// Stage information
$stageInfo = $this->getStageInfoByStatus($request);
$currentStages = $stageInfo['currentStages'];
$progressStage = $stageInfo['progressStage'];
// Load the screen configured in "Request Detail Screen"
$request->request_detail_screen = Screen::find($request->process->request_detail_screen_id);
// The user canCancel if has the processPermission and the case has only one request
$canCancel = (Auth::user()->can('cancel', $request->processVersion) && $requestCount === 1);
// The user can see the comments
$canViewComments = (Auth::user()->hasPermissionsFor('comments')->count() > 0) || class_exists(PackageServiceProvider::class);
// The user is Manager from the main request
$isProcessManager = in_array(Auth::user()->id, $request->process?->manager_id ?? []);
// Check if the user has permission print for request
$canPrintScreens = $canOpenCase = $this->canUserCanOpenCase($allRequests);
if (!$canOpenCase && !$isProcessManager) {
$this->authorize('view', $request);
}
// Get the summary screen tranlations
$this->summaryScreenTranslation($request);
// Load the process map
$inflightData = $this->loadProcessMap($request);
$bpmn = $inflightData['bpmn'];
// Get all PM-Blocks
$modelerController = new ModelerController();
$pmBlockList = $modelerController->getPmBlockList();
// Is TCE Customization
$isTceCustomization = config('app.tce_customization_enable');
// Return the view
return view('cases.edit', compact(
'request',
'parentRequest',
'requestCount',
'canCancel',
'canViewComments',
'canPrintScreens',
'isProcessManager',
'manager',
'managerModelerScripts',
'bpmn',
'inflightData',
'pmBlockList',
'progressStage',
'currentStages',
'isTceCustomization',
));
}
/**
* The user can open the case
*
* @param \Illuminate\Database\Eloquent\Collection $allRequests
* @return bool
*/
private function canUserCanOpenCase($allRequests)
{
// Validate user is administrator
if (Auth::user()->is_administrator) {
return true;
}
// Any user with permissions Edit Request Data, Edit Task Data and view All Requests
if (Auth::user()->can('view-all_requests') && Auth::user()->can('edit-request_data') && Auth::user()->can('edit-task_data')) {
return true;
}
// Validate user is participant or requester in the request related to the case
foreach ($allRequests as $request) {
$participantIds = $request->participants->pluck('id')->toArray();
if (in_array(Auth::user()->id, $participantIds)) {
return true;
}
}
return false;
}
/**
* Translates the summary screen strings
* @param ProcessRequest $request
* @return void
*/
public function summaryScreenTranslation(ProcessRequest $request): void
{
if ($request->summary_screen) {
$screenTranslation = new ScreenTranslation();
if (get_class($request->summary_screen) === Screen::class) {
$request->summary_screen['config'] = $screenTranslation->applyTranslations($request->summary_screen->getLatestVersion());
} else {
$request->summary_screen['config'] = $screenTranslation->applyTranslations($request->summary_screen);
}
}
}
/**
* Get the current stages from a JSON string.
*
* This method decodes a JSON string representing stages into an associative array.
* If the input is null or not a valid JSON string, it returns an empty array.
*
* @param int|null $id The ID of the stage.
* @param string|null $name The name of the stage.
* @return array An associative array of stages if the JSON is valid;
* otherwise, an empty array.
*/
public static function formatCurrentStage(?int $id, ?string $name): array
{
// Initialize currentStages as an empty array
$currentStages = [];
// Check if $id is not null and $name is a valid string
if (!is_null($id) && is_string($name)) {
$currentStages = [
'stage_id' => $id,
'stage_name' => $name,
];
}
return $currentStages;
}
/**
* Get stage information based on request status
*
* @param ProcessRequest $request
* @return array
*/
private function getStageInfoByStatus(ProcessRequest $request): array
{
switch ($request->status) {
case 'COMPLETED':
return [
'currentStages' => [
'stage_name' => __('Completed'),
],
'progressStage' => 100.0, // 100% completed
];
case 'CANCELED':
return [
'currentStages' => [
'stage_name' => __('Canceled'),
],
'progressStage' => 0.0, // 0% progress when canceled
];
case 'ERROR':
return [
'currentStages' => [
'stage_name' => __('Error'),
],
'progressStage' => 0.0, // 0% progress when error
];
default:
$currentStages = $this->formatCurrentStage($request->last_stage_id, $request->last_stage_name);
$allStages = $this->getStagesByProcessId($request->process_id);
$progressStage = calculateProgressById($request->last_stage_id, $allStages);
if (empty($currentStages)) {
$currentStages = [
'stage_name' => __('In Progress'),
];
$progressStage = 50.0;
}
return [
'currentStages' => $currentStages,
'progressStage' => $progressStage,
];
}
}
}