Skip to content

Commit

Permalink
[REF] Simplify error handling
Browse files Browse the repository at this point in the history
Update CRM/Contribute/Import/Parser/Contribution.php

Co-authored-by: Seamus Lee <seamuslee001@gmail.com>
  • Loading branch information
eileenmcnaughton and seamuslee001 committed Aug 23, 2022
1 parent 8a50133 commit be79c37
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 67 deletions.
12 changes: 1 addition & 11 deletions CRM/Contact/Import/Parser/Contact.php
Original file line number Diff line number Diff line change
Expand Up @@ -1710,17 +1710,7 @@ protected function lookupContactID(array $params, bool $isMainContact): ?int {
throw new CRM_Core_Exception(ts('External ID already exists in Database.'), CRM_Import_Parser::DUPLICATE);
}
if ($contactID) {
$existingContact = Contact::get(FALSE)
->addWhere('id', '=', $contactID)
// Don't auto-filter deleted - people use import to undelete.
->addWhere('is_deleted', 'IN', [0, 1])
->addSelect('contact_type')->execute()->first();
if (empty($existingContact['id'])) {
throw new CRM_Core_Exception('No contact found for this contact ID:' . $params['id'], CRM_Import_Parser::NO_MATCH);
}
if ($existingContact['contact_type'] !== $params['contact_type']) {
throw new CRM_Core_Exception('Mismatched contact Types', CRM_Import_Parser::NO_MATCH);
}
$this->validateContactID($contactID, $params['contact_type']);
return $contactID;
}
// Time to see if we can find an existing contact ID to make this an update
Expand Down
76 changes: 20 additions & 56 deletions CRM/Contribute/Import/Parser/Contribution.php
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ public function init() {
/**
* Set field metadata.
*/
protected function setFieldMetadata() {
protected function setFieldMetadata(): void {
if (empty($this->importableFieldsMetadata)) {
$fields = $this->importableFields($this->getContactType());

Expand Down Expand Up @@ -311,6 +311,9 @@ public function import($values): void {
$rowNumber = (int) ($values[array_key_last($values)]);
try {
$params = $this->getMappedRow($values);
if (!empty($params['contact_id'])) {
$this->validateContactID($params['contact_id'], $this->getContactType());
}
$formatted = array_merge(['version' => 3, 'skipRecentView' => TRUE, 'skipCleanMoney' => TRUE, 'contribution_id' => $params['id'] ?? NULL], $params);
//CRM-10994
if (isset($params['total_amount']) && $params['total_amount'] == 0) {
Expand Down Expand Up @@ -340,17 +343,7 @@ public function import($values): void {
$paramValues['contact_type'] = $this->getContactType();
}

$formatError = $this->deprecatedFormatParams($paramValues, $formatted);

if ($formatError) {
if (CRM_Utils_Array::value('error_data', $formatError) == 'soft_credit') {
throw new CRM_Core_Exception('', self::SOFT_CREDIT_ERROR);
}
if (CRM_Utils_Array::value('error_data', $formatError) == 'pledge_payment') {
throw new CRM_Core_Exception('', self::PLEDGE_PAYMENT_ERROR);
}
throw new CRM_Core_Exception('', CRM_Import_Parser::ERROR);
}
$this->deprecatedFormatParams($paramValues, $formatted);

if ($this->isUpdateExisting()) {
//fix for CRM-2219 - Update Contribution
Expand Down Expand Up @@ -611,10 +604,9 @@ public function &getImportedContributions() {
* The reformatted properties that we can use internally.
* @param bool $create
*
* @return array|CRM_Error
* @throws \CRM_Core_Exception
*/
private function deprecatedFormatParams($params, &$values, $create = FALSE) {
private function deprecatedFormatParams($params, &$values, $create = FALSE): void {
// copy all the contribution fields as is
require_once 'api/v3/utils.php';

Expand All @@ -625,23 +617,6 @@ private function deprecatedFormatParams($params, &$values, $create = FALSE) {
}

switch ($key) {
case 'contact_id':
if (!CRM_Utils_Rule::integer($value)) {
return civicrm_api3_create_error("contact_id not valid: $value");
}
$dao = new CRM_Core_DAO();
$qParams = [];
$svq = $dao->singleValueQuery("SELECT is_deleted FROM civicrm_contact WHERE id = $value",
$qParams
);
if (!isset($svq)) {
return civicrm_api3_create_error("Invalid Contact ID: There is no contact record with contact_id = $value.");
}
elseif ($svq == 1) {
return civicrm_api3_create_error("Invalid Contact ID: contact_id $value is a soft-deleted contact.");
}
$values['contact_id'] = $value;
break;

case 'contact_type':
// import contribution record according to select contact type
Expand All @@ -656,13 +631,13 @@ private function deprecatedFormatParams($params, &$values, $create = FALSE) {
$contactType->external_identifier = $externalId;
if ($contactType->find(TRUE)) {
if ($params['contact_type'] != $contactType->contact_type) {
return civicrm_api3_create_error("Contact Type is wrong: $contactType->contact_type");
throw new CRM_Core_Exception("Contact Type is wrong: $contactType->contact_type", CRM_Import_Parser::ERROR);
}
}
}
elseif ($email) {
if (!CRM_Utils_Rule::email($email)) {
return civicrm_api3_create_error("Invalid email address $email provided. Row was skipped");
throw new CRM_Core_Exception("Invalid email address $email provided. Row was skipped", CRM_Import_Parser::ERROR);
}

// get the contact id from duplicate contact rule, if more than one contact is returned
Expand All @@ -687,11 +662,11 @@ private function deprecatedFormatParams($params, &$values, $create = FALSE) {
$checkDedupe = ['is_error' => 0];
}
if (!$checkDedupe['is_error']) {
return civicrm_api3_create_error("Invalid email address(doesn't exist) $email. Row was skipped");
throw new CRM_Core_Exception("Invalid email address(doesn't exist) $email. Row was skipped", CRM_Import_Parser::ERROR);
}
$matchingContactIds = explode(',', $checkDedupe['error_message']['params'][0]);
if (count($matchingContactIds) > 1) {
return civicrm_api3_create_error("Invalid email address(duplicate) $email. Row was skipped");
throw new CRM_Core_Exception("Invalid email address(duplicate) $email. Row was skipped", CRM_Import_Parser::ERROR);
}
if (count($matchingContactIds) == 1) {
$params['contribution_contact_id'] = $matchingContactIds[0];
Expand All @@ -714,14 +689,14 @@ private function deprecatedFormatParams($params, &$values, $create = FALSE) {
$contactType->id = $contactId->contact_id;
if ($contactType->find(TRUE)) {
if ($params['contact_type'] != $contactType->contact_type) {
return civicrm_api3_create_error("Contact Type is wrong: $contactType->contact_type");
throw new CRM_Core_Exception("Contact Type is wrong: $contactType->contact_type", CRM_Import_Parser::ERROR);
}
}
}
}
else {
if ($this->isUpdateExisting()) {
return civicrm_api3_create_error("Empty Contribution and Invoice and Transaction ID. Row was skipped.");
throw new CRM_Core_Exception('Empty Contribution and Invoice and Transaction ID. Row was skipped.', CRM_Import_Parser::ERROR);
}
}
break;
Expand Down Expand Up @@ -765,7 +740,7 @@ private function deprecatedFormatParams($params, &$values, $create = FALSE) {
}
}
else {
throw new CRM_Core_Exception('No match found for specified contact in pledge payment data. Row was skipped.');
throw new CRM_Core_Exception('No match found for specified contact in pledge payment data. Row was skipped.', CRM_Import_Parser::ERROR);
}
}
else {
Expand All @@ -781,7 +756,7 @@ private function deprecatedFormatParams($params, &$values, $create = FALSE) {
$contributionContactID = $params['contribution_contact_id'] = $values['contribution_contact_id'] = $contact->id;
}
else {
return civicrm_api3_create_error('No match found for specified contact in pledge payment data. Row was skipped.');
throw new CRM_Core_Exception('No match found for specified contact in pledge payment data. Row was skipped.');
}
}
else {
Expand All @@ -793,19 +768,19 @@ private function deprecatedFormatParams($params, &$values, $create = FALSE) {

// check if only one contact is found
if (count($matchedIDs) > 1) {
return civicrm_api3_create_error($error['error_message']['message']);
throw new CRM_Core_Exception($error['error_message']['message'], CRM_Import_Parser::ERROR);
}
$contributionContactID = $params['contribution_contact_id'] = $values['contribution_contact_id'] = $matchedIDs[0];
}
else {
return civicrm_api3_create_error('No match found for specified contact in contribution data. Row was skipped.');
throw new CRM_Core_Exception('No match found for specified contact in contribution data. Row was skipped.', CRM_Import_Parser::ERROR);
}
}
}

if (!empty($params['pledge_id'])) {
if (CRM_Core_DAO::getFieldValue('CRM_Pledge_DAO_Pledge', $params['pledge_id'], 'contact_id') != $contributionContactID) {
return civicrm_api3_create_error('Invalid Pledge ID provided. Contribution row was skipped.');
throw new CRM_Core_Exception('Invalid Pledge ID provided. Contribution row was skipped.', CRM_Import_Parser::ERROR);
}
$values['pledge_id'] = $params['pledge_id'];
}
Expand All @@ -815,10 +790,10 @@ private function deprecatedFormatParams($params, &$values, $create = FALSE) {
$pledgeDetails = CRM_Pledge_BAO_Pledge::getContactPledges($contributionContactID);

if (empty($pledgeDetails)) {
return civicrm_api3_create_error('No open pledges found for this contact. Contribution row was skipped.');
throw new CRM_Core_Exception('No open pledges found for this contact. Contribution row was skipped.', CRM_Import_Parser::ERROR);
}
if (count($pledgeDetails) > 1) {
return civicrm_api3_create_error('This contact has more than one open pledge. Unable to determine which pledge to apply the contribution to. Contribution row was skipped.');
throw new CRM_Core_Exception('This contact has more than one open pledge. Unable to determine which pledge to apply the contribution to. Contribution row was skipped.', CRM_Import_Parser::ERROR);
}

// this mean we have only one pending / in progress pledge
Expand All @@ -833,15 +808,8 @@ private function deprecatedFormatParams($params, &$values, $create = FALSE) {
$values['pledge_payment_id'] = $pledgePaymentDetails['id'];
}
else {
return civicrm_api3_create_error('Contribution and Pledge Payment amount mismatch for this record. Contribution row was skipped.');
}
break;

case 'contribution_campaign_id':
if (empty(CRM_Core_DAO::getFieldValue('CRM_Campaign_DAO_Campaign', $params['contribution_campaign_id']))) {
return civicrm_api3_create_error('Invalid Campaign ID provided. Contribution row was skipped.');
throw new CRM_Core_Exception('Contribution and Pledge Payment amount mismatch for this record. Contribution row was skipped.', CRM_Import_Parser::ERROR);
}
$values['contribution_campaign_id'] = $params['contribution_campaign_id'];
break;

}
Expand All @@ -863,8 +831,6 @@ private function deprecatedFormatParams($params, &$values, $create = FALSE) {
}
}
}

return NULL;
}

/**
Expand All @@ -879,7 +845,6 @@ private function deprecatedFormatParams($params, &$values, $create = FALSE) {
* @param int $columnNumber
*
* @return array
* @throws \API_Exception
*/
public function getMappingFieldFromMapperInput(array $fieldMapping, int $mappingID, int $columnNumber): array {
return [
Expand Down Expand Up @@ -954,7 +919,6 @@ private function lookupMatchingContact(array $params): int {
* or as returned from getMappingFieldFromMapperInput
*
* @return string
* @throws \API_Exception
*/
public function getMappedFieldLabel(array $mappedField): string {
if (empty($this->importableFieldsMetadata)) {
Expand Down
23 changes: 23 additions & 0 deletions CRM/Import/Parser.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
*/

use Civi\Api4\Campaign;
use Civi\Api4\Contact;
use Civi\Api4\CustomField;
use Civi\Api4\Event;
use Civi\Api4\UserJob;
Expand Down Expand Up @@ -730,6 +731,28 @@ public static function errorFileName($type) {
return $fileName;
}

/**
* Validate that a passed in contact ID is for an existing, not-deleted contact.
*
* @param int $contactID
* @param string|null $contactType
*
* @throws \CRM_Core_Exception
*/
protected function validateContactID(int $contactID, ?string $contactType): void {
$existingContact = Contact::get(FALSE)
->addWhere('id', '=', $contactID)
// Don't auto-filter deleted - people use import to undelete.
->addWhere('is_deleted', 'IN', [0, 1])
->addSelect('contact_type')->execute()->first();
if (empty($existingContact['id'])) {
throw new CRM_Core_Exception('No contact found for this contact ID:' . $contactID, CRM_Import_Parser::NO_MATCH);
}
if ($contactType && $existingContact['contact_type'] !== $contactType) {
throw new CRM_Core_Exception('Mismatched contact Types', CRM_Import_Parser::NO_MATCH);
}
}

/**
* Determines the file name based on error code.
*
Expand Down

0 comments on commit be79c37

Please sign in to comment.