示例#1
0
 /**
  * Function to add activity contact.
  *
  * @param array $params
  *   The values for this table: activity id, contact id, record type.
  *
  * @return object
  *   activity_contact object
  */
 public static function create(&$params)
 {
     $activityContact = new CRM_Activity_DAO_ActivityContact();
     $activityContact->copyValues($params);
     if (!$activityContact->find(TRUE)) {
         return $activityContact->save();
     }
     return $activityContact;
 }
示例#2
0
    /**
     * Function perform two task.
     * 1. Merge two duplicate contacts cases - follow CRM-5758 rules.
     * 2. Merge two cases of same contact - follow CRM-5598 rules.
     *
     * @param int $mainContactId contact id of main contact record.
     * @param int $mainCaseId case id of main case record.
     * @param int $otherContactId contact id of record which is going to merge.
     * @param int $otherCaseId case id of record which is going to merge.
     *
     * @param bool $changeClient
     *
     * @return integer|NULL
     * @static
     */
    static function mergeCases($mainContactId, $mainCaseId = NULL, $otherContactId = NULL, $otherCaseId = NULL, $changeClient = FALSE)
    {
        $moveToTrash = TRUE;
        $duplicateContacts = FALSE;
        if ($mainContactId && $otherContactId && $mainContactId != $otherContactId) {
            $duplicateContacts = TRUE;
        }
        $duplicateCases = FALSE;
        if ($mainCaseId && $otherCaseId && $mainCaseId != $otherCaseId) {
            $duplicateCases = TRUE;
        }
        $mainCaseIds = array();
        if (!$duplicateContacts && !$duplicateCases) {
            return $mainCaseIds;
        }
        $activityTypes = CRM_Core_PseudoConstant::activityType(TRUE, TRUE, FALSE, 'name');
        $activityStatuses = CRM_Core_PseudoConstant::activityStatus('name');
        $activityContacts = CRM_Core_OptionGroup::values('activity_contacts', FALSE, FALSE, FALSE, NULL, 'name');
        $sourceID = CRM_Utils_Array::key('Activity Source', $activityContacts);
        $assigneeID = CRM_Utils_Array::key('Activity Assignees', $activityContacts);
        $targetID = CRM_Utils_Array::key('Activity Targets', $activityContacts);
        $processCaseIds = array($otherCaseId);
        if ($duplicateContacts && !$duplicateCases) {
            if ($changeClient) {
                $processCaseIds = array($mainCaseId);
            } else {
                //get all case ids for other contact.
                $processCaseIds = self::retrieveCaseIdsByContactId($otherContactId, TRUE);
            }
            if (!is_array($processCaseIds)) {
                return;
            }
        }
        $session = CRM_Core_Session::singleton();
        $currentUserId = $session->get('userID');
        CRM_Utils_Hook::pre_case_merge($mainContactId, $mainCaseId, $otherContactId, $otherCaseId, $changeClient);
        // copy all cases and connect to main contact id.
        foreach ($processCaseIds as $otherCaseId) {
            if ($duplicateContacts) {
                $mainCase = CRM_Core_DAO::copyGeneric('CRM_Case_DAO_Case', array('id' => $otherCaseId));
                $mainCaseId = $mainCase->id;
                if (!$mainCaseId) {
                    continue;
                }
                // CRM-11662 Copy Case custom data
                $extends = array('case');
                $groupTree = CRM_Core_BAO_CustomGroup::getGroupDetail(NULL, NULL, $extends);
                if ($groupTree) {
                    foreach ($groupTree as $groupID => $group) {
                        $table[$groupTree[$groupID]['table_name']] = array('entity_id');
                        foreach ($group['fields'] as $fieldID => $field) {
                            $table[$groupTree[$groupID]['table_name']][] = $groupTree[$groupID]['fields'][$fieldID]['column_name'];
                        }
                    }
                    foreach ($table as $tableName => $tableColumns) {
                        $insert = 'INSERT INTO ' . $tableName . ' (' . implode(', ', $tableColumns) . ') ';
                        $tableColumns[0] = $mainCaseId;
                        $select = 'SELECT ' . implode(', ', $tableColumns);
                        $from = ' FROM ' . $tableName;
                        $where = " WHERE {$tableName}.entity_id = {$otherCaseId}";
                        $query = $insert . $select . $from . $where;
                        $dao = CRM_Core_DAO::executeQuery($query, CRM_Core_DAO::$_nullArray);
                    }
                }
                $mainCase->free();
                $mainCaseIds[] = $mainCaseId;
                //insert record for case contact.
                $otherCaseContact = new CRM_Case_DAO_CaseContact();
                $otherCaseContact->case_id = $otherCaseId;
                $otherCaseContact->find();
                while ($otherCaseContact->fetch()) {
                    $mainCaseContact = new CRM_Case_DAO_CaseContact();
                    $mainCaseContact->case_id = $mainCaseId;
                    $mainCaseContact->contact_id = $otherCaseContact->contact_id;
                    if ($mainCaseContact->contact_id == $otherContactId) {
                        $mainCaseContact->contact_id = $mainContactId;
                    }
                    //avoid duplicate object.
                    if (!$mainCaseContact->find(TRUE)) {
                        $mainCaseContact->save();
                    }
                    $mainCaseContact->free();
                }
                $otherCaseContact->free();
            } elseif (!$otherContactId) {
                $otherContactId = $mainContactId;
            }
            if (!$mainCaseId || !$otherCaseId || !$mainContactId || !$otherContactId) {
                continue;
            }
            // get all activities for other case.
            $otherCaseActivities = array();
            CRM_Core_DAO::commonRetrieveAll('CRM_Case_DAO_CaseActivity', 'case_id', $otherCaseId, $otherCaseActivities);
            //for duplicate cases do not process singleton activities.
            $otherActivityIds = $singletonActivityIds = array();
            foreach ($otherCaseActivities as $caseActivityId => $otherIds) {
                $otherActId = CRM_Utils_Array::value('activity_id', $otherIds);
                if (!$otherActId || in_array($otherActId, $otherActivityIds)) {
                    continue;
                }
                $otherActivityIds[] = $otherActId;
            }
            if ($duplicateCases) {
                if ($openCaseType = array_search('Open Case', $activityTypes)) {
                    $sql = "\nSELECT  id\n  FROM  civicrm_activity\n WHERE  activity_type_id = {$openCaseType}\n   AND  id IN ( " . implode(',', array_values($otherActivityIds)) . ');';
                    $dao = CRM_Core_DAO::executeQuery($sql);
                    while ($dao->fetch()) {
                        $singletonActivityIds[] = $dao->id;
                    }
                    $dao->free();
                }
            }
            // migrate all activities and connect to main contact.
            $copiedActivityIds = $activityMappingIds = array();
            sort($otherActivityIds);
            foreach ($otherActivityIds as $otherActivityId) {
                //for duplicate cases -
                //do not migrate singleton activities.
                if (!$otherActivityId || in_array($otherActivityId, $singletonActivityIds)) {
                    continue;
                }
                //migrate activity record.
                $otherActivity = new CRM_Activity_DAO_Activity();
                $otherActivity->id = $otherActivityId;
                if (!$otherActivity->find(TRUE)) {
                    continue;
                }
                $mainActVals = array();
                $mainActivity = new CRM_Activity_DAO_Activity();
                CRM_Core_DAO::storeValues($otherActivity, $mainActVals);
                $mainActivity->copyValues($mainActVals);
                $mainActivity->id = NULL;
                $mainActivity->activity_date_time = CRM_Utils_Date::isoToMysql($otherActivity->activity_date_time);
                $mainActivity->source_record_id = CRM_Utils_Array::value($mainActivity->source_record_id, $activityMappingIds);
                $mainActivity->original_id = CRM_Utils_Array::value($mainActivity->original_id, $activityMappingIds);
                $mainActivity->parent_id = CRM_Utils_Array::value($mainActivity->parent_id, $activityMappingIds);
                $mainActivity->save();
                $mainActivityId = $mainActivity->id;
                if (!$mainActivityId) {
                    continue;
                }
                $activityMappingIds[$otherActivityId] = $mainActivityId;
                // insert log of all activities
                CRM_Activity_BAO_Activity::logActivityAction($mainActivity);
                $otherActivity->free();
                $mainActivity->free();
                $copiedActivityIds[] = $otherActivityId;
                //create case activity record.
                $mainCaseActivity = new CRM_Case_DAO_CaseActivity();
                $mainCaseActivity->case_id = $mainCaseId;
                $mainCaseActivity->activity_id = $mainActivityId;
                $mainCaseActivity->save();
                $mainCaseActivity->free();
                //migrate source activity.
                $otherSourceActivity = new CRM_Activity_DAO_ActivityContact();
                $otherSourceActivity->activity_id = $otherActivityId;
                $otherSourceActivity->record_type_id = $sourceID;
                $otherSourceActivity->find();
                while ($otherSourceActivity->fetch()) {
                    $mainActivitySource = new CRM_Activity_DAO_ActivityContact();
                    $mainActivitySource->record_type_id = $sourceID;
                    $mainActivitySource->activity_id = $mainActivityId;
                    $mainActivitySource->contact_id = $otherSourceActivity->contact_id;
                    if ($mainActivitySource->contact_id == $otherContactId) {
                        $mainActivitySource->contact_id = $mainContactId;
                    }
                    //avoid duplicate object.
                    if (!$mainActivitySource->find(TRUE)) {
                        $mainActivitySource->save();
                    }
                    $mainActivitySource->free();
                }
                $otherSourceActivity->free();
                //migrate target activities.
                $otherTargetActivity = new CRM_Activity_DAO_ActivityContact();
                $otherTargetActivity->activity_id = $otherActivityId;
                $otherTargetActivity->record_type_id = $targetID;
                $otherTargetActivity->find();
                while ($otherTargetActivity->fetch()) {
                    $mainActivityTarget = new CRM_Activity_DAO_ActivityContact();
                    $mainActivityTarget->record_type_id = $targetID;
                    $mainActivityTarget->activity_id = $mainActivityId;
                    $mainActivityTarget->contact_id = $otherTargetActivity->contact_id;
                    if ($mainActivityTarget->contact_id == $otherContactId) {
                        $mainActivityTarget->contact_id = $mainContactId;
                    }
                    //avoid duplicate object.
                    if (!$mainActivityTarget->find(TRUE)) {
                        $mainActivityTarget->save();
                    }
                    $mainActivityTarget->free();
                }
                $otherTargetActivity->free();
                //migrate assignee activities.
                $otherAssigneeActivity = new CRM_Activity_DAO_ActivityContact();
                $otherAssigneeActivity->activity_id = $otherActivityId;
                $otherAssigneeActivity->record_type_id = $assigneeID;
                $otherAssigneeActivity->find();
                while ($otherAssigneeActivity->fetch()) {
                    $mainAssigneeActivity = new CRM_Activity_DAO_ActivityContact();
                    $mainAssigneeActivity->activity_id = $mainActivityId;
                    $mainAssigneeActivity->record_type_id = $assigneeID;
                    $mainAssigneeActivity->contact_id = $otherAssigneeActivity->contact_id;
                    if ($mainAssigneeActivity->contact_id == $otherContactId) {
                        $mainAssigneeActivity->contact_id = $mainContactId;
                    }
                    //avoid duplicate object.
                    if (!$mainAssigneeActivity->find(TRUE)) {
                        $mainAssigneeActivity->save();
                    }
                    $mainAssigneeActivity->free();
                }
                $otherAssigneeActivity->free();
                // copy custom fields and attachments
                $aparams = array('activityID' => $otherActivityId, 'mainActivityId' => $mainActivityId);
                CRM_Activity_BAO_Activity::copyExtendedActivityData($aparams);
            }
            //copy case relationship.
            if ($duplicateContacts) {
                //migrate relationship records.
                $otherRelationship = new CRM_Contact_DAO_Relationship();
                $otherRelationship->case_id = $otherCaseId;
                $otherRelationship->find();
                $otherRelationshipIds = array();
                while ($otherRelationship->fetch()) {
                    $otherRelVals = array();
                    $updateOtherRel = FALSE;
                    CRM_Core_DAO::storeValues($otherRelationship, $otherRelVals);
                    $mainRelationship = new CRM_Contact_DAO_Relationship();
                    $mainRelationship->copyValues($otherRelVals);
                    $mainRelationship->id = NULL;
                    $mainRelationship->case_id = $mainCaseId;
                    if ($mainRelationship->contact_id_a == $otherContactId) {
                        $updateOtherRel = TRUE;
                        $mainRelationship->contact_id_a = $mainContactId;
                    }
                    //case creator change only when we merge user contact.
                    if ($mainRelationship->contact_id_b == $otherContactId) {
                        //do not change creator for change client.
                        if (!$changeClient) {
                            $updateOtherRel = TRUE;
                            $mainRelationship->contact_id_b = $currentUserId ? $currentUserId : $mainContactId;
                        }
                    }
                    $mainRelationship->end_date = CRM_Utils_Date::isoToMysql($otherRelationship->end_date);
                    $mainRelationship->start_date = CRM_Utils_Date::isoToMysql($otherRelationship->start_date);
                    //avoid duplicate object.
                    if (!$mainRelationship->find(TRUE)) {
                        $mainRelationship->save();
                    }
                    $mainRelationship->free();
                    //get the other relationship ids to update end date.
                    if ($updateOtherRel) {
                        $otherRelationshipIds[$otherRelationship->id] = $otherRelationship->id;
                    }
                }
                $otherRelationship->free();
                //update other relationships end dates
                if (!empty($otherRelationshipIds)) {
                    $sql = 'UPDATE  civicrm_relationship
                               SET  end_date = CURDATE()
                             WHERE  id IN ( ' . implode(',', $otherRelationshipIds) . ')';
                    CRM_Core_DAO::executeQuery($sql);
                }
            }
            //move other case to trash.
            $mergeCase = self::deleteCase($otherCaseId, $moveToTrash);
            if (!$mergeCase) {
                continue;
            }
            $mergeActSubject = $mergeActSubjectDetails = $mergeActType = '';
            if ($changeClient) {
                $mainContactDisplayName = CRM_Contact_BAO_Contact::displayName($mainContactId);
                $otherContactDisplayName = CRM_Contact_BAO_Contact::displayName($otherContactId);
                $mergeActType = array_search('Reassigned Case', $activityTypes);
                $mergeActSubject = ts("Case %1 reassigned client from %2 to %3. New Case ID is %4.", array(1 => $otherCaseId, 2 => $otherContactDisplayName, 3 => $mainContactDisplayName, 4 => $mainCaseId));
            } elseif ($duplicateContacts) {
                $mergeActType = array_search('Merge Case', $activityTypes);
                $mergeActSubject = ts("Case %1 copied from contact id %2 to contact id %3 via merge. New Case ID is %4.", array(1 => $otherCaseId, 2 => $otherContactId, 3 => $mainContactId, 4 => $mainCaseId));
            } else {
                $mergeActType = array_search('Merge Case', $activityTypes);
                $mergeActSubject = ts("Case %1 merged into case %2", array(1 => $otherCaseId, 2 => $mainCaseId));
                if (!empty($copiedActivityIds)) {
                    $sql = '
SELECT id, subject, activity_date_time, activity_type_id
FROM civicrm_activity
WHERE id IN (' . implode(',', $copiedActivityIds) . ')';
                    $dao = CRM_Core_DAO::executeQuery($sql);
                    while ($dao->fetch()) {
                        $mergeActSubjectDetails .= "{$dao->activity_date_time} :: {$activityTypes[$dao->activity_type_id]}";
                        if ($dao->subject) {
                            $mergeActSubjectDetails .= " :: {$dao->subject}";
                        }
                        $mergeActSubjectDetails .= "<br />";
                    }
                }
            }
            //create merge activity record.
            $activityParams = array('subject' => $mergeActSubject, 'details' => $mergeActSubjectDetails, 'status_id' => array_search('Completed', $activityStatuses), 'activity_type_id' => $mergeActType, 'source_contact_id' => $mainContactId, 'activity_date_time' => date('YmdHis'));
            $mergeActivity = CRM_Activity_BAO_Activity::create($activityParams);
            $mergeActivityId = $mergeActivity->id;
            if (!$mergeActivityId) {
                continue;
            }
            $mergeActivity->free();
            //connect merge activity to case.
            $mergeCaseAct = array('case_id' => $mainCaseId, 'activity_id' => $mergeActivityId);
            self::processCaseActivity($mergeCaseAct);
        }
        CRM_Utils_Hook::post_case_merge($mainContactId, $mainCaseId, $otherContactId, $otherCaseId, $changeClient);
        return $mainCaseIds;
    }