Skip to content

Commit

Permalink
Support multiple memberships for recurring + further cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
mattwire committed Mar 23, 2018
1 parent 25a45c6 commit a584929
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 65 deletions.
143 changes: 78 additions & 65 deletions CRM/Contribute/BAO/Contribution.php
Original file line number Diff line number Diff line change
Expand Up @@ -3916,14 +3916,11 @@ public static function recordAdditionalPayment($contributionId, $trxnsData, $pay
}

// update membership details
if (!empty($contributionDAO->_relatedObjects['membership'])) {
self::updateMembershipBasedOnCompletionOfContribution(
$contributionDAO,
$contributionDAO->_relatedObjects['membership'],
$contributionId,
$trxnsData['trxn_date']
);
}
self::updateMembershipBasedOnCompletionOfContribution(
$contributionDAO,
$contributionId,
$trxnsData['trxn_date']
);

// update financial item statuses
$baseTrxnId = CRM_Core_BAO_FinancialTrxn::getFinancialTrxnId($contributionId);
Expand Down Expand Up @@ -4536,12 +4533,6 @@ public static function completeOrder(&$input, &$ids, $objects, $transaction, $re
}

$participant = CRM_Utils_Array::value('participant', $objects);
$memberships = CRM_Utils_Array::value('membership', $objects);
// FIXME: is this if necessary?
if (is_numeric($memberships)) {
$memberships = array($objects['membership']);
}

$recurContrib = CRM_Utils_Array::value('contributionRecur', $objects);
$recurringContributionID = (empty($recurContrib->id)) ? NULL : $recurContrib->id;
$event = CRM_Utils_Array::value('event', $objects);
Expand Down Expand Up @@ -4616,13 +4607,19 @@ public static function completeOrder(&$input, &$ids, $objects, $transaction, $re
$values['is_email_receipt'] = $recurContrib->is_email_receipt;
}

if (!empty($memberships)) {
if (!empty($input['contribution_status_id'])) {
// FIXME: Do we need this check
$contributionStatusId = $input['contribution_status_id'];
}
else {
$contributionStatusId = CRM_Utils_Array::value('contribution_status_id', $contributionParams);
}

if ($contributionStatusId === $completedContributionStatusID) {
self::updateMembershipBasedOnCompletionOfContribution(
$contribution,
$memberships,
$primaryContributionID,
$changeDate,
CRM_Core_PseudoConstant::getLabel('CRM_Contribute_BAO_Contribution', 'contribution_status_id', CRM_Utils_Array::value('contribution_status_id', $input))
$changeDate
);
}
}
Expand Down Expand Up @@ -5384,68 +5381,84 @@ protected static function isPaymentInstrumentChange(&$params, $pendingStatuses)
* load them in this function. Code clean up would compensate for any minor performance implication.
*
* @param \CRM_Contribute_BAO_Contribution $contribution
* @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) {
protected static function updateMembershipBasedOnCompletionOfContribution($contribution, $primaryContributionID, $changeDate) {
// Load memberships from contribution info. There may be multiple memberships (or none)
$memberships = array();
if (!empty($contribution->contribution_recur_id)) {
// Load memberships associated with recurring contribution
$membershipResult = civicrm_api3('Membership', 'get', array(
'contribution_recur_id' => $contribution->contribution_recur_id,
));
}
elseif (!empty($primaryContributionID)) {
// Load membership associated with original contribution
$membershipPaymentResult = civicrm_api3('MembershipPayment', 'get', array(
'contribution_id' => $primaryContributionID,
));
if (!empty($membershipPaymentResult['count'])) {
foreach ($membershipPaymentResult['values'] as $payment) {
$membershipIDs[] = $payment['membership_id'];
}
$membershipResult = civicrm_api3('Membership', 'get', array(
'id' => array('IN' => $membershipIDs),
));
}
}
if (isset($membershipResult) && !empty($membershipResult['count'])) {
$memberships = $membershipResult['values'];
}

foreach ($memberships as $membershipId => $membership) {
if ($membership) {
if (!CRM_Member_BAO_Membership::isRecurFrequencyEqualToMembershipType($membership->membership_type_id, $membership->contribution_recur_id)) {
Civi::log()->warning('You have enabled auto-renew on membership (id=' . $membership->id . ') but the frequencies do not match! The membership will not be auto-renewed.');
if ((!empty($contribution->contribution_recur_id))
&& (!CRM_Member_BAO_Membership::isRecurFrequencyEqualToMembershipType($membership['membership_type_id'], $membership['contribution_recur_id']))) {
Civi::log()->warning('You have enabled auto-renew on membership (id=' . $membership['id'] . ') but the frequencies do not match! The membership will not be auto-renewed.');
continue;
}
$membershipParams = array(
'id' => $membership->id,
'contact_id' => $membership->contact_id,
'is_test' => $membership->is_test,
'membership_type_id' => $membership->membership_type_id,
'id' => $membership['id'],
'contact_id' => $membership['contact_id'],
'is_test' => $membership['is_test'],
'membership_type_id' => $membership['membership_type_id'],
'membership_activity_status' => 'Completed',
);

// Only renew membership (set num_terms > 0) if we have a completed contribution.
if ($contributionStatus === 'Completed') {
$membershipParams['num_terms'] = $contribution->getNumTermsByContributionAndMembershipType(
$membershipParams['membership_type_id'],
$primaryContributionID
);

// Does the contact have a "current" membership (ie. not expired/pending etc).
$currentMembership = CRM_Member_BAO_Membership::getContactMembership($membershipParams['contact_id'],
$membershipParams['membership_type_id'],
$membershipParams['is_test'],
$membershipParams['id']
);
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);
}
$membershipParams['num_terms'] = $contribution->getNumTermsByContributionAndMembershipType(
$membershipParams['membership_type_id'],
$primaryContributionID
);

// Tell the Membership BAO to calculate membership status.
$membershipParams['skipStatusCal'] = 0;
$membershipParams['exclude_is_admin'] = TRUE;
$membershipParams['is_override'] = FALSE;
$membershipParams['status_override_end_date'] = 'null';
}
else {
// Don't renew the membership
$membershipParams['num_terms'] = 0;
// Does the contact have a "current" membership (ie. not expired/pending etc).
$currentMembership = CRM_Member_BAO_Membership::getContactMembership($membershipParams['contact_id'],
$membershipParams['membership_type_id'],
$membershipParams['is_test'],
$membershipParams['id']
);
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);
}

//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);
// Tell the Membership BAO to calculate membership status.
$membershipParams['skipStatusCal'] = 0;
$membershipParams['exclude_is_admin'] = TRUE;
$membershipParams['is_override'] = FALSE;
$membershipParams['status_override_end_date'] = 'null';
}

//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);
}
}

Expand Down
2 changes: 2 additions & 0 deletions api/v3/Membership.php
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,8 @@ function civicrm_api3_membership_create($params) {
else {
// edit mode
$params['action'] = CRM_Core_Action::UPDATE;
// $ids['membership'] is required in CRM_Price_BAO_LineItem::processPriceSet
$ids['membership'] = $params['id'];
}

$membershipBAO = CRM_Member_BAO_Membership::create($params, $ids, TRUE);
Expand Down

0 comments on commit a584929

Please sign in to comment.