Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
workflowusertable.php
1<?php
2
4
12
30{
31 public const WORKFLOW_STATUS_ACTIVE = 0;
32 public const WORKFLOW_STATUS_COMPLETED = 1;
33
34 public const TASK_STATUS_NONE = 0;
35 public const TASK_STATUS_COMPLETED = 1;
36 public const TASK_STATUS_ACTIVE = 2;
37
38
39 public static function getTableName()
40 {
41 return 'b_bp_workflow_user';
42 }
43
44 public static function getMap()
45 {
46 return [
47 (new IntegerField('USER_ID'))
48 ->configurePrimary()
49 ,
50 (new StringField('WORKFLOW_ID'))
51 ->configureSize(32)
52 ->configurePrimary()
53 ,
54 (new IntegerField('IS_AUTHOR'))
55 ->configureNullable(false)
56 ,
57 (new IntegerField('WORKFLOW_STATUS'))
58 ->configureNullable(false)
59 ,
60 (new IntegerField('TASK_STATUS'))
61 ->configureNullable(false)
62 ,
63 (new DatetimeField('MODIFIED'))
64 ->configureNullable(false)
65 ,
66 ];
67 }
68
69 public static function syncOnWorkflowUpdated(\CBPWorkflow $workflow, int $status): void
70 {
71 $workflowId = $workflow->getInstanceId();
72 $users = static::getTaskUsers($workflowId);
73 $hasUsers = !empty($users) || static::hasStoredUsers($workflowId);
74
75 if (!$hasUsers && !static::isLiveFeedProcess($workflow->getDocumentId()))
76 {
77 return;
78 }
79
80 $authorId = $workflow->getStartedBy();
81 $workflowStatus = \CBPWorkflowStatus::isFinished($status)
82 ? static::WORKFLOW_STATUS_COMPLETED
83 : static::WORKFLOW_STATUS_ACTIVE
84 ;
85
86 if ($authorId)
87 {
88 $users[$authorId]['IS_AUTHOR'] ??= 1;
89 }
90
91 foreach ($users as $id => $user)
92 {
93 $users[$id]['WORKFLOW_STATUS'] = $workflowStatus;
94 }
95
96 static::syncUsers($workflowId, $users);
97 }
98
99 private static function isLiveFeedProcess(array $documentId): bool
100 {
101 return ($documentId[0] ?? '') === 'lists' && ($documentId[1] ?? '') === 'BizprocDocument';
102 }
103
104 public static function syncOnTaskUpdated(string $workflowId): array
105 {
106 $users = static::getTaskUsers($workflowId);
107
108 return static::syncUsers($workflowId, $users);
109 }
110
111 private static function getTaskUsers(string $workflowId): array
112 {
113 $taskUsers = \CBPTaskService::getWorkflowUsers($workflowId);
114 $users = [];
115
116 foreach ($taskUsers as $id => $taskStatus)
117 {
118 $users[$id] = [
119 'TASK_STATUS' => $taskStatus === \CBPTaskUserStatus::Waiting
120 ? static::TASK_STATUS_ACTIVE
121 : static::TASK_STATUS_COMPLETED
122 ,
123 ];
124 }
125
126 $authorId = static::getAuthorId($workflowId);
127 if ($authorId && !isset($users[$authorId]))
128 {
129 $users[$authorId] = [
130 'TASK_STATUS' => static::TASK_STATUS_NONE,
131 ];
132 }
133
134 return $users;
135 }
136
137 private static function syncUsers(string $workflowId, array $users): array
138 {
139 $stored = static::getStoredUsers($workflowId);
140
141 $toDelete = array_diff_key($stored, $users);
142 $toAdd = array_diff_key($users, $stored);
143 $toUpdate = array_intersect_key($users, $stored);
144
145 self::deleteOnSync($workflowId, $toDelete);
146 self::addOnSync($workflowId, $toAdd);
147 self::updateOnSync($workflowId, $toUpdate);
148
149 return [array_keys($toAdd), array_keys($toUpdate), array_keys($toDelete)];
150 }
151
152 private static function getAuthorId(string $workflowId): int
153 {
154 $result = static::getList([
155 'select' => ['USER_ID'],
156 'filter' => [
157 '=WORKFLOW_ID' => $workflowId,
158 '=IS_AUTHOR' => 1,
159 ],
160 ])->fetch();
161
162 return (int)($result['USER_ID'] ?? 0);
163 }
164
165 private static function deleteOnSync(string $workflowId, array $toDelete): void
166 {
167 if (!$toDelete)
168 {
169 return;
170 }
171
172 $deleted = array_keys($toDelete);
173 foreach ($deleted as $userId)
174 {
175 static::delete([
176 'USER_ID' => $userId,
177 'WORKFLOW_ID' => $workflowId,
178 ]);
179 }
180
181 WorkflowPush::pushDeleted($workflowId, $deleted);
182 }
183
184 private static function addOnSync(string $workflowId, array $toAdd): void
185 {
186 if (!$toAdd)
187 {
188 return;
189 }
190
191 foreach ($toAdd as $userId => $user)
192 {
193 static::add([
194 'USER_ID' => $userId,
195 'WORKFLOW_ID' => $workflowId,
196 'IS_AUTHOR' => $user['IS_AUTHOR'] ?? 0,
197 'WORKFLOW_STATUS' => $user['WORKFLOW_STATUS'] ?? static::WORKFLOW_STATUS_ACTIVE,
198 'TASK_STATUS' => $user['TASK_STATUS'] ?? static::TASK_STATUS_NONE,
199 'MODIFIED' => new DateTime(),
200 ]);
201 }
202
203 WorkflowPush::pushAdded($workflowId, array_keys($toAdd));
204 }
205
206 private static function updateOnSync(string $workflowId, array $toUpdate): void
207 {
208 if (!$toUpdate)
209 {
210 return;
211 }
212
213 $modified = new DateTime();
214
215 foreach ($toUpdate as $userId => $user)
216 {
217 $user['MODIFIED'] = $modified;
218
219 static::update(
220 [
221 'USER_ID' => $userId,
222 'WORKFLOW_ID' => $workflowId,
223 ],
224 $user
225 );
226 }
227
228 WorkflowPush::pushUpdated($workflowId, array_keys($toUpdate));
229 }
230
231 private static function getStoredUsers(string $workflowId): array
232 {
233 $result = static::getList([
234 'select' => ['USER_ID', 'IS_AUTHOR', 'WORKFLOW_STATUS', 'TASK_STATUS'],
235 'filter' => ['=WORKFLOW_ID' => $workflowId],
236 ]);
237
238 $users = [];
239
240 while ($row = $result->fetch())
241 {
242 $users[(int)$row['USER_ID']] = [
243 'IS_AUTHOR' => (int)$row['IS_AUTHOR'],
244 'WORKFLOW_STATUS' => (int)$row['WORKFLOW_STATUS'],
245 'TASK_STATUS' => (int)$row['TASK_STATUS'],
246 ];
247 }
248
249 return $users;
250 }
251
252 private static function hasStoredUsers(string $workflowId): bool
253 {
254 return static::getCount(['=WORKFLOW_ID' => $workflowId]) > 0;
255 }
256
257 public static function deleteByWorkflow(string $workflowId): array
258 {
259 $stored = static::getStoredUsers($workflowId);
260 self::deleteOnSync($workflowId, $stored);
261
262 return array_keys($stored);
263 }
264
265 public static function convertUserProcesses(int $userId): void
266 {
267 $connection = Application::getConnection();
268
269 if ($connection->getType() !== 'mysql')
270 {
271 return;
272 }
273
274 //truncate first
275 $connection->query(
276 <<<SQL
277 DELETE FROM b_bp_workflow_user WHERE USER_ID = {$userId}
278 SQL
279 );
280
281 // convert user "Live Feed" workflows (lists + BizprocDocument)
282 $connection->query(
283 <<<SQL
284 INSERT INTO b_bp_workflow_user
285 (USER_ID, WORKFLOW_ID, IS_AUTHOR, WORKFLOW_STATUS, MODIFIED)
286 (
287 select wt.STARTED_BY, wt.ID, 1, case when wi.id is null then 1 else 0 end, wt.MODIFIED
288 from b_bp_workflow_state wt
289 left join b_bp_workflow_instance wi on (wt.id = wi.id)
290 where wt.STARTED_BY = {$userId} and wt.MODULE_ID = 'lists' and wt.ENTITY = 'BizprocDocument'
291 )
292 ON DUPLICATE KEY UPDATE IS_AUTHOR = 1, WORKFLOW_STATUS = VALUES(WORKFLOW_STATUS), MODIFIED = VALUES(MODIFIED)
293 SQL
294 );
295
296 // convert my active tasks
297 $connection->query(
298 <<<SQL
299 INSERT INTO b_bp_workflow_user
300 (USER_ID, WORKFLOW_ID, IS_AUTHOR, WORKFLOW_STATUS, TASK_STATUS, MODIFIED)
301 (
302 select tu.USER_ID, t.WORKFLOW_ID, 0, 0, 2,
303 case when tu.DATE_UPDATE is null then now() else tu.DATE_UPDATE end
304 from b_bp_task_user tu
305 inner join b_bp_task t on (t.ID = tu.TASK_ID)
306 where tu.USER_ID = {$userId} and tu.STATUS = '0'
307 )
308 ON DUPLICATE KEY UPDATE TASK_STATUS = VALUES(TASK_STATUS), MODIFIED = VALUES(MODIFIED)
309 SQL
310 );
311
312 //convert other tasks
313 \Bitrix\Bizproc\Worker\Task\UserToWorkflowStepper::bindUser($userId);
314 }
315}
static pushDeleted(mixed $itemId,... $userIds)
Definition basepush.php:28
static pushAdded(mixed $itemId,... $userIds)
Definition basepush.php:18
static pushUpdated(mixed $itemId,... $userIds)
Definition basepush.php:23
static syncOnWorkflowUpdated(\CBPWorkflow $workflow, int $status)
static getConnection($name="")