Skip to content

Commit a2b812d

Browse files
authored
Merge pull request #8563 from ProcessMaker/epic/FOUR-26611
Smart Extract - HTIL
2 parents de87bff + 844a774 commit a2b812d

File tree

16 files changed

+286
-81
lines changed

16 files changed

+286
-81
lines changed

ProcessMaker/Http/Controllers/TaskController.php

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ public function edit(ProcessRequestToken $task, string $preview = '')
140140
$element = $task->getDefinition(true);
141141
$screenFields = $screenVersion ? $screenVersion->screenFilteredFields() : [];
142142
$taskDraftsEnabled = TaskDraft::draftsEnabled();
143-
143+
$isSmartExtractTask = $task->element_name === 'Manual Document Review';
144144
// Remove screen parent to reduce the size of the response
145145
$screen = $task->screen;
146146
$screen['parent'] = null;
@@ -190,6 +190,25 @@ public function edit(ProcessRequestToken $task, string $preview = '')
190190
'datetime_format',
191191
]);
192192
$userConfiguration = (new UserConfigurationController())->index();
193+
$hitlEnabled = config('smart-extract.hitl_enabled', false) && $isSmartExtractTask;
194+
195+
// Build the iframe source
196+
$iframeSrc = null;
197+
if ($hitlEnabled) {
198+
$dashboardUrl = config('smart-extract.dashboard_url');
199+
$requestData = $task->processRequest->data ?? [];
200+
201+
$documentToken = $requestData['documentToken'] ?? null;
202+
$fileId = $requestData['fileId'] ?? null;
203+
204+
if ($documentToken && $fileId && !empty($dashboardUrl)) {
205+
$queryParams = http_build_query([
206+
'documentToken' => $documentToken,
207+
'fileId' => $fileId,
208+
]);
209+
$iframeSrc = $dashboardUrl . '?' . $queryParams;
210+
}
211+
}
193212

194213
return view('tasks.edit', [
195214
'task' => $task,
@@ -204,6 +223,8 @@ public function edit(ProcessRequestToken $task, string $preview = '')
204223
'screenFields' => $screenFields,
205224
'taskDraftsEnabled' => $taskDraftsEnabled,
206225
'userConfiguration' => $userConfiguration,
226+
'hitlEnabled' => $hitlEnabled,
227+
'iframeSrc' => $iframeSrc,
207228
]);
208229
}
209230
}

ProcessMaker/Http/Middleware/HideServerHeaders.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ class HideServerHeaders
5555
/**
5656
* Handle an incoming request.
5757
*
58-
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
58+
* @param Closure(Request): (Response) $next
5959
*/
6060
public function handle(Request $request, Closure $next): Response
6161
{

ProcessMaker/Http/Middleware/IsManager.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ class IsManager
1313
/**
1414
* Handle an incoming request.
1515
*
16-
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
16+
* @param Closure(Request): (Response) $next
1717
*/
1818
public function handle(Request $request, Closure $next): Response
1919
{

ProcessMaker/Http/Resources/Task.php

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ public function toArray($request)
7474

7575
$this->addAssignableUsers($array, $include);
7676

77+
$this->mergeHitlCaseNumber($array);
78+
7779
return $array;
7880
}
7981

@@ -114,6 +116,28 @@ private function addAssignableUsers(&$array, $include)
114116
}
115117
}
116118

