X-Git-Url: https://vcs.fsf.org/?a=blobdiff_plain;f=CRM%2FContribute%2FBAO%2FContribution.php;h=0508a7116d4871201ca0a2154d0a55221f497eac;hb=2b68a50cdab2028339d5689d0f03d8037e6a9703;hp=eaa08dfa1a0750ab764672a4338a8238ed6a9b04;hpb=d1b6e73b99eb1805d8a5f77afd3940c0d45eca06;p=civicrm-core.git diff --git a/CRM/Contribute/BAO/Contribution.php b/CRM/Contribute/BAO/Contribution.php index eaa08dfa1a..0508a7116d 100644 --- a/CRM/Contribute/BAO/Contribution.php +++ b/CRM/Contribute/BAO/Contribution.php @@ -134,9 +134,9 @@ class CRM_Contribute_BAO_Contribution extends CRM_Contribute_DAO_Contribution { CRM_Core_DAO::setCreateDefaults($params, self::getDefaults()); } + $contributionStatus = CRM_Contribute_PseudoConstant::contributionStatus(NULL, 'name'); //if contribution is created with cancelled or refunded status, add credit note id if (!empty($params['contribution_status_id'])) { - $contributionStatus = CRM_Contribute_PseudoConstant::contributionStatus(NULL, 'name'); // @todo - should we include Chargeback? If so use self::isContributionStatusNegative($params['contribution_status_id']) if (($params['contribution_status_id'] == array_search('Refunded', $contributionStatus) || $params['contribution_status_id'] == array_search('Cancelled', $contributionStatus)) @@ -212,8 +212,7 @@ class CRM_Contribute_BAO_Contribution extends CRM_Contribute_DAO_Contribution { ); } - // reset the group contact cache for this group - CRM_Contact_BAO_GroupContactCache::remove(); + CRM_Contact_BAO_GroupContactCache::opportunisticCacheFlush(); if ($contributionID) { CRM_Utils_Hook::post('edit', 'Contribution', $contribution->id, $contribution); @@ -541,16 +540,17 @@ class CRM_Contribute_BAO_Contribution extends CRM_Contribute_DAO_Contribution { 'Contribution', 'name' ); - if (!$activity->find(TRUE)) { - if (empty($contribution->contact_id)) { - $contribution->find(TRUE); - } - CRM_Activity_BAO_Activity::addActivity($contribution, 'Offline'); - } - else { + + //CRM-18406: Update activity when edit contribution. + if ($activity->find(TRUE)) { // CRM-13237 : if activity record found, update it with campaign id of contribution CRM_Core_DAO::setFieldValue('CRM_Activity_BAO_Activity', $activity->id, 'campaign_id', $contribution->campaign_id); + $contribution->activity_id = $activity->id; + } + if (empty($contribution->contact_id)) { + $contribution->find(TRUE); } + CRM_Activity_BAO_Activity::addActivity($contribution, 'Offline'); // do not add to recent items for import, CRM-4399 if (empty($params['skipRecentView'])) { @@ -1207,7 +1207,12 @@ GROUP BY p.id } /** - * Get list of contribution In Honor of contact Ids. + * Get list of contributions which credit the passed in contact ID. + * + * The returned array provides details about the original contribution & donor. + * + * @todo - this is a confusing function called from one place. It has a test. It would be + * nice to deprecate it. * * @param int $honorId * In Honor of Contact ID. @@ -2502,7 +2507,7 @@ INNER JOIN civicrm_activity ON civicrm_activity_contact.activity_id = civicrm_ac $membership_status = CRM_Member_PseudoConstant::membershipStatus($membership->status_id, NULL, 'label'); $template->assign('mem_status', $membership_status); if ($membership_status == 'Pending' && $membership->is_pay_later == 1) { - $template->assign('is_pay_later', 1); + $values['is_pay_later'] = 1; } // if separate payment there are two contributions recorded and the @@ -2552,8 +2557,18 @@ INNER JOIN civicrm_activity ON civicrm_activity_contact.activity_id = civicrm_ac $addressParams = array('id' => $this->address_id); $addressDetails = CRM_Core_BAO_Address::getValues($addressParams, FALSE, 'id'); $addressDetails = array_values($addressDetails); + } + // Else we assign the billing address of the contribution contact. + else { + $addressParams = array('contact_id' => $this->contact_id, 'is_billing' => 1); + $addressDetails = (array) CRM_Core_BAO_Address::getValues($addressParams); + $addressDetails = array_values($addressDetails); + } + + if (!empty($addressDetails[0]['display'])) { $values['address'] = $addressDetails[0]['display']; } + if ($this->_component == 'contribute') { //get soft contributions $softContributions = CRM_Contribute_BAO_ContributionSoft::getSoftContribution($this->id, TRUE); @@ -2561,10 +2576,7 @@ INNER JOIN civicrm_activity ON civicrm_activity_contact.activity_id = civicrm_ac $values['softContributions'] = $softContributions['soft_credit']; } if (isset($this->contribution_page_id)) { - CRM_Contribute_BAO_ContributionPage::setValues( - $this->contribution_page_id, - $values - ); + $values = $this->addContributionPageValuesToValuesHeavyHandedly($values); if ($this->contribution_page_id) { // CRM-8254 - override default currency if applicable $config = CRM_Core_Config::singleton(); @@ -2587,7 +2599,9 @@ INNER JOIN civicrm_activity ON civicrm_activity_contact.activity_id = civicrm_ac if (!empty($lineItem)) { $itemId = key($lineItem); foreach ($lineItem as &$eachItem) { - if (is_array($this->_relatedObjects['membership']) && array_key_exists($eachItem['membership_type_id'], $this->_relatedObjects['membership'])) { + if (isset($this->_relatedObjects['membership']) + && is_array($this->_relatedObjects['membership']) + && array_key_exists($eachItem['membership_type_id'], $this->_relatedObjects['membership'])) { $eachItem['join_date'] = CRM_Utils_Date::customFormat($this->_relatedObjects['membership'][$eachItem['membership_type_id']]->join_date); $eachItem['start_date'] = CRM_Utils_Date::customFormat($this->_relatedObjects['membership'][$eachItem['membership_type_id']]->start_date); $eachItem['end_date'] = CRM_Utils_Date::customFormat($this->_relatedObjects['membership'][$eachItem['membership_type_id']]->end_date); @@ -2825,6 +2839,7 @@ INNER JOIN civicrm_activity ON civicrm_activity_contact.activity_id = civicrm_ac $template->assign('receive_date', CRM_Utils_Date::processDate($this->receive_date) ); + $values['receipt_date'] = (empty($this->receipt_date) ? NULL : $this->receipt_date); $template->assign('contributeMode', 'notify'); $template->assign('action', $this->is_test ? 1024 : 1); $template->assign('receipt_text', @@ -3980,7 +3995,7 @@ WHERE eft.financial_trxn_id IN ({$trxnId}, {$baseTrxnId['financialTrxnId']}) SELECT GROUP_CONCAT(fa.`name`) as financial_account, ft.total_amount, ft.payment_instrument_id, - ft.trxn_date, ft.trxn_id, ft.status_id, ft.check_number + ft.trxn_date, ft.trxn_id, ft.status_id, ft.check_number, con.currency FROM civicrm_contribution con LEFT JOIN civicrm_entity_financial_trxn eft ON (eft.entity_id = con.id AND eft.entity_table = 'civicrm_contribution') @@ -4013,6 +4028,7 @@ WHERE eft.financial_trxn_id IN ({$trxnId}, {$baseTrxnId['financialTrxnId']}) 'receive_date' => $resultDAO->trxn_date, 'trxn_id' => $resultDAO->trxn_id, 'status' => $statuses[$resultDAO->status_id], + 'currency' => $resultDAO->currency, ); if ($paidByName == 'Check') { $val['check_number'] = $resultDAO->check_number; @@ -4344,6 +4360,7 @@ WHERE eft.financial_trxn_id IN ({$trxnId}, {$baseTrxnId['financialTrxnId']}) 'campaign_id', 'receive_date', 'receipt_date', + 'contribution_status_id', ); if (self::isSingleLineItem($primaryContributionID)) { $inputContributionWhiteList[] = 'financial_type_id'; @@ -4352,16 +4369,19 @@ WHERE eft.financial_trxn_id IN ({$trxnId}, {$baseTrxnId['financialTrxnId']}) $participant = CRM_Utils_Array::value('participant', $objects); $memberships = CRM_Utils_Array::value('membership', $objects); $recurContrib = CRM_Utils_Array::value('contributionRecur', $objects); + $recurringContributionID = (empty($recurContrib->id)) ? NULL : $recurContrib->id; $event = CRM_Utils_Array::value('event', $objects); + $completedContributionStatusID = CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'contribution_status_id', 'Completed'); + $contributionParams = array_merge(array( - 'contribution_status_id' => 'Completed', + 'contribution_status_id' => $completedContributionStatusID, 'source' => self::getRecurringContributionDescription($contribution, $event), ), array_intersect_key($input, array_fill_keys($inputContributionWhiteList, 1) )); - if (!empty($recurContrib->id)) { - $contributionParams['contribution_recur_id'] = $recurContrib->id; + if ($recurringContributionID) { + $contributionParams['contribution_recur_id'] = $recurringContributionID; } $changeDate = CRM_Utils_Array::value('trxn_date', $input, date('YmdHis')); @@ -4386,16 +4406,13 @@ WHERE eft.financial_trxn_id IN ({$trxnId}, {$baseTrxnId['financialTrxnId']}) // Figure out what we gain from this. CRM_Contribute_BAO_ContributionPage::setValues($contribution->contribution_page_id, $values); } - elseif ($recurContrib && $recurContrib->id) { + elseif ($recurContrib && $recurringContributionID) { $values['amount'] = $recurContrib->amount; $values['financial_type_id'] = $objects['contributionType']->id; $values['title'] = $source = ts('Offline Recurring Contribution'); - $domainValues = CRM_Core_BAO_Domain::getNameAndEmail(); - $values['receipt_from_name'] = $domainValues[0]; - $values['receipt_from_email'] = $domainValues[1]; } - if ($recurContrib && $recurContrib->id && !isset($input['is_email_receipt'])) { + if ($recurContrib && $recurringContributionID && !isset($input['is_email_receipt'])) { //CRM-13273 - is_email_receipt setting on recurring contribution should take precedence over contribution page setting // but CRM-16124 if $input['is_email_receipt'] is set then that should not be overridden. $values['is_email_receipt'] = $recurContrib->is_email_receipt; @@ -4491,7 +4508,7 @@ LIMIT 1;"; $contributionParams['id'] = $contribution->id; - civicrm_api3('Contribution', 'create', $contributionParams); + $contributionResult = civicrm_api3('Contribution', 'create', $contributionParams); // Add new soft credit against current $contribution. if (CRM_Utils_Array::value('contributionRecur', $objects) && $objects['contributionRecur']->id) { @@ -4524,11 +4541,11 @@ LIMIT 1;"; elseif (!empty($contribution->_relatedObjects['membership'])) { $input['skipLineItem'] = TRUE; $input['contribution_mode'] = 'membership'; - $contribution->contribution_status_id = $contributionStatuses['Completed']; + $contribution->contribution_status_id = $contributionParams['contribution_status_id']; $contribution->trxn_id = CRM_Utils_Array::value('trxn_id', $input); $contribution->receive_date = CRM_Utils_Date::isoToMysql($contribution->receive_date); } - $input['contribution_status_id'] = $contributionStatuses['Completed']; + $input['contribution_status_id'] = $contributionParams['contribution_status_id']; $input['total_amount'] = $input['amount']; $input['contribution'] = $contribution; $input['financial_type_id'] = $contribution->financial_type_id; @@ -4548,7 +4565,8 @@ LIMIT 1;"; CRM_Core_Error::debug_log_message("Contribution record updated successfully"); $transaction->commit(); - CRM_Contribute_BAO_ContributionRecur::updateRecurLinkedPledge($contribution); + CRM_Contribute_BAO_ContributionRecur::updateRecurLinkedPledge($contribution->id, $recurringContributionID, + $input['contribution_status_id'], $input['total_amount']); // create an activity record if ($input['component'] == 'contribute') { @@ -4570,7 +4588,10 @@ LIMIT 1;"; if (!array_key_exists('is_email_receipt', $values) || $values['is_email_receipt'] == 1 ) { - self::sendMail($input, $ids, $objects['contribution'], $values, $recur, FALSE); + civicrm_api3('Contribution', 'sendconfirmation', array( + 'id' => $contribution->id, + 'payment_processor_id' => $paymentProcessorId, + )); CRM_Core_Error::debug_log_message("Receipt sent"); } @@ -4579,6 +4600,7 @@ LIMIT 1;"; CRM_Contribute_BAO_ContributionRecur::sendRecurringStartOrEndNotification($ids, $recur, $isFirstOrLastRecurringPayment); } + return $contributionResult; } /** @@ -4593,7 +4615,7 @@ LIMIT 1;"; * Incoming data from Payment processor. * @param array $ids * Related object IDs. - * @param CRM_Contribute_BAO_Contribution $contribution + * @param int $contributionID * @param array $values * Values related to objects that have already been loaded. * @param bool $recur @@ -4603,10 +4625,19 @@ LIMIT 1;"; * is because the function is also used to generate pdfs * * @return array + * @throws \CRM_Core_Exception + * @throws \CiviCRM_API3_Exception */ - public static function sendMail(&$input, &$ids, $contribution, &$values, $recur = FALSE, $returnMessageText = FALSE) { + public static function sendMail(&$input, &$ids, $contributionID, &$values, $recur = FALSE, + $returnMessageText = FALSE) { $input['is_recur'] = $recur; - $input['receipt_date'] = $contribution->receipt_date; + + $contribution = new CRM_Contribute_BAO_Contribution(); + $contribution->id = $contributionID; + if (!$contribution->find(TRUE)) { + throw new CRM_Core_Exception('Contribution does not exist'); + } + $contribution->loadRelatedObjects($input, $ids, TRUE); // set receipt from e-mail and name in value if (!$returnMessageText) { $session = CRM_Core_Session::singleton(); @@ -4617,11 +4648,13 @@ LIMIT 1;"; $values['receipt_from_name'] = CRM_Utils_Array::value('receipt_from_name', $input, $userName); } } + + $return = $contribution->composeMessageArray($input, $ids, $values, $recur, $returnMessageText); // Contribution ID should really always be set. But ? - if (!$returnMessageText && (!isset($input['receipt_update']) || $input['receipt_update'])) { + if (!$returnMessageText && (!isset($input['receipt_update']) || $input['receipt_update']) && empty($contribution->receipt_date)) { civicrm_api3('Contribution', 'create', array('receipt_date' => 'now', 'id' => $contribution->id)); } - return $contribution->composeMessageArray($input, $ids, $values, $recur, $returnMessageText); + return $return; } /** @@ -4920,4 +4953,85 @@ LIMIT 1;"; return $prevFinancialItem->financial_account_id; } + /** + * ContributionPage values were being imposed onto values. + * + * I have made this explicit and removed the couple (is_recur, is_pay_later) we + * REALLY didn't want superimposed. The rest are left there in their overkill out + * of cautiousness. + * + * The rationale for making this explicit is that it was a case of carefully set values being + * seemingly randonly overwritten without much care. In general I think array randomly setting + * variables en mass is risky. + * + * @param array $values + * + * @return array + */ + protected function addContributionPageValuesToValuesHeavyHandedly(&$values) { + $contributionPageValues = array(); + CRM_Contribute_BAO_ContributionPage::setValues( + $this->contribution_page_id, + $contributionPageValues + ); + $valuesToCopy = array( + // These are the values that I believe to be useful. + 'title', + 'is_email_receipt', + 'pay_later_receipt', + 'pay_later_text', + 'receipt_from_email', + 'receipt_from_name', + 'receipt_text', + 'custom_pre_id', + 'custom_post_id', + 'honoree_profile_id', + 'onbehalf_profile_id', + 'honor_block_is_active', + // Kinda might be - but would be on the contribution... + 'campaign_id', + 'currency', + // Included for 'fear of regression' but can't justify any use for these.... + 'intro_text', + 'payment_processor', + 'financial_type_id', + 'amount_block_is_active', + 'bcc_receipt', + 'cc_receipt', + 'created_date', + 'created_id', + 'default_amount_id', + 'end_date', + 'footer_text', + 'goal_amount', + 'initial_amount_help_text', + 'initial_amount_label', + 'intro_text', + 'is_allow_other_amount', + 'is_billing_required', + 'is_confirm_enabled', + 'is_credit_card_only', + 'is_monetary', + 'is_partial_payment', + 'is_recur_installments', + 'is_recur_interval', + 'is_share', + 'max_amount', + 'min_amount', + 'min_initial_amount', + 'recur_frequency_unit', + 'start_date', + 'thankyou_footer', + 'thankyou_text', + 'thankyou_title', + + ); + foreach ($valuesToCopy as $valueToCopy) { + if (isset($contributionPageValues[$valueToCopy])) { + $values[$valueToCopy] = $contributionPageValues[$valueToCopy]; + } + } + return $values; + } + }