*
* @package CRM
* @copyright CiviCRM LLC (c) 2004-2015
- * $Id$
- *
*/
class CRM_Member_BAO_Membership extends CRM_Member_DAO_Membership {
/**
* Class constructor.
- *
- * @return \CRM_Member_DAO_Membership
- */
- /**
*/
public function __construct() {
parent::__construct();
}
/**
- * Given the list of params in the params array, fetch the object
- * and store the values in the values array
+ * Fetch the object and store the values in the values array.
*
* @param array $params
* Input parameters to find object.
* @param bool $active
* Do you want only active memberships to.
* be returned
+ * @param bool $relatedMemberships
*
- * @return CRM_Member_BAO_Membership|null the found object or null
+ * @return CRM_Member_BAO_Membership|null
+ * The found object or null
*/
- public static function &getValues(&$params, &$values, $active = FALSE) {
+ public static function &getValues(&$params, &$values, $active = FALSE, $relatedMemberships = FALSE) {
if (empty($params)) {
return NULL;
}
CRM_Core_DAO::storeValues($membership, $values[$membership->id]);
$memberships[$membership->id] = $membership;
+ if ($relatedMemberships && !empty($membership->owner_membership_id)) {
+ $values['owner_membership_ids'][] = $membership->owner_membership_id;
+ }
}
return $memberships;
if (empty($params['is_override']) && empty($params['skipStatusCal'])) {
$dates = array('start_date', 'end_date', 'join_date');
- $start_date = $end_date = $join_date = NULL; // declare these out of courtesy as IDEs don't pick up the setting of them below
+ // Declare these out of courtesy as IDEs don't pick up the setting of them below.
+ $start_date = $end_date = $join_date = NULL;
foreach ($dates as $date) {
$$date = $params[$date] = CRM_Utils_Date::processDate(CRM_Utils_Array::value($date, $params), NULL, TRUE, 'Ymd');
}
}
// data cleanup only: all verifications on number of related memberships are done upstream in:
- // CRM_Member_BAO_Membership::createRelatedMemberships()
- // CRM_Contact_BAO_Relationship::relatedMemberships()
+ // CRM_Member_BAO_Membership::createRelatedMemberships()
+ // CRM_Contact_BAO_Relationship::relatedMemberships()
if (isset($params['owner_membership_id'])) {
unset($params['max_related']);
}
$url = CRM_Utils_System::url('civicrm/contact/view/membership',
"action=view&reset=1&id={$membership->id}&cid={$membership->contact_id}&context=home"
);
- if (empty($membership->membership_type_id)) {// ie in an update situation
+ if (empty($membership->membership_type_id)) {
+ // ie in an update situation.
$membership->find(TRUE);
}
$membershipTypes = CRM_Member_PseudoConstant::membershipType();
}
/**
- *
- * get membership status and membership type values
+ * Get membership status and membership type values.
*
* @param int $membershipId
* Membership id of values to return.
/**
* Delete membership.
+ *
* Wrapper for most delete calls. Use this unless you JUST want to delete related memberships w/o deleting the parent.
*
* @param int $membershipId
* Membership id that needs to be deleted.
*
- *
- * @return int $results id of deleted Membership on success, false otherwise
+ * @return int
+ * Id of deleted Membership on success, false otherwise.
*/
public static function del($membershipId) {
//delete related first and then delete parent.
* @param int $membershipId
* Membership id that needs to be deleted.
*
- *
- * @return int $results id of deleted Membership on success, false otherwise
+ * @return int
+ * Id of deleted Membership on success, false otherwise.
*/
public static function deleteMembership($membershipId) {
// CRM-12147, retrieve membership data before we delete it for hooks
*
* @return bool
* Is this a separate membership payment
- *
*/
public static function buildMembershipBlock(
&$form,
* Contribution page id.
*
* @return array|null
- *
*/
public static function getMembershipBlock($pageID) {
$membershipBlock = array();
/**
* Return a current membership of given contact.
+ *
* NB: if more than one membership meets criteria, a randomly selected one is returned.
*
* @param int $contactID
/**
* Get all exportable fields.
*
- * @retun array return array of all exportable fields
+ * @return array return array of all exportable fields
*/
public static function &exportableFields() {
$expFieldMembership = CRM_Member_DAO_Membership::export();
}
/**
- * Get membership joins/renewals for a specified membership
- * type. Specifically, retrieves a count of memberships whose "Membership
+ * Get membership joins/renewals for a specified membership type.
+ *
+ * Specifically, retrieves a count of memberships whose "Membership
* Signup" or "Membership Renewal" activity falls in the given date range.
* Dates match the pattern "yyyy-mm-dd".
*
}
/**
- * Get a count of membership for a specified membership type,
- * optionally for a specified date. The date must have the form yyyy-mm-dd.
+ * Get a count of membership for a specified membership type, optionally for a specified date.
+ *
+ * The date must have the form yyyy-mm-dd.
*
* If $date is omitted, this function counts as a member anyone whose
* membership status_id indicates they're a current member.
* @param bool $isPaidMembership
* @param array $membershipID
*
- * @param $isProcessSeparateMembershipTransaction
+ * @param bool $isProcessSeparateMembershipTransaction
*
* @param int $defaultContributionTypeID
* @param array $membershipLineItems
* Line items specific to membership payment that is separate to contribution.
- * @param $isPayLater
+ * @param bool $isPayLater
*
* @throws \CRM_Core_Exception
*/
$isProcessSeparateMembershipTransaction, $defaultContributionTypeID, $membershipLineItems, $isPayLater) {
$result = $membershipContribution = NULL;
$isTest = CRM_Utils_Array::value('is_test', $membershipParams, FALSE);
- $errors = $createdMemberships = array();
+ $errors = $createdMemberships = $paymentResult = array();
//@todo move this into the calling function & pass in the correct financialTypeID
if (isset($paymentParams['financial_type'])) {
}
if ($isPaidMembership) {
- $result = CRM_Contribute_BAO_Contribution_Utils::processConfirm($form, $membershipParams,
+ if ($isProcessSeparateMembershipTransaction) {
+ // If we have 2 transactions only one can use the invoice id.
+ $membershipParams['invoiceID'] .= '-2';
+ }
+
+ $paymentResult = CRM_Contribute_BAO_Contribution_Utils::processConfirm($form, $membershipParams,
$premiumParams, $contactID,
$financialTypeID,
'membership',
$isPayLater
);
if (is_a($result[1], 'CRM_Core_Error')) {
- $errors[1] = CRM_Core_Error::getMessages($result[1]);
+ $errors[1] = CRM_Core_Error::getMessages($paymentResult[1]);
}
- elseif (!empty($result[1])) {
+
+ if (is_a($paymentResult, 'CRM_Core_Error')) {
+ $errors[1] = CRM_Core_Error::getMessages($paymentResult);
+ }
+ elseif (!empty($paymentResult['contribution'])) {
+ //note that this will be over-written if we are using a separate membership transaction. Otherwise there is only one
+ $membershipContribution = $paymentResult['contribution'];
// Save the contribution ID so that I can be used in email receipts
// For example, if you need to generate a tax receipt for the donation only.
- $form->_values['contribution_other_id'] = $result[1]->id;
- //note that this will be over-written if we are using a separate membership transaction. Otherwise there is only one
- $membershipContribution = $result[1];
+ $form->_values['contribution_other_id'] = $membershipContribution->id;
}
}
if ($isProcessSeparateMembershipTransaction) {
try {
- $lineItems = $form->_lineItem = $membershipLineItems;
+ $form->_lineItem = $membershipLineItems;
+ if (empty($form->_params['auto_renew']) && !empty($membershipParams['is_recur'])) {
+ unset($membershipParams['is_recur']);
+ }
$membershipContribution = self::processSecondaryFinancialTransaction($contactID, $form, $membershipParams, $isTest, $membershipLineItems, CRM_Utils_Array::value('minimum_fee', $membershipDetails, 0), CRM_Utils_Array::value('financial_type_id', $membershipDetails));
}
catch (CRM_Core_Exception $e) {
foreach ($createdMemberships as $createdMembership) {
CRM_Core_BAO_CustomValueTable::postProcess(
$form->_params,
- CRM_Core_DAO::$_nullArray,
'civicrm_membership',
$createdMembership->id,
'Membership'
}
//CRM-15232: Check if membership is created and on the basis of it use
- //membership reciept template to send payment reciept
+ //membership receipt template to send payment receipt
if (count($createdMemberships)) {
$form->_values['isMembership'] = TRUE;
}
$form->_values['contribution_id'] = $membershipContributionID;
}
- // Do not send an email if Recurring transaction is done via Direct Mode
- // Email will we sent when the IPN is received.
- if (!empty($form->_params['is_recur']) && $form->_contributeMode == 'direct') {
- if (!empty($membershipContribution->trxn_id)) {
+ if ($form->_contributeMode == 'direct') {
+ if (CRM_Utils_Array::value('contribution_status_id', $paymentResult) == 1) {
try {
civicrm_api3('contribution', 'completetransaction', array(
- 'id' => $membershipContribution->id,
- 'trxn_id' => $membershipContribution->trxn_id,
+ 'id' => $paymentResult['contribution']->id,
+ 'trxn_id' => $paymentResult['contribution']->trxn_id,
+ 'is_transactional' => FALSE,
));
}
catch (CiviCRM_API3_Exception $e) {
}
/**
- * Function for updating a membership record's contribution_recur_id
+ * Function for updating a membership record's contribution_recur_id.
*
* @param CRM_Member_DAO_Membership $membership
* @param \CRM_Contribute_BAO_Contribution|\CRM_Contribute_DAO_Contribution $contribution
- *
- * @return void
*/
static public function updateRecurMembership(CRM_Member_DAO_Membership $membership, CRM_Contribute_BAO_Contribution $contribution) {
}
/**
+ * A wrapper for renewing memberships from a form.
+ *
* @deprecated
- * A wrapper for renewing memberships from a form - including the form in the membership processing adds complexity
+ * - including the form in the membership processing adds complexity
* as the forms are being forced to pretend similarity
* Try to call the renewMembership directly
* @todo - this form method needs to have the interaction with the form layer removed from it
* @param int $membershipID
* Membership ID, this should always be passed in & optionality should be removed.
*
- * @throws CRM_Core_Exception
+ * @param bool $isPending
+ * Is the transaction pending. We are working towards this ALWAYS being true and completion being done
+ * in the complete transaction function, called by all types of payment processor (removing assumptions
+ * about what they do & always doing a pending + a complete at the appropriate time).
*
+ * @return CRM_Member_BAO_Membership|CRM_Core_Error
*/
public static function renewMembershipFormWrapper(
$contactID,
$membershipTypeID,
$is_test,
&$form,
- $changeToday = NULL,
- $modifiedID = NULL,
- $customFieldsFormatted = NULL,
- $numRenewTerms = 1,
- $membershipID = NULL
+ $changeToday,
+ $modifiedID,
+ $customFieldsFormatted,
+ $numRenewTerms,
+ $membershipID,
+ $isPending
) {
$statusFormat = '%Y-%m-%d';
$format = '%Y%m%d';
$membershipTypeDetails = CRM_Member_BAO_MembershipType::getMembershipTypeDetails($membershipTypeID);
// check is it pending. - CRM-4555
- list($pending, $contributionRecurID, $changeToday, $membershipSource, $isPayLater, $campaignId) = self::extractFormValues($form, $changeToday, $membershipTypeDetails);
- list($membership, $renewalMode, $dates) = self::renewMembership($contactID, $membershipTypeID, $is_test, $changeToday, $modifiedID, $customFieldsFormatted, $numRenewTerms, $membershipID, $pending, $allStatus, $membershipTypeDetails, $contributionRecurID, $format, $membershipSource, $ids, $statusFormat, $isPayLater, $campaignId);
+ list($contributionRecurID, $changeToday, $membershipSource, $isPayLater, $campaignId) = self::extractFormValues($form, $changeToday);
+ list($membership, $renewalMode, $dates) = self::renewMembership($contactID, $membershipTypeID, $is_test,
+ $changeToday, $modifiedID, $customFieldsFormatted, $numRenewTerms, $membershipID, $isPending, $allStatus,
+ $membershipTypeDetails, $contributionRecurID, $format, $membershipSource, $ids, $statusFormat, $isPayLater, $campaignId);
$form->set('renewal_mode', $renewalMode);
if (!empty($dates)) {
$form->assign('mem_start_date',
* Array of month, day, year.
* values in case today needs
* to be customised, null otherwise
- *
- * @return void
*/
public static function fixMembershipStatusBeforeRenew(&$currentMembership, $changeToday) {
$today = NULL;
$format
),
'membership_type_id' => $currentMembership['membership_type_id'],
- 'max_related' => $currentMembership['max_related'],
+ 'max_related' => CRM_Utils_Array::value('max_related', $currentMembership, 0),
);
$session = CRM_Core_Session::singleton();
/**
* Get list of membership fields for profile.
+ *
* For now we only allow custom membership fields to be in
* profile
*
}
/**
- * Create memberships for related contacts.
- * takes into account the maximum related memberships
+ * Create memberships for related contacts, taking into account the maximum related memberships.
*
* @param array $params
* Array of key - value pairs.
* @param CRM_Core_DAO $dao
* Membership object.
*
- * @return null|array
- * array of memberships if created
+ * @param bool $reset
+ *
+ * @return array|null
+ * Membership details, if created.
+ *
+ * @throws \CRM_Core_Exception
*/
public static function createRelatedMemberships(&$params, &$dao, $reset = FALSE) {
static $relatedContactIds = array();
unset($params['max_related']);
// Number of inherited memberships available - NULL is interpreted as unlimited, '0' as none
$available = ($membership->max_related == NULL ? PHP_INT_MAX : $membership->max_related);
- $queue = array(); // will be used to queue potential memberships to be created
+ // will be used to queue potential memberships to be created.
+ $queue = array();
foreach ($relatedContacts as $contactId => $relationshipStatus) {
//use existing membership record.
}
/**
- * Check whether payment processor supports
- * cancellation of membership subscription
+ * Check whether payment processor supports cancellation of membership subscription.
*
* @param int $mid
* Membership id.
}
/**
- * Get membership joins for a specified membership
- * type. Specifically, retrieves a count of still current memberships whose
+ * Get membership joins for a specified membership type.
+ *
+ * Specifically, retrieves a count of still current memberships whose
* join_date and start_date are within a specified date range. Dates match
* the pattern "yyyy-mm-dd".
*
}
/**
- * Get membership renewals for a specified membership
- * type. Specifically, retrieves a count of still current memberships
+ * Get membership renewals for a specified membership type.
+ *
+ * Specifically, retrieves a count of still current memberships
* whose join_date is before and start_date is within a specified date
* range. Dates match the pattern "yyyy-mm-dd".
*
* @param int $contactID
* @param CRM_Contribute_Form_Contribution_Confirm $form
* @param array $tempParams
- * @param $isTest
+ * @param bool $isTest
* @param array $lineItems
* @param $minimumFee
* @param int $financialTypeID
// irrespective of the value, CRM-2888
$tempParams['cms_create_account'] = 0;
- $pending = $form->_params['is_pay_later'] ? (($minimumFee > 0.0) ? TRUE : FALSE) : FALSE;
+ //CRM-16165, scenarios are
+ // 1) If contribution is_pay_later and if contribution amount is > 0.0 we set pending = TRUE, vice-versa FALSE
+ // 2) If not pay later but auto-renewal membership is chosen then pending = TRUE as it later triggers
+ // pending recurring contribution, vice-versa FALSE
+ $pending = $form->_params['is_pay_later'] ? (($minimumFee > 0.0) ? TRUE : FALSE) : (!empty($form->_params['auto_renew']) ? TRUE : FALSE);
//set this variable as we are not creating pledge for
//separate membership payment contribution.
//so for differentiating membership contribution from
//main contribution.
$form->_params['separate_membership_payment'] = 1;
- $membershipContribution = CRM_Contribute_Form_Contribution_Confirm::processContribution($form,
+ $membershipContribution = CRM_Contribute_Form_Contribution_Confirm::processFormContribution($form,
$tempParams,
$result,
$contactID,
$pending,
TRUE,
$isTest,
- $lineItems
+ $lineItems,
+ $form->_bltID
);
return $membershipContribution;
}
* @param $customFieldsFormatted
* @param int $membershipID
* @param $memType
- * @param $isTest
- * @param $numTerms
+ * @param bool $isTest
+ * @param int $numTerms
* @param $membershipContribution
* @param CRM_Core_Form $form
*
* @return array
*/
public static function createOrRenewMembership($membershipParams, $contactID, $customFieldsFormatted, $membershipID, $memType, $isTest, $numTerms, $membershipContribution, &$form) {
+ if (!empty($membershipContribution)) {
+ $pendingStatus = CRM_Core_OptionGroup::getValue('contribution_status', 'Pending', 'name');
+ $pending = ($membershipContribution->contribution_status_id == $pendingStatus) ? TRUE : FALSE;
+ }
$membership = self::renewMembershipFormWrapper($contactID, $memType,
$isTest, $form, NULL,
CRM_Utils_Array::value('cms_contactID', $membershipParams),
$customFieldsFormatted, $numTerms,
- $membershipID
+ $membershipID,
+ self::extractPendingFormValue($form, $memType, $pending)
);
if (!empty($membershipContribution)) {
}
/**
- * Extract relevant values from the form so we can separate form logic from BAO logcis.
+ * Determine if the form has a pending status.
+ *
+ * This is an interim refactoring step. This information should be extracted at the form layer.
+ *
+ * @deprecated
*
* @param CRM_Core_Form $form
- * @param $changeToday
- * @param $membershipTypeDetails
+ * @param int $membershipID
*
- * @return array
+ * @return bool
*/
- public static function extractFormValues($form, $changeToday, $membershipTypeDetails) {
- $pending = FALSE;
+ public static function extractPendingFormValue($form, $membershipID, $pending = FALSE) {
+ $membershipTypeDetails = CRM_Member_BAO_MembershipType::getMembershipTypeDetails($membershipID);
//@todo this is a BAO function & should not inspect the form - the form should do this
// & pass required params to the BAO
if (CRM_Utils_Array::value('minimum_fee', $membershipTypeDetails) > 0.0) {
- if (((isset($form->_contributeMode) && $form->_contributeMode == 'notify') || !empty($form->_params['is_pay_later']) ||
- (!empty($form->_params['is_recur']) && $form->_contributeMode == 'direct'
- )
+ if (((isset($form->_contributeMode) && $form->_contributeMode == 'notify') || !empty($form->_params['is_pay_later'])
) &&
- (($form->_values['is_monetary'] && $form->_amount > 0.0) || !empty($form->_params['separate_membership_payment']) ||
+ (($form->_values['is_monetary'] && $form->_amount > 0.0) ||
CRM_Utils_Array::value('record_contribution', $form->_params)
)
) {
$pending = TRUE;
}
}
+ return $pending;
+ }
+
+ /**
+ * Extract relevant values from the form so we can separate form logic from BAO logcis.
+ *
+ * @param CRM_Core_Form $form
+ * @param $changeToday
+ *
+ * @return array
+ */
+ public static function extractFormValues($form, $changeToday) {
$contributionRecurID = isset($form->_params['contributionRecurID']) ? $form->_params['contributionRecurID'] : NULL;
//we renew expired membership, CRM-6277
$campaignId = CRM_Utils_Array::value('campaign_id', $form->_values);
}
}
- return array($pending, $contributionRecurID, $changeToday, $membershipSource, $isPayLater, $campaignId);
+ return array($contributionRecurID, $changeToday, $membershipSource, $isPayLater, $campaignId);
}
/**
* Process price set and line items.
*
* @param int $membershipId
- * @param $lineItem
- *
- * @return void
+ * @param array $lineItem
*/
public function processPriceSet($membershipId, $lineItem) {
//FIXME : need to move this too