diff --git a/CRM/Contribute/BAO/Contribution.php b/CRM/Contribute/BAO/Contribution.php index 7a051842583..2e5167e10c4 100644 --- a/CRM/Contribute/BAO/Contribution.php +++ b/CRM/Contribute/BAO/Contribution.php @@ -4563,91 +4563,7 @@ public static function completeOrder(&$input, &$ids, $objects, $transaction, $re } if (!empty($memberships)) { - foreach ($memberships as $membershipTypeIdKey => $membership) { - if ($membership) { - $membershipParams = array( - 'id' => $membership->id, - 'contact_id' => $membership->contact_id, - 'is_test' => $membership->is_test, - 'membership_type_id' => $membership->membership_type_id, - 'membership_activity_status' => 'Completed', - ); - - $currentMembership = CRM_Member_BAO_Membership::getContactMembership($membershipParams['contact_id'], - $membershipParams['membership_type_id'], - $membershipParams['is_test'], - $membershipParams['id'] - ); - - // CRM-8141 update the membership type with the value recorded in log when membership created/renewed - // this picks up membership type changes during renewals - // @todo this is almost certainly an obsolete sql call, the pre-change - // membership is accessible via $this->_relatedObjects - $sql = " -SELECT membership_type_id -FROM civicrm_membership_log -WHERE membership_id={$membershipParams['id']} -ORDER BY id DESC -LIMIT 1;"; - $dao = CRM_Core_DAO::executeQuery($sql); - if ($dao->fetch()) { - if (!empty($dao->membership_type_id)) { - $membershipParams['membership_type_id'] = $dao->membership_type_id; - } - } - $dao->free(); - - if (CRM_Core_PseudoConstant::getLabel('CRM_Contribute_BAO_Contribution', 'contribution_status_id', CRM_Utils_Array::value('contribution_status_id', $input)) === 'Pending') { - $membershipParams['num_terms'] = 0; - } - else { - $membershipParams['num_terms'] = $contribution->getNumTermsByContributionAndMembershipType( - $membershipParams['membership_type_id'], - $primaryContributionID - ); - // @todo remove all this stuff in favour of letting the api call further down handle in - // (it is a duplication of what the api does). - $dates = array_fill_keys(array('join_date', 'start_date', 'end_date'), NULL); - if ($currentMembership) { - /* - * Fixed FOR CRM-4433 - * In BAO/Membership.php(renewMembership function), we skip the extend membership date and status - * when Contribution mode is notify and membership is for renewal ) - */ - CRM_Member_BAO_Membership::fixMembershipStatusBeforeRenew($currentMembership, $changeDate); - - // @todo - we should pass membership_type_id instead of null here but not - // adding as not sure of testing - $dates = CRM_Member_BAO_MembershipType::getRenewalDatesForMembershipType($membershipParams['id'], - $changeDate, NULL, $membershipParams['num_terms'] - ); - - $dates['join_date'] = $currentMembership['join_date']; - } - - //get the status for membership. - $calcStatus = CRM_Member_BAO_MembershipStatus::getMembershipStatusByDate($dates['start_date'], - $dates['end_date'], - $dates['join_date'], - 'today', - TRUE, - $membershipParams['membership_type_id'], - $membershipParams - ); - - unset($dates['end_date']); - $membershipParams['status_id'] = CRM_Utils_Array::value('id', $calcStatus, 'New'); - //we might be renewing membership, - //so make status override false. - $membershipParams['is_override'] = FALSE; - } - //CRM-17723 - reset static $relatedContactIds array() - // @todo move it to Civi Statics. - $var = TRUE; - CRM_Member_BAO_Membership::createRelatedMemberships($var, $var, TRUE); - civicrm_api3('Membership', 'create', $membershipParams); - } - } + self::updateMembershipBasedOnCompletionOfContribution(CRM_Core_PseudoConstant::getLabel('CRM_Contribute_BAO_Contribution', 'contribution_status_id', CRM_Utils_Array::value('contribution_status_id', $input)), $contribution, $memberships, $primaryContributionID, $changeDate); } } else { @@ -5394,6 +5310,112 @@ protected static function isPaymentInstrumentChange(&$params, $pendingStatuses) return FALSE; } + /** + * Update the memberships associated with a contribution if it has been completed. + * + * Note that the way in which $memberships are loaded as objects is pretty messy & I think we could just + * load them in this function. Code clean up would compensate for any minor performance implication. + * + * @param array $memberships + * @param int $primaryContributionID + * @param string $changeDate + * @param string $contributionStatus + * This shouldn't be required but historical function overload by repeattransaction probably requires it. + * + * @todo investigate completely bypassing this function if $contributionStatus != Completed. + */ + protected static function updateMembershipBasedOnCompletionOfContribution($contribution, $memberships, $primaryContributionID, $changeDate, $contributionStatus = 'Completed') { + foreach ($memberships as $membershipTypeIdKey => $membership) { + if ($membership) { + $membershipParams = array( + 'id' => $membership->id, + 'contact_id' => $membership->contact_id, + 'is_test' => $membership->is_test, + 'membership_type_id' => $membership->membership_type_id, + 'membership_activity_status' => 'Completed', + ); + + $currentMembership = CRM_Member_BAO_Membership::getContactMembership($membershipParams['contact_id'], + $membershipParams['membership_type_id'], + $membershipParams['is_test'], + $membershipParams['id'] + ); + + // CRM-8141 update the membership type with the value recorded in log when membership created/renewed + // this picks up membership type changes during renewals + // @todo this is almost certainly an obsolete sql call, the pre-change + // membership is accessible via $this->_relatedObjects + $sql = " +SELECT membership_type_id +FROM civicrm_membership_log +WHERE membership_id={$membershipParams['id']} +ORDER BY id DESC +LIMIT 1;"; + $dao = CRM_Core_DAO::executeQuery($sql); + if ($dao->fetch()) { + if (!empty($dao->membership_type_id)) { + $membershipParams['membership_type_id'] = $dao->membership_type_id; + } + } + $dao->free(); + + // Unclear why this is here but this function is overloaded by repeattransaction. + if ($contributionStatus === 'Pending') { + $membershipParams['num_terms'] = 0; + } + else { + $membershipParams['num_terms'] = $contribution->getNumTermsByContributionAndMembershipType( + $membershipParams['membership_type_id'], + $primaryContributionID + ); + // @todo remove all this stuff in favour of letting the api call further down handle in + // (it is a duplication of what the api does). + $dates = array_fill_keys(array( + 'join_date', + 'start_date', + 'end_date', + ), NULL); + if ($currentMembership) { + /* + * Fixed FOR CRM-4433 + * In BAO/Membership.php(renewMembership function), we skip the extend membership date and status + * when Contribution mode is notify and membership is for renewal ) + */ + CRM_Member_BAO_Membership::fixMembershipStatusBeforeRenew($currentMembership, $changeDate); + + // @todo - we should pass membership_type_id instead of null here but not + // adding as not sure of testing + $dates = CRM_Member_BAO_MembershipType::getRenewalDatesForMembershipType($membershipParams['id'], + $changeDate, NULL, $membershipParams['num_terms'] + ); + $dates['join_date'] = $currentMembership['join_date']; + } + + //get the status for membership. + $calcStatus = CRM_Member_BAO_MembershipStatus::getMembershipStatusByDate($dates['start_date'], + $dates['end_date'], + $dates['join_date'], + 'today', + TRUE, + $membershipParams['membership_type_id'], + $membershipParams + ); + + unset($dates['end_date']); + $membershipParams['status_id'] = CRM_Utils_Array::value('id', $calcStatus, 'New'); + //we might be renewing membership, + //so make status override false. + $membershipParams['is_override'] = FALSE; + } + //CRM-17723 - reset static $relatedContactIds array() + // @todo move it to Civi Statics. + $var = TRUE; + CRM_Member_BAO_Membership::createRelatedMemberships($var, $var, TRUE); + civicrm_api3('Membership', 'create', $membershipParams); + } + } + } + /** * Assign Test Value. *