Skip to content

Commit

Permalink
refs #40812, backer additional contact now will use dedupe and add
Browse files Browse the repository at this point in the history
email/phone/addr to same contact found
  • Loading branch information
jimyhuang committed Jul 25, 2024
1 parent 573015a commit be34139
Show file tree
Hide file tree
Showing 2 changed files with 191 additions and 80 deletions.
157 changes: 85 additions & 72 deletions CRM/Core/Payment/Backer.php
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,6 @@ function processContribution($jsonString, &$contributionResult) {
civicrm_api('contact', 'create', $contact);
}

// process recurring or contribution
if ($contactId) {
$contributionResult['contactId'] = $contactId;
// create additional contact if needed
Expand Down Expand Up @@ -340,49 +339,66 @@ function processContribution($jsonString, &$contributionResult) {
sort($foundDupes);
$additionalContactId = reset($foundDupes);
}
else {
$dedupeParams = array(
'last_name' => $params['additional']['last_name'],
'first_name' => $params['additional']['first_name'],
);
$dedupeParams = CRM_Dedupe_Finder::formatParams($dedupeParams, 'Individual');
$foundDupes = CRM_Dedupe_Finder::dupesByRules(
$dedupeParams,
'Individual',
'Strict',
array(),
array(
array('table' => 'civicrm_contact', 'field' => 'sort_name', 'weight' => 10),
),
10
);
}
if ($additionalContactId) {
$params['additional']['id'] = $additionalContactId;
// only process address
$otherLocationTypeId = array_search('Other', $locationType);
$addContact = array();

// check addr exists
$blockValue = $params['additional']['address'][0];
$blockValue['contact_id'] = $additionalContactId;
CRM_Core_BAO_Address::valueExists($blockValue);
if (empty($blockValue['id'])) {
$otherLocationTypeId = array_search('Other', $locationType);
$billingLocationTypeId = array_search('Billing', $locationType);
if ($otherLocationTypeId && $billingLocationTypeId) {
$existsBillingAddr = CRM_Core_DAO::singleValueQuery("SELECT id FROM civicrm_address WHERE location_type_id = '$billingLocationTypeId' AND contact_id = %1", array(
if ($otherLocationTypeId) {
$existsAddr = CRM_Core_DAO::singleValueQuery("SELECT id FROM civicrm_address WHERE contact_id = %1", array(
1 => array($additionalContactId, 'Integer')
));
if ($existsAddr) {
$params['additional']['address'][0]['location_type_id'] = $otherLocationTypeId;
}
}
$addContact['address'] = $params['additional']['address'];
}

// check phone exists
$blockValue = $params['additional']['phone'][0];
$blockValue['contact_id'] = $additionalContactId;
CRM_Core_BAO_Phone::valueExists($blockValue);
if (empty($blockValue['id'])) {
if ($otherLocationTypeId) {
$existsPhone = CRM_Core_DAO::singleValueQuery("SELECT id FROM civicrm_phone WHERE contact_id = %1", array(
1 => array($additionalContactId, 'Integer')
));
if ($existsPhone) {
$params['additional']['phone'][0]['location_type_id'] = $otherLocationTypeId;
$params['additional']['phone'][0]['is_primary'] = 0;
}
}
$addContact['phone'] = $params['additional']['phone'];
}

// check email exists
$blockValue = $params['additional']['email'][0];
$blockValue['contact_id'] = $additionalContactId;
CRM_Core_BAO_Email::valueExists($blockValue);
if (empty($blockValue['id'])) {
if ($otherLocationTypeId) {
$existsEmail = CRM_Core_DAO::singleValueQuery("SELECT id FROM civicrm_email WHERE contact_id = %1", array(
1 => array($additionalContactId, 'Integer')
));
if ($existsBillingAddr) {
CRM_Core_DAO::executeQuery("UPDATE civicrm_address SET location_type_id = '$otherLocationTypeId' WHERE id = %1", array(
1 => array($existsBillingAddr, 'Integer')
));
if ($existsEmail) {
$params['additional']['email'][0]['location_type_id'] = $otherLocationTypeId;
$params['additional']['email'][0]['is_primary'] = 0;
}
}
$addContact = array(
'version' => 3,
'id' => $additionalContactId,
'address' => $params['additional']['address'],
'log_data' => ts('Updated contact').'-'.ts('Backer Auto Import'),
);
// log exists
$addContact['email'] = $params['additional']['email'];
}

// only update contact when value different
if (!empty($addContact)) {
$addContact['id'] = $additionalContactId;
$addContact['version'] = 3;
$addContact['log_data'] = ts('Updated contact').'-'.ts('Backer Auto Import');
civicrm_api('contact', 'create', $addContact);
}
}
Expand All @@ -394,7 +410,7 @@ function processContribution($jsonString, &$contributionResult) {
$additionalContactId = $result['id'];
}

if ($additionalContactId) {
if ($additionalContactId && $additionalContactId != $contactId) {
$addContactParams = array(
'version' => 3,
'contact_id_a' => $contactId,
Expand Down Expand Up @@ -578,6 +594,9 @@ public static function formatContact($json, &$params) {
2 => array($countryId, 'Integer'),
));
}

// #40812#note-10 , do not remove recipient data in form data stage
$params['additional'] = array();
$address = array(
'country' => ($json['recipient']['recipient_country'] == 'TW') ? 'Taiwan' : '',
'postal_code' => $json['recipient']['recipient_postal_code'] ? $json['recipient']['recipient_postal_code'] : '',
Expand All @@ -586,47 +605,41 @@ public static function formatContact($json, &$params) {
'street_address' => $json['recipient']['recipient_address'] ? $json['recipient']['recipient_address'] : '',
'location_type_id' => array_search('Home', $locationType),
);
if (trim($json['recipient']['recipient_name']) == trim($json['user']['name'])) {
$params['address'][] = $address;
$addName = self::explodeName(trim($json['recipient']['recipient_name']));
if ($addName === FALSE) {
$addName= array(
'', // sure name
$json['recipient']['recipient_name'], // given name
);
}
else {
$params['additional'] = array();
$addName = self::explodeName(trim($json['recipient']['recipient_name']));
if ($addName === FALSE) {
$addName= array(
'', // sure name
$json['recipient']['recipient_name'], // given name
);
}
$params['additional'] = array(
'contact_type' => 'Individual',
'last_name' => $addName[0],
'first_name' => $addName[1],
$params['additional'] = array(
'contact_type' => 'Individual',
'last_name' => $addName[0],
'first_name' => $addName[1],
);
if ($json['recipient']['recipient_contact_email'] && CRM_Utils_Rule::email(trim($json['recipient']['recipient_contact_email']))) {
$params['additional']['email'][0] = array(
'email' => trim($json['recipient']['recipient_contact_email']),
'location_type_id' => array_search('Home', $locationType),
'is_primary' => 1,
'append' => TRUE,
);
if ($json['recipient']['recipient_contact_email'] && CRM_Utils_Rule::email(trim($json['recipient']['recipient_contact_email']))) {
$params['additional']['email'][0] = array(
'email' => trim($json['recipient']['recipient_contact_email']),
'location_type_id' => array_search('Home', $locationType),
'is_primary' => 1,
'append' => TRUE,
);
}
if (!empty($json['recipient']['recipient_cellphone'])) {
$params['additional']['phone'][0] = array(
'phone' => trim($json['recipient']['recipient_cellphone']),
'phone_type_id' => 5, // other
'location_type_id' => array_search('Home', $locationType),
'is_primary' => 1,
'append' => TRUE,
);
$addPhone = self::validateMobilePhone(trim($json['recipient']['recipient_cellphone']));
if ($addPhone) {
$params['additional']['phone'][0]['phone_type_id'] = 2;
$params['additional']['phone'][0]['phone'] = $addPhone;
}
}
if (!empty($json['recipient']['recipient_cellphone'])) {
$params['additional']['phone'][0] = array(
'phone' => trim($json['recipient']['recipient_cellphone']),
'phone_type_id' => 5, // other
'location_type_id' => array_search('Home', $locationType),
'is_primary' => 1,
'append' => TRUE,
);
$addPhone = self::validateMobilePhone(trim($json['recipient']['recipient_cellphone']));
if ($addPhone) {
$params['additional']['phone'][0]['phone_type_id'] = 2;
$params['additional']['phone'][0]['phone'] = $addPhone;
}
$params['additional']['address'][0] = $address;
}
$params['additional']['address'][0] = $address;
}

public static function formatRecurring($json, &$params) {
Expand Down
114 changes: 106 additions & 8 deletions tests/phpunit/CRM/Core/Payment/BackerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -536,20 +536,26 @@ function testBackerIPN(){
$this->assertEquals($formatted['phone'][0]['phone'], $result['values'][$result['id']]['phone']);
}

function testBackerAdditionAddress(){
function testBackerAdditionalContact(){
$now = time();
$contributionResult = NULL;

// prepare data
// case 1, this should create additional contact
$json = json_decode($this->_json[1], TRUE);
$json['recipient']['recipient_name'] = '王小明';
$json['transaction']['trade_no'] = CRM_Utils_String::createRandom(15);
$json['user']['id'] = mt_rand(100000, 999999);
$json['user']['email'] = '[email protected]';
$json['user']['name'] = '張小弟';
$json['user']['cellphone'] = '+886912445667';
$json['recipient']['recipient_name'] = '張大媽';
$json['recipient']['recipient_contact_email'] = '[email protected]';
$json['recipient']['recipient_cellphone'] = '0933444555';
$json = json_encode($json);
$formatted = CRM_Core_Payment_Backer::formatParams($json);

// run
$createdContributionId = $this->_processor->processContribution($json, $contributionResult);
$this->_processor->processContribution($json, $contributionResult);
$createdContributionId = $contributionResult['contributionId'];
$this->assertNotEmpty($createdContributionId, "In line " . __LINE__);
$this->assertNotEmpty($createdContributionId, "Contribution not created. In line " . __LINE__);
$contactId = CRM_Core_DAO::getFieldValue('CRM_Contribute_DAO_Contribution', $createdContributionId, 'contact_id');

$params = array(
Expand All @@ -561,18 +567,110 @@ function testBackerAdditionAddress(){
$this->assertAPISuccess($result);
$this->assertGreaterThan(0 , $result['count'], 'Additional contact count should greater than zero. In line '.__LINE__);
$additionalContact = reset($result['values']);
$additionalContactId = $additionalContact['contact_id'];
$additionalContactId1 = $additionalContact['contact_id'];
$this->assertEquals($formatted['additional']['address'][0]['street_address'], $additionalContact['street_address']);
$this->assertEquals($formatted['additional']['phone'][0]['phone'], $additionalContact['phone']);
$this->assertEquals($formatted['additional']['email'][0]['email'], $additionalContact['email']);

$params = array(
'version' => 3,
'contact_id_a' => $contactId,
'contact_id_b' => $additionalContactId,
'contact_id_b' => $additionalContactId1,
'relationship_type_id' => $this->_rtypeId,
);
$relation = civicrm_api('contact', 'get', $params);
$this->assertAPISuccess($relation);
$this->assertGreaterThan(0 , $relation['count'], 'Relationship result should greater than zero. In line '.__LINE__);

// duplicate case 1, won't add another contact
$formatted = CRM_Core_Payment_Backer::formatParams($json);
$this->_processor->processContribution($json, $contributionResult);
$params = array(
'version' => 3,
'last_name' => $formatted['additional']['last_name'],
'first_name' => $formatted['additional']['first_name'],
);
$result = civicrm_api('contact', 'get', $params);
$this->assertAPISuccess($result);
$this->assertEquals(1 , $result['count'], 'Additional contact count should be 1. In line '.__LINE__);

$params = array(
'version' => 3,
'last_name' => $formatted['additional']['last_name'],
'first_name' => $formatted['additional']['first_name'],
);
$result = civicrm_api('contact', 'get', $params);
$this->assertAPISuccess($result);
$this->assertGreaterThan(0 , $result['count'], 'Additional contact count should greater than zero. In line '.__LINE__);
$additionalContact = reset($result['values']);
$additionalContactId1 = $additionalContact['contact_id'];
$this->assertEquals($formatted['additional']['address'][0]['street_address'], $additionalContact['street_address']);
$this->assertEquals($formatted['additional']['phone'][0]['phone'], $additionalContact['phone']);
$this->assertEquals($formatted['additional']['email'][0]['email'], $additionalContact['email']);

// case 2, additional contact shouldn't be create again when missing email
$json = json_decode($this->_json[1], TRUE);
$json['transaction']['trade_no'] = CRM_Utils_String::createRandom(15);
$json['user']['id'] = mt_rand(100000, 999999);
$json['user']['email'] = '[email protected]';
$json['user']['name'] = '陳小刀';
$json['user']['cellphone'] = '+886900111222';
$json['recipient']['recipient_name'] = '陳小刀';
unset($json['recipient']['recipient_contact_email']);
$json['recipient']['recipient_cellphone'] = '0900111222';
$json = json_encode($json);
$formatted = CRM_Core_Payment_Backer::formatParams($json);

$contributionResult = NULL;
$this->_processor->processContribution($json, $contributionResult);
$createdContributionId = $contributionResult['contributionId'];
$this->assertNotEmpty($createdContributionId, "Contribution not created. In line " . __LINE__);
$contactId = CRM_Core_DAO::getFieldValue('CRM_Contribute_DAO_Contribution', $createdContributionId, 'contact_id');

$params = array(
'version' => 3,
'last_name' => $formatted['additional']['last_name'],
'first_name' => $formatted['additional']['first_name'],
);
$result = civicrm_api('contact', 'get', $params);
$this->assertAPISuccess($result);
$this->assertEquals(1 , $result['count'], 'Additional contact count should be only 1. In line '.__LINE__);
$additionalContact = reset($result['values']);
$additionalContactId2 = $additionalContact['contact_id'];
$this->assertEquals($additionalContactId2, $contactId, 'Additional contact should be same contact as previous after dedupe. In line '.__LINE__);
$blockValue = $formatted['additional']['address'][0];
$blockValue['contact_id'] = $contactId;
CRM_Core_BAO_Address::valueExists($blockValue);
$this->assertNotEmpty($blockValue['id'], "Additional address should be added to same contact. In line " . __LINE__);

// case 3, this should dupe original contact, no additional contact should be created
$json = json_decode($this->_json[1], TRUE);
$json['transaction']['trade_no'] = CRM_Utils_String::createRandom(15);
$json['user']['id'] = mt_rand(100000, 999999);
$json['user']['email'] = '[email protected]';
$json['user']['name'] = '陳未增';
$json['user']['cellphone'] = '+886966777888';
$json['recipient']['recipient_name'] = '陳未增';
$json['recipient']['recipient_contact_email'] = '[email protected]';
$json['recipient']['recipient_cellphone'] = '0977777888';
$json = json_encode($json);
$formatted = CRM_Core_Payment_Backer::formatParams($json);

$contributionResult = NULL;
$createdContributionId = $this->_processor->processContribution($json, $contributionResult);
$createdContributionId = $contributionResult['contributionId'];
$this->assertNotEmpty($createdContributionId, "Contribution not created. In line " . __LINE__);
$contactId = CRM_Core_DAO::getFieldValue('CRM_Contribute_DAO_Contribution', $createdContributionId, 'contact_id');

$blockValue = $formatted['additional']['address'][0];
$blockValue['contact_id'] = $contactId;
CRM_Core_BAO_Address::valueExists($blockValue);
$this->assertNotEmpty($blockValue['id'], "Additional address should be added to same contact. In line " . __LINE__);

$blockValue = $formatted['additional']['phone'][0];
$blockValue['contact_id'] = $contactId;
CRM_Core_BAO_Phone::valueExists($blockValue);
$this->assertNotEmpty($blockValue['id'], "Additional phone should be added to same contact. In line " . __LINE__);
}

function testBackerReceiptNew(){
Expand Down

0 comments on commit be34139

Please sign in to comment.