1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
ExternalEventTask.php
См. документацию.
1<?php
2
3namespace Bitrix\Bizproc\Task;
4
5use Bitrix\Bizproc\Error;
6use Bitrix\Bizproc\FieldType;
7use Bitrix\Bizproc\Result;
8use Bitrix\Bizproc\Task\Data\ExternalEventTask\ExternalEventTaskData;
9use Bitrix\Bizproc\Task\Data\ExternalEventTask\UsersByStatus;
10use Bitrix\Bizproc\Task\Data\TaskData;
11use Bitrix\Bizproc\Task\Dto\AddTaskDto;
12use Bitrix\Bizproc\Task\Dto\CompleteTaskDto;
13use Bitrix\Bizproc\Task\Dto\DeleteTaskDto;
14use Bitrix\Bizproc\Task\Dto\ExternalEventTask\AddCommandDto;
15use Bitrix\Bizproc\Task\Dto\ExternalEventTask\RemoveCommandDto;
16use Bitrix\Bizproc\Task\Dto\MarkCompletedTaskDto;
17use Bitrix\Bizproc\Task\Dto\TaskSettings;
18use Bitrix\Bizproc\Task\Dto\UpdateTaskDto;
19use Bitrix\Bizproc\Workflow\Entity\WorkflowUserTable;
20use Bitrix\Main\Localization\Loc;
21
22final class ExternalEventTask extends BaseTask
23{
27 protected TaskData $task;
28
29 private const BUTTON_NAME = 'execute';
30 private const FIELD_NAME = 'command';
31 private const USER_STATUS = \CBPTaskUserStatus::Ok;
32
33 public function __construct(TaskData $task, int $userId)
34 {
35 parent::__construct($task, $userId);
36
37 $this->task = ExternalEventTaskData::createFromArray($task->getData());
38 }
39
40 public static function getAssociatedActivity(): string
41 {
42 return 'HandleExternalEventActivity';
43 }
44
45 public static function addToTask(AddCommandDto $command): ?ExternalEventTask
46 {
47 $runtime = \CBPRuntime::getRuntime();
48 if (!$runtime->hasWorkflow($command->workflowId))
49 {
50 return null;
51 }
52
53 $currentTask = self::getCurrentTask($command->workflowId);
54 if ($currentTask)
55 {
56 $externalTask = new self(TaskData::createFromArray($currentTask), 0);
57
58 $users = $externalTask->getTaskUsersByStatus();
59 if ($users)
60 {
61 $intersect = array_intersect($users->completed, $command->userIds);
62 if ($intersect)
63 {
64 $externalTask->markTaskUnCompleted($intersect);
65 $externalTask->addUsersToCompletedUsersParameter($intersect);
66 }
67
68 $allUsers = array_merge($users->completed, $users->waiting);
69 $diff = array_diff($command->userIds, $allUsers);
70 if ($diff)
71 {
72 $newUsers = array_merge($allUsers, $command->userIds);
73 $externalTask->update(new UpdateTaskDto(users: $newUsers));
74 }
75 }
76
77 return $externalTask;
78 }
79
80 $workflow = $runtime->getWorkflow($command->workflowId);
81
82 return self::add(new AddTaskDto(
83 workflowId: $command->workflowId,
84 complexDocumentId: $workflow->getDocumentId(),
85 userIds: $command->userIds,
86 activityName: $command->id,
87 ));
88 }
89
90 public static function add(Dto\AddTaskDto $task): ?ExternalEventTask
91 {
92 return parent::add(new AddTaskDto(
93 workflowId: $task->workflowId,
94 complexDocumentId: $task->complexDocumentId,
95 userIds: $task->userIds,
96 activityName: $task->activityName,
97 settings: new TaskSettings(
98 name: Loc::getMessage('BIZPROC_LIB_TASK_EXTERNAL_EVENT_TASK_NAME') ?? '',
99 description: Loc::getMessage('BIZPROC_LIB_TASK_EXTERNAL_EVENT_TASK_DESCRIPTION') ?? '',
100 isInline: false,
101 delegationType: \CBPTaskDelegationType::ExactlyNone,
102 parameters: ['COMPLETED_USERS' => []],
103 ),
104 ));
105 }
106
107 public static function getCurrentTask(string $workflowId): bool|array
108 {
109 if (!$workflowId)
110 {
111 return false;
112 }
113
114 $taskService = self::getTaskService();
115
116 return $taskService::getList(
117 [],
118 [
119 'WORKFLOW_ID' => $workflowId,
120 'ACTIVITY' => self::getAssociatedActivity(),
121 'STATUS' => \CBPTaskStatus::Running,
122 ],
123 false,
124 false,
125 ['ID', 'WORKFLOW_ID', 'PARAMETERS']
126 )->fetch();
127 }
128
129 public function markCompleted(MarkCompletedTaskDto $markCompletedData): Result
130 {
131 if ($this->userId <= 0)
132 {
133 return Result::createError(new Error('negative userId', 'negative userId'));
134 }
135
136 if (!$this->getEvents())
137 {
138 $this->markTaskCompleted([$this->userId]);
139 }
140 else
141 {
142 $this->addUsersToCompletedUsersParameter([$this->userId]);
143 }
144
145 return Result::createOk();
146 }
147
148 private function addUsersToCompletedUsersParameter(array $userIds): void
149 {
150 $completedUsers = $this->task->getCompletedUsersParameter();
151 if ($completedUsers !== null && $userIds)
152 {
153 $isAdded = false;
154 foreach ($userIds as $userId)
155 {
156 if (!in_array($userId, $completedUsers, true))
157 {
158 $isAdded = true;
159 $completedUsers[] = $userId;
160 }
161 }
162
163 if ($isAdded)
164 {
165 $this->task->setCompletedUsersParameter($completedUsers);
166 $this->update(new UpdateTaskDto(parameters: $this->task->getParameters()));
167 }
168 }
169 }
170
171 public function removeFromTask(RemoveCommandDto $command): Result
172 {
173 $users = $this->getTaskUsersByStatus($command->userIds);
174 if (!$users) // no users, no task
175 {
176 return Result::createOk();
177 }
178
179 if (!$users->completed && !$users->waiting && !$users->markCompleted)
180 {
181 $this->delete(new DeleteTaskDto());
182
183 return Result::createOk();
184 }
185
186 if ($users->markCompleted)
187 {
188 $this->markTaskCompleted($users->markCompleted);
189 }
190
191 if (!$users->waiting)
192 {
193 $this->complete(new CompleteTaskDto());
194
195 return Result::createOk();
196 }
197
198 $actualUsers = array_merge($users->completed, $users->waiting, $users->markCompleted);
199 $this->update(new UpdateTaskDto(users: $actualUsers));
200
201 return Result::createOk();
202 }
203
204 public function complete(CompleteTaskDto $completeData): Result
205 {
206 return parent::complete(new CompleteTaskDto(status: \CBPTaskStatus::CompleteOk));
207 }
208
209 private function getTaskUsersByStatus(array $removeUsers = []): ?UsersByStatus
210 {
211 $taskService = self::getTaskService();
212
213 $taskUsers = $taskService::getTaskUsers($this->getId())[$this->getId()] ?? [];
214 if (!$taskUsers)
215 {
216 return null;
217 }
218
219 $state = $this->getWorkflowState();
220 if (!$state)
221 {
222 return null;
223 }
224
225 return new UsersByStatus($taskUsers, $state, $removeUsers, $this->task->getCompletedUsersParameter());
226 }
227
228 private function markTaskCompleted(array $userIds): void
229 {
230 $taskService = self::getTaskService();
231 foreach ($userIds as $userId)
232 {
233 $taskService->markCompleted($this->getId(), $userId, self::USER_STATUS);
234 }
235 }
236
237 private function markTaskUnCompleted(array $userIds): void
238 {
239 $taskService = self::getTaskService();
240 $taskService->markUnCompleted($this->getId(), $userIds);
241 }
242
243 public function getTaskControls(): array
244 {
245 $field = array_merge(
246 $this->getAllowableCommandFieldProperty(),
247 [
248 'Id' => self::FIELD_NAME,
249 'Name' => Loc::getMessage('BIZPROC_LIB_TASK_EXTERNAL_EVENT_TASK_FIELD_NAME') ?? '',
250 ]
251 );
252
253 return [
254 'BUTTONS' => [
255 [
256 'TYPE' => 'submit',
257 'TARGET_USER_STATUS' => self::USER_STATUS,
258 'NAME' => self::BUTTON_NAME,
259 'VALUE' => 'Y',
260 'TEXT' => Loc::getMessage('BIZPROC_LIB_TASK_EXTERNAL_EVENT_TASK_SEND_BUTTON_NAME') ?? '',
261 ],
262 ],
263 'FIELDS' => [$field],
264 ];
265 }
266
267 private function getAllowableCommandFieldProperty(): array
268 {
269 $options = ['' => Loc::getMessage('BIZPROC_LIB_TASK_EXTERNAL_EVENT_TASK_DEFAULT_OPTION_NAME')];
270
271 $events = $this->getEvents();
272 if ($events)
273 {
274 $options = array_merge($options, $events);
275 }
276
277 return [
278 'Type' => FieldType::SELECT,
279 'Required' => true,
280 'Options' => $options,
281 'Settings' => ['ShowEmptyValue' => false],
282 ];
283 }
284
286 {
287 $fields = $request['fields'] ?? $request;
288
289 $command = trim($fields[self::FIELD_NAME] ?? '');
290 if (empty($command))
291 {
292 if (
293 !$this->getEvents()
294 && $this->removeFromTask(new RemoveCommandDto(id: $command, userIds: [$this->userId]))->isSuccess()
295 )
296 {
297 WorkflowUserTable::syncOnTaskUpdated($this->task->workflowId);
298 }
299
300 return Result::createOk();
301 }
302
303 if (!$this->validateCommand($command))
304 {
305 return Result::createError(new Error(
306 Loc::getMessage('BIZPROC_LIB_TASK_EXTERNAL_EVENT_TASK_ERROR_UNKNOWN_COMMAND') ?? '',
307 'unknown_command'
308 ));
309 }
310
311 $eventParameters = ['Groups' => $this->getUserGroups($this->userId), 'User' => $this->userId];
312
313 \CBPRuntime::sendExternalEvent($this->task->workflowId, $command, $eventParameters);
314
315 return Result::createOk();
316 }
317
318 private function validateCommand(string $command): bool
319 {
320 return array_key_exists($command, $this->getEvents());
321 }
322
323 private function getEvents(): array
324 {
325 if ($this->userId > 0)
326 {
327 $state = $this->getWorkflowState();
328 if ($state)
329 {
330 return $this->getAllowableEventsFromState($this->userId, $state);
331 }
332 }
333
334 return [];
335 }
336
337 private function getWorkflowState(): ?array
338 {
339 $workflowId = $this->task->workflowId;
340 $documentId = $this->task->getDocumentId();
341
342 if ($workflowId !== '' && $documentId)
343 {
344 $state = \CBPDocument::getDocumentState($documentId, $workflowId)[$workflowId] ?? null;
345 if ($state)
346 {
347 return $state;
348 }
349 }
350
351 return null;
352 }
353
354 private function getAllowableEventsFromState(int $userId, array $state): array
355 {
356 $allowableEvents = \CBPDocument::getAllowableEvents($userId, $this->getUserGroups($userId), $state, true);
357 $events = [];
358 foreach ($allowableEvents as $event)
359 {
360 $events[$event['NAME']] = $event['TITLE'];
361 }
362
363 return $events;
364 }
365
366 private function getUserGroups(int $userId): array
367 {
368 $currentUser = \Bitrix\Main\Engine\CurrentUser::get();
369
370 return (int)$currentUser->getId() === $userId ? $currentUser->getUserGroups() : \CUser::GetUserGroup($userId);
371 }
372}
if(!Loader::includeModule('catalog')) if(!AccessController::getCurrent() ->check(ActionDictionary::ACTION_PRICE_EDIT)) if(!check_bitrix_sessid()) $request
Определения catalog_reindex.php:36
if(!is_object($USER)||! $USER->IsAuthorized()) $userId
Определения check_mail.php:18
const SELECT
Определения fieldtype.php:47
update(UpdateTaskDto $updateData)
Определения BaseTask.php:66
int $userId
Определения BaseTask.php:16
static getTaskService()
Определения BaseTask.php:119
static createFromArray(array $data)
Определения TaskData.php:19
static addToTask(AddCommandDto $command)
Определения ExternalEventTask.php:45
static add(Dto\AddTaskDto $task)
Определения ExternalEventTask.php:90
postTaskForm(array $request)
Определения ExternalEventTask.php:285
complete(CompleteTaskDto $completeData)
Определения ExternalEventTask.php:204
static getCurrentTask(string $workflowId)
Определения ExternalEventTask.php:107
removeFromTask(RemoveCommandDto $command)
Определения ExternalEventTask.php:171
__construct(TaskData $task, int $userId)
Определения ExternalEventTask.php:33
markCompleted(MarkCompletedTaskDto $markCompletedData)
Определения ExternalEventTask.php:129
Определения error.php:15
const ExactlyNone
Определения constants.php:326
const CompleteOk
Определения constants.php:261
const Running
Определения constants.php:258
const Ok
Определения constants.php:276
$options
Определения commerceml2.php:49
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
Определения file_new.php:804
$event
Определения prolog_after.php:141
$fields
Определения yandex_run.php:501