*/
use Civi\Api4\Contact;
+use Civi\Api4\Relationship;
/**
*
CRM_Core_Error::deprecatedWarning('attempting to create an employer with invalid contact types is deprecated');
return;
}
+
$relationshipIds = [];
- $duplicate = CRM_Contact_BAO_Relationship::checkDuplicateRelationship(
- [
- 'contact_id_a' => $contactID,
- 'contact_id_b' => $employerID,
- 'relationship_type_id' => $relationshipTypeID,
- ],
- $contactID,
- $employerID
- );
- if (!$duplicate) {
+ $ids = [];
+ $action = CRM_Core_Action::ADD;
+ $existingRelationship = Relationship::get(FALSE)
+ ->setWhere([
+ ['contact_id_a', '=', $contactID],
+ ['contact_id_b', '=', $employerID],
+ ['OR', [['start_date', '<=', 'now'], ['start_date', 'IS EMPTY']]],
+ ['OR', [['end_date', '>=', 'now'], ['end_date', 'IS EMPTY']]],
+ ['relationship_type_id', '=', $relationshipTypeID],
+ ['is_active', 'IN', [0, 1]],
+ ])
+ ->setSelect(['id', 'is_active', 'start_date', 'end_date', 'contact_id_a.employer_id'])
+ ->addOrderBy('is_active', 'DESC')
+ ->setLimit(1)
+ ->execute()->first();
+
+ if (!empty($existingRelationship)) {
+ if ($existingRelationship['is_active']) {
+ // My work here is done.
+ return;
+ }
+
+ $action = CRM_Core_Action::UPDATE;
+ // No idea why we set these ids but it's either legacy cruft or used by `relatedMemberships`
+ $ids['contact'] = $contactID;
+ $ids['contactTarget'] = $employerID;
+ $ids['relationship'] = $existingRelationship['id'];
+ CRM_Contact_BAO_Relationship::setIsActive($existingRelationship['id'], TRUE);
+ }
+ else {
$params = [
'is_active' => TRUE,
'contact_check' => [$employerID => TRUE],
// set current employer
self::setCurrentEmployer([$contactID => $employerID]);
- $ids = [];
- $action = CRM_Core_Action::ADD;
-
- //we do not know that triggered relationship record is active.
- if ($duplicate) {
- $relationship = new CRM_Contact_DAO_Relationship();
- $relationship->contact_id_a = $contactID;
- $relationship->contact_id_b = $employerID;
- $relationship->relationship_type_id = $relationshipTypeID;
- if ($relationship->find(TRUE)) {
- $action = CRM_Core_Action::UPDATE;
- $ids['contact'] = $contactID;
- $ids['contactTarget'] = $employerID;
- $ids['relationship'] = $relationship->id;
- CRM_Contact_BAO_Relationship::setIsActive($relationship->id, TRUE);
- }
- }
-
//need to handle related memberships. CRM-3792
+ // @todo - this probably duplicates the work done in the setIsActive
+ // for duplicates...
if ($previousEmployerID != $employerID) {
CRM_Contact_BAO_Relationship::relatedMemberships($contactID, [
'relationship_ids' => $relationshipIds,
*/
class CRM_Dedupe_MergerTest extends CiviUnitTestCase {
+ use CRMTraits_Custom_CustomDataTrait;
+
protected $_groupId;
protected $_contactIds = [];
$this->callAPISuccess('Contact', 'merge', ['to_keep_id' => $contact1, 'to_remove_id' => $contact2]);
}
+ /**
+ * Test that a custom field attached to the relationship does not block merge.
+ *
+ * @throws \CRM_Core_Exception
+ */
+ public function testMergeWithRelationshipWithCustomFields(): void {
+ $contact1 = $this->individualCreate();
+ $this->createCustomGroupWithFieldsOfAllTypes(['extends' => 'Relationship']);
+ $contact2 = $this->createContactWithEmployerRelationship([
+ $this->getCustomFieldName('text') => 'blah',
+ $this->getCustomFieldName('boolean') => TRUE,
+ ]);
+ $this->callAPISuccess('Contact', 'merge', ['to_keep_id' => $contact1, 'to_remove_id' => $contact2]);
+ $this->callAPISuccessGetSingle('Relationship', [
+ 'contact_id_a' => $contact1,
+ ]);
+
+ $contact2 = $this->createContactWithEmployerRelationship([
+ $this->getCustomFieldName('boolean') => TRUE,
+ $this->getCustomFieldName('text') => '',
+ ]);
+ $this->callAPISuccess('Contact', 'merge', ['to_keep_id' => $contact2, 'to_remove_id' => $contact1]);
+ $this->callAPISuccessGetSingle('Relationship', [
+ 'contact_id_a' => $contact2,
+ ]);
+ }
+
/**
* Implements hook_civicrm_entityTypes().
*
$links[] = new CRM_Core_Reference_Basic('civicrm_im', 'name', 'civicrm_contact', 'first_name');
}
+ /**
+ * Create an individual with a relationship of type employee.
+ *
+ * @param array $params
+ *
+ * @return int
+ * @throws \CRM_Core_Exception
+ */
+ protected function createContactWithEmployerRelationship(array $params): int {
+ $contact2 = $this->individualCreate();
+ // Test the merge can also happen if the other contact has an empty text field.
+ $this->callAPISuccess('Relationship', 'create', array_merge([
+ 'contact_id_a' => $contact2,
+ 'contact_id_b' => CRM_Core_BAO_Domain::getDomain()->contact_id,
+ 'relationship_type_id' => 'Employee of',
+ 'is_current_employer' => TRUE,
+ ], $params));
+ return $contact2;
+ }
+
}