Commit | Line | Data |
---|---|---|
b019b130 TO |
1 | <?php |
2 | namespace Civi\CCase; | |
3 | ||
4 | /** | |
5 | * The sequence-listener looks for CiviCase XML tags with "<sequence>". If | |
6 | * a change is made to any record in case-type which uses "<sequence>", then | |
7 | * it attempts to add the next step in the sequence. | |
8 | */ | |
9 | class SequenceListener implements CaseChangeListener { | |
10 | ||
11 | /** | |
12 | * @var SequenceListener | |
13 | */ | |
14 | private static $singleton; | |
15 | ||
16 | /** | |
04855556 TO |
17 | * @param bool $reset |
18 | * Whether to forcibly rebuild the entire container. | |
45322593 | 19 | * @return SequenceListener |
b019b130 TO |
20 | */ |
21 | public static function singleton($reset = FALSE) { | |
22 | if ($reset || self::$singleton === NULL) { | |
23 | self::$singleton = new SequenceListener(); | |
24 | } | |
25 | return self::$singleton; | |
26 | } | |
27 | ||
7fe37828 EM |
28 | /** |
29 | * @param \Civi\CCase\Event\CaseChangeEvent $event | |
30 | */ | |
b019b130 TO |
31 | public static function onCaseChange_static(\Civi\CCase\Event\CaseChangeEvent $event) { |
32 | self::singleton()->onCaseChange($event); | |
33 | } | |
34 | ||
7fe37828 | 35 | /** |
5f7f8810 JP |
36 | * Triggers next case activity in sequence if current activity status is updated |
37 | * to type=COMPLETED(See CRM-21598). The adjoining activity is created according | |
38 | * to the sequence configured in case type. | |
39 | * | |
7fe37828 EM |
40 | * @param \Civi\CCase\Event\CaseChangeEvent $event |
41 | * | |
42 | * @throws \CiviCRM_API3_Exception | |
45322593 | 43 | * @return void |
7fe37828 | 44 | */ |
b019b130 TO |
45 | public function onCaseChange(\Civi\CCase\Event\CaseChangeEvent $event) { |
46 | /** @var \Civi\CCase\Analyzer $analyzer */ | |
47 | $analyzer = $event->analyzer; | |
48 | ||
b019b130 TO |
49 | $activitySetXML = $this->getSequenceXml($analyzer->getXml()); |
50 | if (!$activitySetXML) { | |
51 | return; | |
52 | } | |
53 | ||
b864360d | 54 | $actTypes = array_flip(\CRM_Activity_BAO_Activity::buildOptions('activity_type_id', 'validate')); |
de33391d | 55 | $actStatuses = array_flip(\CRM_Activity_BAO_Activity::getStatusesByType(\CRM_Activity_BAO_Activity::COMPLETED)); |
b019b130 | 56 | |
c64f69d9 | 57 | $actIndex = $analyzer->getActivityIndex(['activity_type_id', 'status_id']); |
b019b130 TO |
58 | |
59 | foreach ($activitySetXML->ActivityTypes->ActivityType as $actTypeXML) { | |
60 | $actTypeId = $actTypes[(string) $actTypeXML->name]; | |
61 | if (empty($actIndex[$actTypeId])) { | |
62 | // Haven't tried this step yet! | |
63 | $this->createActivity($analyzer, $actTypeXML); | |
b019b130 TO |
64 | return; |
65 | } | |
de33391d | 66 | elseif (!in_array(key($actIndex[$actTypeId]), $actStatuses)) { |
b019b130 | 67 | // Haven't gotten past this step yet! |
b019b130 TO |
68 | return; |
69 | } | |
70 | } | |
71 | ||
674829bf DA |
72 | //CRM-17452 - Close the case only if all the activities are complete |
73 | $activities = $analyzer->getActivities(); | |
74 | foreach ($activities as $activity) { | |
de33391d | 75 | if (!in_array($activity['status_id'], $actStatuses)) { |
674829bf DA |
76 | return; |
77 | } | |
78 | } | |
79 | ||
80 | // OK, the all activities have completed | |
c64f69d9 | 81 | civicrm_api3('Case', 'create', [ |
46bcf597 | 82 | 'id' => $analyzer->getCaseId(), |
b019b130 | 83 | 'status_id' => 'Closed', |
c64f69d9 | 84 | ]); |
b019b130 | 85 | $analyzer->flush(); |
b019b130 TO |
86 | } |
87 | ||
88 | /** | |
89 | * Find the ActivitySet which defines the pipeline. | |
90 | * | |
91 | * @param \SimpleXMLElement $xml | |
92 | * @return \SimpleXMLElement|NULL | |
93 | */ | |
94 | public function getSequenceXml($xml) { | |
95 | if ($xml->ActivitySets && $xml->ActivitySets->ActivitySet) { | |
96 | foreach ($xml->ActivitySets->ActivitySet as $activitySetXML) { | |
97 | $seq = (string) $activitySetXML->sequence; | |
98 | if ($seq && strtolower($seq) == 'true') { | |
99 | if ($activitySetXML->ActivityTypes && $activitySetXML->ActivityTypes->ActivityType) { | |
100 | return $activitySetXML; | |
101 | } | |
102 | else { | |
103 | return NULL; | |
104 | } | |
105 | } | |
106 | } | |
107 | } | |
108 | return NULL; | |
109 | } | |
110 | ||
111 | /** | |
04855556 TO |
112 | * @param Analyzer $analyzer |
113 | * The case being analyzed -- to which we want to add an activity. | |
b019b130 TO |
114 | * @param \SimpleXMLElement $actXML the <ActivityType> tag which describes the new activity |
115 | */ | |
116 | public function createActivity(Analyzer $analyzer, \SimpleXMLElement $actXML) { | |
c64f69d9 | 117 | $params = [ |
b019b130 TO |
118 | 'activity_type_id' => (string) $actXML->name, |
119 | 'status_id' => 'Scheduled', | |
120 | 'activity_date_time' => \CRM_Utils_Time::getTime('YmdHis'), | |
121 | 'case_id' => $analyzer->getCaseId(), | |
c64f69d9 | 122 | ]; |
c90ec5ab MWMC |
123 | $case = $analyzer->getCase(); |
124 | if (!empty($case['contact_id'])) { | |
125 | $params['target_id'] = \CRM_Utils_Array::first($case['contact_id']); | |
126 | } | |
127 | ||
128 | civicrm_api3('Activity', 'create', $params); | |
b019b130 TO |
129 | $analyzer->flush(); |
130 | } | |
96025800 | 131 | |
ef10e0b5 | 132 | } |