119+
private function mergeHitlCaseNumber(array &$array): void
120+
{
121+
if (!config('smart-extract.hitl_enabled')) {
122+
return;
123+
}
124+
125+
if (!empty(data_get($array, 'process_request.case_number'))) {
126+
return;
127+
}
128+
129+
$this->processRequest->loadMissing('parentRequest');
130+
$parentCaseNumber = $this->processRequest->parentRequest?->case_number;
131+
if (!$parentCaseNumber) {
132+
return;
133+
}
134+
135+
data_set($array, 'process_request.case_number', $parentCaseNumber);
136+
if (empty($array['case_number'])) {
137+
$array['case_number'] = $parentCaseNumber;
138+
}
139+
}
140+
117141
/**
118142
* Add the active users to the list of assigned users
119143
*
@@ -131,7 +155,7 @@ private function addActiveAssignedUsers(array $users, array $assignedUsers)
131155
->whereNotIn('status', Process::NOT_ASSIGNABLE_USER_STATUS)
132156
->whereIn('id', $chunk)
133157
->pluck('id')->toArray();
134-
$assignedUsers = array_merge($assignedUsers,$activeUsers);
158+
$assignedUsers = array_merge($assignedUsers, $activeUsers);
135159
}
136160

137161
return $assignedUsers;

ProcessMaker/Jobs/ErrorHandling.php

Lines changed: 52 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -211,10 +211,59 @@ public function setDefaultsFromDataSourceConfig(array $config)
211211
public static function convertResponseToException($result)
212212
{
213213
if ($result['status'] === 'error') {
214-
if (str_starts_with($result['message'], 'Command exceeded timeout of')) {
215-
throw new ScriptTimeoutException($result['message']);
214+
$rawMessage = $result['message'] ?? '';
215+
if (str_starts_with((string) $rawMessage, 'Command exceeded timeout of')) {
216+
throw new ScriptTimeoutException((string) $rawMessage);
217+
}
218+
219+
$message = self::extractScriptErrorMessage($result);
220+
221+
if (empty($message)) {
222+
$message = $rawMessage ?: 'Script execution failed with unknown error';
223+
}
224+
225+
throw new ScriptException($message);
226+
}
227+
}
228+
229+
/**
230+
* Extract a concise error message from the microservice response.
231+
*/
232+
private static function extractScriptErrorMessage(array $result): string
233+
{
234+
$candidates = [
235+
$result['output']['error'] ?? null,
236+
$result['output']['exception'] ?? null,
237+
$result['output']['stderr'] ?? null,
238+
$result['output']['stdout'] ?? null,
239+
$result['message'] ?? null,
240+
];
241+
242+
foreach ($candidates as $candidate) {
243+
if (is_string($candidate) || is_numeric($candidate)) {
244+
$short = self::shortenMessage((string) $candidate);
245+
if (!empty($short)) {
246+
return $short;
247+
}
216248
}
217-
throw new ScriptException(json_encode($result, JSON_PRETTY_PRINT));
218249
}
250+
251+
return '';
252+
}
253+
254+
/**
255+
* Keep only the first line of the error and limit its length to avoid noisy traces.
256+
*/
257+
private static function shortenMessage(string $message): string
258+
{
259+
$firstLine = strtok($message, "\n");
260+
$firstLine = $firstLine === false ? $message : $firstLine;
261+
$trimmed = trim($firstLine);
262+
263+
if (strlen($trimmed) > 400) {
264+
return substr($trimmed, 0, 400) . '';
265+
}
266+
267+
return $trimmed;
219268
}
220269
}

ProcessMaker/Traits/TaskControllerIndexMethods.php

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ private function excludeNonVisibleTasks($query, $request)
155155
{
156156
$nonSystem = filter_var($request->input('non_system'), FILTER_VALIDATE_BOOLEAN);
157157
$allTasks = filter_var($request->input('all_tasks'), FILTER_VALIDATE_BOOLEAN);
158+
$hitlEnabled = filter_var(config('smart-extract.hitl_enabled'), FILTER_VALIDATE_BOOLEAN);
158159
$query->when(!$allTasks, function ($query) {
159160
$query->where(function ($query) {
160161
$query->where('element_type', '=', 'task');
@@ -164,8 +165,20 @@ private function excludeNonVisibleTasks($query, $request)
164165
});
165166
});
166167
})
167-
->when($nonSystem, function ($query) {
168-
$query->nonSystem();
168+
->when($nonSystem, function ($query) use ($hitlEnabled) {
169+
if (!$hitlEnabled) {
170+
$query->nonSystem();
171+
172+
return;
173+
}
174+
175+
$query->where(function ($query) {
176+
$query->nonSystem();
177+
$query->orWhere(function ($query) {
178+
$query->where('element_type', '=', 'task');
179+
$query->where('element_name', '=', 'Manual Document Review');
180+
});
181+
});
169182
});
170183
}
171184

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,8 @@
173173
"package-rpa": "1.1.1",
174174
"package-savedsearch": "1.43.7",
175175
"package-slideshow": "1.4.3",
176-
"package-signature": "1.15.3",
176+
"package-smart-extract": "dev-develop",
177+
"package-signature": "1.15.2",
177178
"package-testing": "1.8.1",
178179
"package-translations": "2.14.5",
179180
"package-versions": "1.13.0",

resources/js/processes/modeler/components/inspector/TaskAssignment.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,10 +126,10 @@
126126
return this.$root.$children[0].process;
127127
},
128128
assignmentLockGetter () {
129-
return _.get(this.node, "assignmentLock");
129+
return _.get(this.node, "assignmentLock") || false;
130130
},
131131
allowReassignmentGetter () {
132-
return _.get(this.node, "allowReassignment");
132+
return _.get(this.node, "allowReassignment") || false;
133133
},
134134
assignedUserGetter () {
135135
let value = _.get(this.node, "assignedUsers");

resources/js/tasks/components/TasksList.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -496,7 +496,7 @@ export default {
496496
return `
497497
<a href="${this.openTask(record, 1)}"
498498
class="text-nowrap">
499-
# ${processRequest.case_number || record.case_number}
499+
# ${processRequest.case_number || record.case_number || ""}
500500
</a>`;
501501
},
502502
formatCaseTitle(processRequest, record) {

resources/views/layouts/layoutnext.blade.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ class="main flex-grow-1 h-100
133133
@endif
134134

135135
@yield('js')
136+
@stack('scripts')
136137

137138
@isset($addons)
138139
@foreach ($addons as $addon)

0 commit comments

Comments
 (0)