Bitrix-D7 23.9
 
Загрузка...
Поиск...
Не найдено
appconfiguration.php
1<?php
2
4
8use Bitrix\Crm\Automation\Trigger\Entity\TriggerTable;
16use CBPDocument;
17use Exception;
18
20{
21 const ENTITY_BIZPROC_MAIN = 'BIZPROC_MAIN';
22 const ENTITY_BIZPROC_CRM_TRIGGER = 'BIZPROC_CRM_TRIGGER';
23 const ENTITY_BIZPROC_SCRIPT = 'BIZPROC_SCRIPT';
24
25 const OWNER_ENTITY_TYPE_BIZPROC = 'BIZPROC';
26 const OWNER_ENTITY_TYPE_TRIGGER = 'TRIGGER';
27 const OWNER_ENTITY_TYPE_BIZPROC_SCRIPT = 'BIZPROC_SCRIPT';
28
29 private static $entityList = [
30 self::ENTITY_BIZPROC_MAIN => 500,
31 self::ENTITY_BIZPROC_CRM_TRIGGER => 600,
32 self::ENTITY_BIZPROC_SCRIPT => 700,
33 ];
34 private static $customDealMatch = '/^C([0-9]+):/';
35 private static $accessModules = ['crm'];
36 private static $context;
37 private static $accessManifest = [
38 'total',
39 'bizproc_crm',
40 ];
41
42 public static function getEntityList()
43 {
44 return static::$entityList;
45 }
46
47 public static function onEventExportController(Event $event)
48 {
49 $result = null;
50 $code = $event->getParameter('CODE');
51 $itemCode = $event->getParameter('ITEM_CODE');
52 if (!static::$entityList[$code])
53 {
54 return $result;
55 }
56
57 $option = $event->getParameters();
58 if ($code !== self::ENTITY_BIZPROC_SCRIPT && !Helper::checkAccessManifest($option, static::$accessManifest))
59 {
60 return $result;
61 }
62
63 if (
64 $code === self::ENTITY_BIZPROC_SCRIPT
65 && !Helper::checkAccessManifest($option, ['bizproc_script'])
66 )
67 {
68 return $result;
69 }
70
71 try
72 {
73 if (static::checkRequiredParams($code))
74 {
75 $step = $event->getParameter('STEP');
76 switch ($code)
77 {
79 $result = static::exportBizproc($step);
80 break;
82 $result = static::exportCrmTrigger($step);
83 break;
85 $result = static::exportScript($step, $event->getParameter('NEXT'), $itemCode);
86 break;
87 }
88 }
89 }
90 catch (Exception $e)
91 {
92 $result['NEXT'] = false;
93 $result['ERROR_ACTION'] = $e->getMessage();
94 $result['ERROR_MESSAGES'] = Loc::getMessage(
95 'BIZPROC_ERROR_CONFIGURATION_EXPORT_EXCEPTION',
96 [
97 '#CODE#' => $code,
98 ]
99 );
100 }
101
102 return $result;
103 }
104
105 public static function onEventClearController(Event $event)
106 {
107 $code = $event->getParameter('CODE');
108 if (!static::$entityList[$code])
109 {
110 return null;
111 }
112 $option = $event->getParameters();
113
114 if ($code !== self::ENTITY_BIZPROC_SCRIPT && !Helper::checkAccessManifest($option, static::$accessManifest))
115 {
116 return null;
117 }
118
119 if (
120 $code === self::ENTITY_BIZPROC_SCRIPT
121 && !Helper::checkAccessManifest($option, ['bizproc_script'])
122 )
123 {
124 return null;
125 }
126
127 $result = null;
128
129 try
130 {
131 if (static::checkRequiredParams($code))
132 {
133 switch ($code)
134 {
136 $result = static::clearBizproc($option);
137 break;
139 $result = static::clearCrmTrigger($option);
140 break;
142 $result = static::clearScript($option);
143 break;
144 }
145 }
146 }
147 catch (Exception $e)
148 {
149 $result['NEXT'] = false;
150 $result['ERROR_ACTION'] = $e->getMessage();
151 $result['ERROR_MESSAGES'] = Loc::getMessage(
152 'BIZPROC_ERROR_CONFIGURATION_CLEAR_EXCEPTION',
153 [
154 '#CODE#' => $code,
155 ]
156 );
157 }
158
159 return $result;
160 }
161
162 public static function onEventImportController(Event $event)
163 {
164 $code = $event->getParameter('CODE');
165 if (!static::$entityList[$code])
166 {
167 return null;
168 }
169 $data = $event->getParameters();
170
171 if ($code !== self::ENTITY_BIZPROC_SCRIPT && !Helper::checkAccessManifest($data, static::$accessManifest))
172 {
173 return null;
174 }
175
176 if (
177 $code === self::ENTITY_BIZPROC_SCRIPT
178 && !Helper::checkAccessManifest($data, ['bizproc_script'])
179 )
180 {
181 return null;
182 }
183
184 $result = null;
185 $userId = (int)$event->getParameter('USER_ID');
186
187 $contextUser = $event->getParameter('CONTEXT_USER');
188 $setting = new Setting($contextUser);
189 $app = $setting->get(Setting::SETTING_APP_INFO);
190 $appId = (int)$app['ID'];
191
192 try
193 {
194 if (static::checkRequiredParams($code))
195 {
196 switch ($code)
197 {
199 $result = static::importBizproc($data);
200 break;
202 $result = static::importCrmTrigger($data);
203 break;
205 $result = static::importScript($data, $userId, $appId);
206 break;
207 }
208 }
209 }
210 catch (Exception $e)
211 {
212 $result['NEXT'] = false;
213 $result['ERROR_ACTION'] = $e->getMessage();
214 $result['ERROR_MESSAGES'] = Loc::getMessage(
215 'BIZPROC_ERROR_CONFIGURATION_IMPORT_EXCEPTION',
216 [
217 '#CODE#' => $code,
218 ]
219 );
220 }
221
222 return $result;
223 }
224
230 private static function checkRequiredParams($type)
231 {
232 $return = true;
233 if ($type == self::ENTITY_BIZPROC_CRM_TRIGGER)
234 {
235 if (!Loader::IncludeModule('crm'))
236 {
237 throw new SystemException('need install module: crm');
238 }
239 }
240
241 return $return;
242 }
243
244 //region bizproc
245 private static function exportBizproc($step)
246 {
247 $result = [
248 'FILE_NAME' => '',
249 'CONTENT' => [],
250 'NEXT' => false,
251 ];
252 $res = WorkflowTemplateTable::getList(
253 [
254 'order' => [
255 'ID' => 'ASC',
256 ],
257 'filter' => [
258 '=MODULE_ID' => static::$accessModules,
259 '<AUTO_EXECUTE' => \CBPDocumentEventType::Script,
260 ],
261 'limit' => 1,
262 'offset' => $step,
263 ]
264 );
265 if ($tpl = $res->fetchObject())
266 {
267 $result['NEXT'] = $step;
268 if (in_array($tpl->getModuleId(), static::$accessModules))
269 {
270 $result['FILE_NAME'] = $step;
271 $packer = new \Bitrix\Bizproc\Workflow\Template\Packer\Bpt();
272 $data = $packer->makePackageData($tpl);
273 $result['CONTENT'] = [
274 'ID' => $tpl->getId(),
275 'MODULE_ID' => $tpl->getModuleId(),
276 'ENTITY' => $tpl->getEntity(),
277 'DOCUMENT_TYPE' => $tpl->getDocumentType(),
278 'DOCUMENT_STATUS' => $tpl->getDocumentStatus(),
279 'NAME' => $tpl->getName(),
280 'AUTO_EXECUTE' => $tpl->getAutoExecute(),
281 'DESCRIPTION' => $tpl->getDescription(),
282 'SYSTEM_CODE' => $tpl->getSystemCode(),
283 'ORIGINATOR_ID' => $tpl->getOriginatorId(),
284 'ORIGIN_ID' => $tpl->getOriginId(),
285 'TEMPLATE_DATA' => $data,
286 ];
287 }
288 }
289
290 return $result;
291 }
292
293 private static function clearBizproc($option)
294 {
295 $result = [
296 'NEXT' => false,
297 'OWNER_DELETE' => [],
298 ];
299 $clearFull = $option['CLEAR_FULL'];
300 $prefix = $option['PREFIX_NAME'];
301 $pattern = '/^\‍(' . $prefix . '\‍)/';
302
303 $res = WorkflowTemplateTable::getList(
304 [
305 'order' => [
306 'ID' => 'ASC',
307 ],
308 'filter' => [
309 '=MODULE_ID' => static::$accessModules,
310 '>ID' => $option['NEXT'],
311 '<AUTO_EXECUTE' => \CBPDocumentEventType::Script,
312 ],
313 'select' => ['*'],
314 ]
315 );
316 $errorsTmp = [];
317 while ($item = $res->Fetch())
318 {
319 $result['NEXT'] = $item['ID'];
320
321 if (!$clearFull && $item['DOCUMENT_TYPE'] == 'DEAL')
322 {
323 //dont off old custom deal robot
324 $matches = [];
325 preg_match(static::$customDealMatch, $item['DOCUMENT_STATUS'], $matches, PREG_OFFSET_CAPTURE);
326 if (!empty($matches))
327 {
328 continue;
329 }
330 }
331
332 if ($clearFull || !empty($item['DOCUMENT_STATUS']))
333 {
334 CBPDocument::DeleteWorkflowTemplate(
335 $item['ID'],
336 [
337 $item['MODULE_ID'],
338 $item['ENTITY'],
339 $item['DOCUMENT_TYPE'],
340 ],
341 $errorsTmp
342 );
343 if (!$errorsTmp)
344 {
345 $result['OWNER_DELETE'][] = [
346 'ENTITY_TYPE' => self::OWNER_ENTITY_TYPE_BIZPROC,
347 'ENTITY' => $item['ID'],
348 ];
349 }
350 }
351 else
352 {
353 $name = $item['NAME'];
354 if ($prefix != '' && preg_match($pattern, $name) === 0)
355 {
356 $name = "($prefix) " . $name;
357 }
358 CBPDocument::UpdateWorkflowTemplate(
359 $item['ID'],
360 [
361 $item['MODULE_ID'],
362 $item['ENTITY'],
363 $item['DOCUMENT_TYPE'],
364 ],
365 [
366 'ACTIVE' => 'N',
367 'AUTO_EXECUTE' => \CBPDocumentEventType::None,
368 'NAME' => $name,
369 ],
370 $errorsTmp
371 );
372 }
373 }
374
375 return $result;
376 }
377
378 private static function importBizproc($importData)
379 {
380 $result = [];
381
382 if (!isset($importData['CONTENT']['DATA']))
383 {
384 return false;
385 }
386 $item = $importData['CONTENT']['DATA'];
387 if (
388 in_array($item['MODULE_ID'], static::$accessModules)
389 && Loader::includeModule($item['MODULE_ID'])
390 && class_exists($item['ENTITY'])
391 )
392 {
393 if (is_subclass_of($item['ENTITY'], '\\IBPWorkflowDocument'))
394 {
395
396 if (isset($importData['RATIO']['CRM_STATUS']))
397 {
398 if (is_array($item['TEMPLATE_DATA']))
399 {
400 $item['TEMPLATE_DATA'] = static::changeDealCategory($item['TEMPLATE_DATA'], $importData['RATIO']['CRM_STATUS']);
401 }
402 if ($item['DOCUMENT_TYPE'] == 'DEAL' && $item['DOCUMENT_STATUS'])
403 {
404 $item['DOCUMENT_STATUS'] = static::changeDealCategory($item['DOCUMENT_STATUS'], $importData['RATIO']['CRM_STATUS']);
405 }
406 }
407
408 try
409 {
410 $code = static::$context . '_xml_' . intval($item['ID']);
411 $id = \CBPWorkflowTemplateLoader::importTemplateFromArray(
412 0,
413 [
414 $item['MODULE_ID'],
415 $item['ENTITY'],
416 $item['DOCUMENT_TYPE'],
417 ],
418 $item['AUTO_EXECUTE'],
419 $item['NAME'],
420 isset($item['DESCRIPTION']) ? (string)$item['DESCRIPTION'] : '',
421 $item['TEMPLATE_DATA'],
422 $code
423 );
424
425 if ($id > 0)
426 {
427 $result['OWNER'] = [
428 'ENTITY_TYPE' => self::OWNER_ENTITY_TYPE_BIZPROC,
429 'ENTITY' => $id,
430 ];
431
432 if ($item['DOCUMENT_STATUS'])
433 {
434 \CBPWorkflowTemplateLoader::update(
435 $id,
436 [
437 'DOCUMENT_STATUS' => $item['DOCUMENT_STATUS'],
438 ]
439 );
440 }
441 }
442 }
443 catch (\Exception $e)
444 {
445 $result['ERROR_ACTION'] = $e->getMessage();
446 $result['ERROR_MESSAGES'] = Loc::getMessage(
447 'BIZPROC_ERROR_CONFIGURATION_IMPORT_EXCEPTION_BP'
448 );
449 }
450 }
451 }
452
453 return $result;
454 }
455 //end region bizproc
456
457 //region trigger
458 private static function exportCrmTrigger($step)
459 {
460 $result = [
461 'FILE_NAME' => '',
462 'CONTENT' => [],
463 'NEXT' => false,
464 ];
465
466 $res = TriggerTable::getList(
467 [
468 'order' => [
469 'ID' => 'ASC',
470 ],
471 'filter' => [],
472 'select' => ['*'],
473 'limit' => 1,
474 'offset' => $step,
475 ]
476 );
477 if ($item = $res->Fetch())
478 {
479 $result['FILE_NAME'] = $step;
480 $result['CONTENT'] = $item;
481 $result['NEXT'] = $step;
482 }
483
484 return $result;
485 }
486
487 private static function clearCrmTrigger($option)
488 {
489 $result = [
490 'NEXT' => false,
491 ];
492 $clearFull = $option['CLEAR_FULL'];
493
494 $res = TriggerTable::getList(
495 [
496 'order' => [
497 'ID' => 'ASC',
498 ],
499 'filter' => [
500 '>ID' => $option['NEXT'],
501 ],
502 'limit' => 10,
503 ]
504 );
505 while ($item = $res->Fetch())
506 {
507 $result['NEXT'] = $item['ID'];
508 if (!$clearFull && $item['ENTITY_TYPE_ID'] == \CCrmOwnerType::Deal)
509 {
510 //dont off old custom deal trigger
511 $matches = [];
512 preg_match(static::$customDealMatch, $item['ENTITY_STATUS'], $matches, PREG_OFFSET_CAPTURE);
513 if (!empty($matches))
514 {
515 continue;
516 }
517 }
518 $delete = TriggerTable::delete($item['ID']);
519 if ($delete->isSuccess())
520 {
521 $result['OWNER_DELETE'][] = [
522 'ENTITY_TYPE' => self::OWNER_ENTITY_TYPE_TRIGGER,
523 'ENTITY' => $item['ID'],
524 ];
525 }
526 }
527
528 return $result;
529 }
530
531 private static function importCrmTrigger($importData)
532 {
533 $result = [];
534 if (!isset($importData['CONTENT']['DATA']))
535 {
536 return false;
537 }
538 $item = $importData['CONTENT']['DATA'];
539
540 if (
541 isset($item['NAME'])
542 && isset($item['CODE'])
543 && isset($item['ENTITY_TYPE_ID'])
544 && isset($item['ENTITY_STATUS'])
545 )
546 {
547 if (isset($importData['RATIO']['CRM_STATUS']))
548 {
549 if (is_array($item['APPLY_RULES']))
550 {
551 $item['APPLY_RULES'] = static::changeDealCategory(
552 $item['APPLY_RULES'],
553 $importData['RATIO']['CRM_STATUS']
554 );
555 }
556 if ($item['ENTITY_TYPE_ID'] == \CCrmOwnerType::Deal)
557 {
558 $item['ENTITY_STATUS'] = static::changeDealCategory(
559 $item['ENTITY_STATUS'],
560 $importData['RATIO']['CRM_STATUS']
561 );
562 }
563 }
564
565 $saveData = [
566 'NAME' => $item['NAME'],
567 'CODE' => $item['CODE'],
568 'ENTITY_TYPE_ID' => $item['ENTITY_TYPE_ID'],
569 'ENTITY_STATUS' => $item['ENTITY_STATUS'],
570 'APPLY_RULES' => is_array($item['APPLY_RULES']) ? $item['APPLY_RULES'] : null,
571 ];
572
573 $res = TriggerTable::add($saveData);
574 if ($res->isSuccess())
575 {
576 $result['OWNER'] = [
577 'ENTITY_TYPE' => self::OWNER_ENTITY_TYPE_TRIGGER,
578 'ENTITY' => $res->getId(),
579 ];
580 }
581 }
582
583 return $result;
584 }
585
586 //end region trigger
587
588 //region script
589 private static function exportScript($step, $nextId, $docType)
590 {
591 $result = [
592 'FILE_NAME' => '',
593 'CONTENT' => [],
594 'NEXT' => false,
595 ];
596
597 $nextId = (int)$nextId;
598
599 $filter = [
600 '>ID' => $nextId,
601 '=MODULE_ID' => static::$accessModules,
602 ];
603
604 if ($docType)
605 {
606 $filter['=DOCUMENT_TYPE'] = $docType;
607 }
608
609 $res = ScriptTable::getList(
610 [
611 'order' => [
612 'ID' => 'ASC',
613 ],
614 'filter' => $filter,
615 'limit' => 1,
616 'select' => ['ID'],
617 ]
618 );
619 if ($tpl = $res->fetch())
620 {
621 $data = Script\Manager::exportScript($tpl['ID']);
622 if ($data)
623 {
624 $result['NEXT'] = $tpl['ID'];
625 $result['FILE_NAME'] = $step;
626 $result['CONTENT'] = $data;
627 }
628 }
629
630 return $result;
631 }
632
633 private static function clearScript($option)
634 {
635 $result = [
636 'NEXT' => false,
637 'OWNER_DELETE' => [],
638 ];
639
640 if (!$option['CLEAR_FULL'])
641 {
642 return $result;
643 }
644
645 $res = ScriptTable::getList(
646 [
647 'order' => [
648 'ID' => 'ASC',
649 ],
650 'filter' => [
651 '>ID' => (int)$option['NEXT'],
652 '=MODULE_ID' => static::$accessModules,
653 ],
654 'limit' => 1,
655 'select' => ['ID'],
656 ]
657 );
658
659 while ($item = $res->Fetch())
660 {
661 $result['NEXT'] = $item['ID'];
662
663 $deletionResult = Script\Manager::deleteScript($item['ID']);
664
665 if ($deletionResult->isSuccess())
666 {
667 $result['OWNER_DELETE'][] = [
669 'ENTITY' => $item['ID'],
670 ];
671 }
672 }
673
674 return $result;
675 }
676
677 private static function importScript($importData, int $userId, int $appId)
678 {
679 $result = [];
680
681 if (!isset($importData['CONTENT']['DATA']))
682 {
683 return false;
684 }
685 $item = $importData['CONTENT']['DATA'];
686 if (
687 in_array($item['MODULE_ID'], static::$accessModules)
688 && Loader::includeModule($item['MODULE_ID'])
689 && class_exists($item['ENTITY'])
690 )
691 {
692 if (is_subclass_of($item['ENTITY'], '\\IBPWorkflowDocument'))
693 {
694 if (isset($importData['RATIO']['CRM_STATUS']) && $item['DOCUMENT_TYPE'] === 'DEAL')
695 {
696 if (is_array($item['WORKFLOW_TEMPLATE']))
697 {
698 $item['WORKFLOW_TEMPLATE'] = static::changeDealCategory(
699 $item['WORKFLOW_TEMPLATE'],
700 $importData['RATIO']['CRM_STATUS']
701 );
702 }
703 }
704
705 if ($appId > 0)
706 {
707 $item['ORIGINATOR_ID'] = 'REST_APP';
708 $item['ORIGIN_ID'] = $appId;
709 }
710
711 $importResult = Script\Manager::importScript($item, $userId);
712
713 if ($importResult->isSuccess())
714 {
715 $result['OWNER'] = [
717 'ENTITY' => $importResult->getId(),
718 ];
719 }
720 else
721 {
722 $result['ERROR_ACTION'] = $result['ERROR_MESSAGES'] = current($importResult->getErrorMessages());
723 }
724 }
725 }
726
727 return $result;
728 }
729 //end region script
730
731 private static function changeDealCategory($data, $ratio)
732 {
733 if (!empty($ratio))
734 {
735 $ratioRegEx = [];
736 $ratioReplace = [];
737 foreach ($ratio as $oldId => $newId)
738 {
739 $ratioRegEx[] = '/^C' . $oldId . ':/';
740 $ratioReplace[] = 'C' . $newId . ':';
741 }
742 if (!empty($ratioRegEx))
743 {
744 $data = static::changeDealCategoryAction($data, $ratioRegEx, $ratioReplace, $ratio);
745 }
746 }
747
748 return $data;
749 }
750
751 private static function changeDealCategoryAction($data, $ratioRegEx, $ratioReplace, $ratio)
752 {
753 if (is_string($data))
754 {
755 $data = preg_replace($ratioRegEx, $ratioReplace, $data);
756 }
757 elseif (is_array($data))
758 {
759 if (
760 isset($data['field'])
761 && $data['field'] == 'CATEGORY_ID'
762 && $data['value'] > 0
763 && $ratio[$data['value']] > 0
764 )
765 {
766 $data['value'] = $ratio[$data['value']];
767 }
768
769 foreach ($data as $key => $value)
770 {
771 $newKey = static::changeDealCategoryAction($key, $ratioRegEx, $ratioReplace, $ratio);
772 if ($newKey != $key)
773 {
774 unset($data[$key]);
775 }
776
777 if ($newKey == 'CATEGORY_ID')
778 {
779 if (is_array($value))
780 {
781 if (isset($value['Options']) && is_array($value['Options']))
782 {
783 $data[$newKey]['Options'] = [];
784 foreach ($value['Options'] as $dealId => $title)
785 {
786 if (isset($ratio[$dealId]))
787 {
788 $data[$newKey]['Options'][$ratio[$dealId]] = $title;
789 }
790 }
791 }
792 else
793 {
794 $data[$newKey] = static::changeDealCategoryAction(
795 $value,
796 $ratioRegEx,
797 $ratioReplace,
798 $ratio
799 );
800 }
801 }
802 elseif (is_string($value) && isset($ratio[$value]))
803 {
804 $data[$newKey] = $ratio[$value];
805 }
806 else
807 {
808 $data[$newKey] = static::changeDealCategoryAction(
809 $value,
810 $ratioRegEx,
811 $ratioReplace,
812 $ratio
813 );
814 }
815 }
816 elseif ($newKey == 'CategoryId' && intVal($value) > 0 && !empty($ratio[$value]))
817 {
818 $data[$newKey] = $ratio[$value];
819 }
820 else
821 {
822 $data[$newKey] = static::changeDealCategoryAction(
823 $value,
824 $ratioRegEx,
825 $ratioReplace,
826 $ratio
827 );
828 }
829 }
830 }
831
832 return $data;
833 }
834}
getParameter($key)
Definition event.php:80
static getMessage($code, $replace=null, $language=null)
Definition loc.php:29
static checkAccessManifest($params, $uses=[])
Definition helper.php:324