/** * Create a Contact Membership. * * This API is used for creating a Membership for a contact. * Required parameters : membership_type_id and status_id. * * @param array $params * Array of name/value property values of civicrm_membership. * * @return array * API result array. */ function civicrm_api3_membership_create($params) { // check params for membership id during update if (!empty($params['id']) && !isset($params['skipStatusCal'])) { // Don't calculate status on existing membership - expect API use to pass them in // or leave unchanged. $params['skipStatusCal'] = 1; } else { // also check for status id if override is set (during add/update) if (!empty($params['is_override']) && empty($params['status_id'])) { return civicrm_api3_create_error('Status ID required'); } } $values = array(); _civicrm_api3_custom_format_params($params, $values, 'Membership'); $params = array_merge($params, $values); // Fixme: This code belongs in the BAO if (empty($params['id']) || !empty($params['num_terms'])) { if (empty($params['id'])) { $calcDates = CRM_Member_BAO_MembershipType::getDatesForMembershipType($params['membership_type_id'], CRM_Utils_Array::value('join_date', $params), CRM_Utils_Array::value('start_date', $params), CRM_Utils_Array::value('end_date', $params), CRM_Utils_Array::value('num_terms', $params, 1)); } else { $calcDates = CRM_Member_BAO_MembershipType::getRenewalDatesForMembershipType($params['id'], NULL, CRM_Utils_Array::value('membership_type_id', $params), $params['num_terms']); } foreach (array('join_date', 'start_date', 'end_date') as $date) { if (empty($params[$date]) && isset($calcDates[$date])) { $params[$date] = $calcDates[$date]; } } } // Fixme: This code belongs in the BAO $action = CRM_Core_Action::ADD; // we need user id during add mode $ids = array(); if (!empty($params['contact_id'])) { $ids['userId'] = $params['contact_id']; } //for edit membership id should be present if (!empty($params['id'])) { $ids['membership'] = $params['id']; $action = CRM_Core_Action::UPDATE; } //need to pass action to handle related memberships. $params['action'] = $action; if (empty($params['line_item']) && !empty($params['membership_type_id'])) { CRM_Price_BAO_LineItem::getLineItemArray($params, NULL, 'membership', $params['membership_type_id']); } $membershipBAO = CRM_Member_BAO_Membership::create($params, $ids, TRUE); if (array_key_exists('is_error', $membershipBAO)) { // In case of no valid status for given dates, $membershipBAO // is going to contain 'is_error' => "Error Message" return civicrm_api3_create_error(ts('The membership can not be saved, no valid membership status for given dates')); } $membership = array(); _civicrm_api3_object_to_array($membershipBAO, $membership[$membershipBAO->id]); return civicrm_api3_create_success($membership, $params, 'Membership', 'create', $membershipBAO); }
/** * @param int $contactID * @param int $membershipTypeID * @param bool $is_test * @param $changeToday * @param int $modifiedID * @param $customFieldsFormatted * @param $numRenewTerms * @param int $membershipID * @param $pending * @param int $contributionRecurID * @param $membershipSource * @param $isPayLater * @param int $campaignId * @param array $formDates * * @throws CRM_Core_Exception * @return array */ public static function renewMembership($contactID, $membershipTypeID, $is_test, $changeToday, $modifiedID, $customFieldsFormatted, $numRenewTerms, $membershipID, $pending, $contributionRecurID, $membershipSource, $isPayLater, $campaignId, $formDates = array()) { $renewalMode = $updateStatusId = FALSE; $allStatus = CRM_Member_PseudoConstant::membershipStatus(); $format = '%Y%m%d'; $statusFormat = '%Y-%m-%d'; $membershipTypeDetails = CRM_Member_BAO_MembershipType::getMembershipTypeDetails($membershipTypeID); $dates = array(); // CRM-7297 - allow membership type to be be changed during renewal so long as the parent org of new membershipType // is the same as the parent org of an existing membership of the contact $currentMembership = CRM_Member_BAO_Membership::getContactMembership($contactID, $membershipTypeID, $is_test, $membershipID, TRUE); if ($currentMembership) { $activityType = 'Membership Renewal'; $renewalMode = TRUE; // Do NOT do anything. //1. membership with status : PENDING/CANCELLED (CRM-2395) //2. Paylater/IPN renew. CRM-4556. if ($pending || in_array($currentMembership['status_id'], array(array_search('Pending', $allStatus), array_search('Cancelled', CRM_Member_PseudoConstant::membershipStatus(NULL, " name = 'Cancelled' ", 'name', FALSE, TRUE))))) { $membership = new CRM_Member_DAO_Membership(); $membership->id = $currentMembership['id']; $membership->find(TRUE); // CRM-8141 create a membership_log entry so that we will know the membership_type_id to change to when payment completed $format = '%Y%m%d'; // note that we are logging the requested new membership_type_id that may be different than current membership_type_id // it will be used when payment is received to update the membership_type_id to what was paid for $logParams = array('membership_id' => $membership->id, 'status_id' => $membership->status_id, 'start_date' => CRM_Utils_Date::customFormat($membership->start_date, $format), 'end_date' => CRM_Utils_Date::customFormat($membership->end_date, $format), 'modified_date' => CRM_Utils_Date::customFormat(date('Ymd'), $format), 'membership_type_id' => $membershipTypeID, 'max_related' => !empty($membershipTypeDetails['max_related']) ? $membershipTypeDetails['max_related'] : NULL); $session = CRM_Core_Session::singleton(); // If we have an authenticated session, set modified_id to that user's contact_id, else set to membership.contact_id if ($session->get('userID')) { $logParams['modified_id'] = $session->get('userID'); } else { $logParams['modified_id'] = $membership->contact_id; } CRM_Member_BAO_MembershipLog::add($logParams); if ($contributionRecurID) { CRM_Core_DAO::setFieldValue('CRM_Member_DAO_Membership', $membership->id, 'contribution_recur_id', $contributionRecurID); } return array($membership, $renewalMode, $dates); } // Check and fix the membership if it is STALE self::fixMembershipStatusBeforeRenew($currentMembership, $changeToday); // Now Renew the membership if (!$currentMembership['is_current_member']) { // membership is not CURRENT // CRM-7297 Membership Upsell - calculate dates based on new membership type $dates = CRM_Member_BAO_MembershipType::getRenewalDatesForMembershipType($currentMembership['id'], $changeToday, $membershipTypeID, $numRenewTerms); $currentMembership['join_date'] = CRM_Utils_Date::customFormat($currentMembership['join_date'], $format); foreach (array('start_date', 'end_date') as $dateType) { $currentMembership[$dateType] = CRM_Utils_Array::value($dateType, $formDates); if (empty($currentMembership[$dateType])) { $currentMembership[$dateType] = CRM_Utils_Array::value($dateType, $dates); } } $currentMembership['is_test'] = $is_test; if (!empty($membershipSource)) { $currentMembership['source'] = $membershipSource; } else { $currentMembership['source'] = CRM_Core_DAO::getFieldValue('CRM_Member_DAO_Membership', $currentMembership['id'], 'source'); } if (!empty($currentMembership['id'])) { $ids['membership'] = $currentMembership['id']; } $memParams = $currentMembership; $memParams['membership_type_id'] = $membershipTypeID; //set the log start date. $memParams['log_start_date'] = CRM_Utils_Date::customFormat($dates['log_start_date'], $format); } else { // CURRENT Membership $membership = new CRM_Member_DAO_Membership(); $membership->id = $currentMembership['id']; $membership->find(TRUE); // CRM-7297 Membership Upsell - calculate dates based on new membership type $dates = CRM_Member_BAO_MembershipType::getRenewalDatesForMembershipType($membership->id, $changeToday, $membershipTypeID, $numRenewTerms); // Insert renewed dates for CURRENT membership $memParams = array(); $memParams['join_date'] = CRM_Utils_Date::isoToMysql($membership->join_date); $memParams['start_date'] = CRM_Utils_Date::isoToMysql($membership->start_date); $memParams['end_date'] = CRM_Utils_Array::value('end_date', $formDates); if (empty($memParams['end_date'])) { $memParams['end_date'] = CRM_Utils_Array::value('end_date', $dates); } $memParams['membership_type_id'] = $membershipTypeID; //set the log start date. $memParams['log_start_date'] = CRM_Utils_Date::customFormat($dates['log_start_date'], $format); if (empty($membership->source)) { if (!empty($membershipSource)) { $memParams['source'] = $membershipSource; } else { $memParams['source'] = CRM_Core_DAO::getFieldValue('CRM_Member_DAO_Membership', $currentMembership['id'], 'source'); } } if (!empty($currentMembership['id'])) { $ids['membership'] = $currentMembership['id']; } } //CRM-4555 if ($pending) { $updateStatusId = array_search('Pending', $allStatus); } } else { // NEW Membership $activityType = 'Membership Signup'; $memParams = array('contact_id' => $contactID, 'membership_type_id' => $membershipTypeID); if (!$pending) { $dates = CRM_Member_BAO_MembershipType::getDatesForMembershipType($membershipTypeID, NULL, NULL, NULL, $numRenewTerms); foreach (array('join_date', 'start_date', 'end_date') as $dateType) { $memParams[$dateType] = CRM_Utils_Array::value($dateType, $formDates); if (empty($memParams[$dateType])) { $memParams[$dateType] = CRM_Utils_Array::value($dateType, $dates); } } $status = CRM_Member_BAO_MembershipStatus::getMembershipStatusByDate(CRM_Utils_Date::customFormat($dates['start_date'], $statusFormat), CRM_Utils_Date::customFormat($dates['end_date'], $statusFormat), CRM_Utils_Date::customFormat($dates['join_date'], $statusFormat), 'today', TRUE, $membershipTypeID, $memParams); $updateStatusId = CRM_Utils_Array::value('id', $status); } else { // if IPN/Pay-Later set status to: PENDING $updateStatusId = array_search('Pending', $allStatus); } if (!empty($membershipSource)) { $memParams['source'] = $membershipSource; } $memParams['is_test'] = $is_test; $memParams['is_pay_later'] = $isPayLater; } // Putting this in an IF is precautionary as it seems likely that it would be ignored if empty, but // perhaps shouldn't be? if ($contributionRecurID) { $memParams['contribution_recur_id'] = $contributionRecurID; } //CRM-4555 //if we decided status here and want to skip status //calculation in create( ); then need to pass 'skipStatusCal'. if ($updateStatusId) { $memParams['status_id'] = $updateStatusId; $memParams['skipStatusCal'] = TRUE; } //since we are renewing, //make status override false. $memParams['is_override'] = FALSE; //CRM-4027, create log w/ individual contact. if ($modifiedID) { $ids['userId'] = $modifiedID; $memParams['is_for_organization'] = TRUE; } else { $ids['userId'] = $contactID; } //inherit campaign from contrib page. if (isset($campaignId)) { $memParams['campaign_id'] = $campaignId; } $memParams['custom'] = $customFieldsFormatted; $membership = self::create($memParams, $ids, FALSE, $activityType); // not sure why this statement is here, seems quite odd :( - Lobo: 12/26/2010 // related to: http://forum.civicrm.org/index.php/topic,11416.msg49072.html#msg49072 $membership->find(TRUE); return array($membership, $renewalMode, $dates); }
function completeTransaction(&$input, &$ids, &$objects, &$transaction, $recur = FALSE) { $contribution =& $objects['contribution']; $primaryContributionID = isset($contribution->id) ? $contribution->id : $objects['first_contribution']->id; $memberships =& $objects['membership']; if (is_numeric($memberships)) { $memberships = array($objects['membership']); } $participant =& $objects['participant']; $event =& $objects['event']; $changeToday = CRM_Utils_Array::value('trxn_date', $input, self::$_now); $recurContrib =& $objects['contributionRecur']; $values = array(); if (isset($input['is_email_receipt'])) { $values['is_email_receipt'] = $input['is_email_receipt']; } $source = NULL; if ($input['component'] == 'contribute') { if ($contribution->contribution_page_id) { CRM_Contribute_BAO_ContributionPage::setValues($contribution->contribution_page_id, $values); $source = ts('Online Contribution') . ': ' . $values['title']; } elseif ($recurContrib && $recurContrib->id) { $contribution->contribution_page_id = NULL; $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'])) { //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; } $contribution->source = $source; if (CRM_Utils_Array::value('is_email_receipt', $values)) { $contribution->receipt_date = self::$_now; } if (!empty($memberships)) { $membershipsUpdate = array(); foreach ($memberships as $membershipTypeIdKey => $membership) { if ($membership) { $format = '%Y%m%d'; $currentMembership = CRM_Member_BAO_Membership::getContactMembership($membership->contact_id, $membership->membership_type_id, $membership->is_test, $membership->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 $sql = "\nSELECT membership_type_id\nFROM civicrm_membership_log\nWHERE membership_id={$membership->id}\nORDER BY id DESC\nLIMIT 1;"; $dao = new CRM_Core_DAO(); $dao->query($sql); if ($dao->fetch()) { if (!empty($dao->membership_type_id)) { $membership->membership_type_id = $dao->membership_type_id; $membership->save(); } // else fall back to using current membership type } // else fall back to using current membership type $dao->free(); $num_terms = $contribution->getNumTermsByContributionAndMembershipType($membership->membership_type_id, $primaryContributionID); 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, $changeToday); // @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($membership->id, $changeToday, NULL, $num_terms); $dates['join_date'] = CRM_Utils_Date::customFormat($currentMembership['join_date'], $format); } else { $dates = CRM_Member_BAO_MembershipType::getDatesForMembershipType($membership->membership_type_id, NULL, NULL, NULL, $num_terms); } //get the status for membership. $calcStatus = CRM_Member_BAO_MembershipStatus::getMembershipStatusByDate($dates['start_date'], $dates['end_date'], $dates['join_date'], 'today', TRUE, $membership->membership_type_id, (array) $membership); $formatedParams = array('status_id' => CRM_Utils_Array::value('id', $calcStatus, 2), 'join_date' => CRM_Utils_Date::customFormat(CRM_Utils_Array::value('join_date', $dates), $format), 'start_date' => CRM_Utils_Date::customFormat(CRM_Utils_Array::value('start_date', $dates), $format), 'end_date' => CRM_Utils_Date::customFormat(CRM_Utils_Array::value('end_date', $dates), $format)); //we might be renewing membership, //so make status override false. $formatedParams['is_override'] = FALSE; $membership->copyValues($formatedParams); $membership->save(); //updating the membership log $membershipLog = array(); $membershipLog = $formatedParams; $logStartDate = $formatedParams['start_date']; if (CRM_Utils_Array::value('log_start_date', $dates)) { $logStartDate = CRM_Utils_Date::customFormat($dates['log_start_date'], $format); $logStartDate = CRM_Utils_Date::isoToMysql($logStartDate); } $membershipLog['start_date'] = $logStartDate; $membershipLog['membership_id'] = $membership->id; $membershipLog['modified_id'] = $membership->contact_id; $membershipLog['modified_date'] = date('Ymd'); $membershipLog['membership_type_id'] = $membership->membership_type_id; CRM_Member_BAO_MembershipLog::add($membershipLog, CRM_Core_DAO::$_nullArray); //update related Memberships. CRM_Member_BAO_Membership::updateRelatedMemberships($membership->id, $formatedParams); //update the membership type key of membership relatedObjects array //if it has changed after membership update if ($membershipTypeIdKey != $membership->membership_type_id) { $membershipsUpdate[$membership->membership_type_id] = $membership; $contribution->_relatedObjects['membership'][$membership->membership_type_id] = $membership; unset($contribution->_relatedObjects['membership'][$membershipTypeIdKey]); unset($memberships[$membershipTypeIdKey]); } } } //update the memberships object with updated membershipTypeId data //if membershipTypeId has changed after membership update if (!empty($membershipsUpdate)) { $memberships = $memberships + $membershipsUpdate; } } } else { // event $eventParams = array('id' => $objects['event']->id); $values['event'] = array(); CRM_Event_BAO_Event::retrieve($eventParams, $values['event']); //get location details $locationParams = array('entity_id' => $objects['event']->id, 'entity_table' => 'civicrm_event'); $values['location'] = CRM_Core_BAO_Location::getValues($locationParams); $ufJoinParams = array('entity_table' => 'civicrm_event', 'entity_id' => $ids['event'], 'module' => 'CiviEvent'); list($custom_pre_id, $custom_post_ids) = CRM_Core_BAO_UFJoin::getUFGroupIds($ufJoinParams); $values['custom_pre_id'] = $custom_pre_id; $values['custom_post_id'] = $custom_post_ids; //for tasks 'Change Participant Status' and 'Batch Update Participants Via Profile' case //and cases involving status updation through ipn $values['totalAmount'] = $input['amount']; $contribution->source = ts('Online Event Registration') . ': ' . $values['event']['title']; if ($values['event']['is_email_confirm']) { $contribution->receipt_date = self::$_now; $values['is_email_receipt'] = 1; } if (!CRM_Utils_Array::value('skipComponentSync', $input)) { $participant->status_id = 1; } $participant->save(); } if (CRM_Utils_Array::value('net_amount', $input, 0) == 0 && CRM_Utils_Array::value('fee_amount', $input, 0) != 0) { $input['net_amount'] = $input['amount'] - $input['fee_amount']; } // This complete transaction function is being overloaded to create new contributions too. // here we record if it is a new contribution. // @todo separate the 2 more appropriately. $isNewContribution = FALSE; if (empty($contribution->id)) { $isNewContribution = TRUE; if (!empty($input['amount']) && $input['amount'] != $contribution->total_amount) { $contribution->total_amount = $input['amount']; // The BAO does this stuff but we are actually kinda bypassing it here (bad code! go sit in the corner) // so we have to handle net_amount in this (naughty) code. if (isset($input['fee_amount']) && is_numeric($input['fee_amount'])) { $contribution->fee_amount = $input['fee_amount']; } $contribution->net_amount = $contribution->total_amount - $contribution->fee_amount; } if (!empty($input['campaign_id'])) { $contribution->campaign_id = $input['campaign_id']; } } $contributionStatuses = CRM_Core_PseudoConstant::get('CRM_Contribute_DAO_Contribution', 'contribution_status_id', array('labelColumn' => 'name', 'flip' => 1)); // @todo this section should call the api in order to have hooks called & // because all this 'messiness' setting variables could be avoided // by letting the api resolve pseudoconstants & copy set values and format dates. $contribution->contribution_status_id = $contributionStatuses['Completed']; $contribution->is_test = $input['is_test']; // CRM-15960 If we don't have a value we 'want' for the amounts, leave it to the BAO to sort out. if (isset($input['net_amount'])) { $contribution->fee_amount = CRM_Utils_Array::value('fee_amount', $input, 0); } if (isset($input['net_amount'])) { $contribution->net_amount = $input['net_amount']; } $contribution->trxn_id = $input['trxn_id']; $contribution->receive_date = CRM_Utils_Date::isoToMysql($contribution->receive_date); $contribution->thankyou_date = CRM_Utils_Date::isoToMysql($contribution->thankyou_date); $contribution->receipt_date = CRM_Utils_Date::isoToMysql($contribution->receipt_date); $contribution->cancel_date = 'null'; if (CRM_Utils_Array::value('check_number', $input)) { $contribution->check_number = $input['check_number']; } if (CRM_Utils_Array::value('payment_instrument_id', $input)) { $contribution->payment_instrument_id = $input['payment_instrument_id']; } if (!empty($contribution->id)) { $contributionId['id'] = $contribution->id; $input['prevContribution'] = CRM_Contribute_BAO_Contribution::getValues($contributionId, CRM_Core_DAO::$_nullArray, CRM_Core_DAO::$_nullArray); } $contribution->save(); //add line items for recurring payments if (!empty($contribution->contribution_recur_id)) { if ($isNewContribution) { $input['line_item'] = $this->addRecurLineItems($contribution->contribution_recur_id, $contribution); } else { // this is just to prevent e-notices when we call recordFinancialAccounts - per comments on that line - intention is somewhat unclear $input['line_item'] = array(); } if (!empty($memberships) && $primaryContributionID != $contribution->id) { foreach ($memberships as $membership) { try { $membershipPayment = array('membership_id' => $membership->id, 'contribution_id' => $contribution->id); if (!civicrm_api3('membership_payment', 'getcount', $membershipPayment)) { civicrm_api3('membership_payment', 'create', $membershipPayment); } } catch (CiviCRM_API3_Exception $e) { echo $e->getMessage(); // we are catching & ignoring errors as an extra precaution since lost IPNs may be more serious that lost membership_payment data // this fn is unit-tested so risk of changes elsewhere breaking it are otherwise mitigated } } } } //copy initial contribution custom fields for recurring contributions if ($recurContrib && $recurContrib->id) { $this->copyCustomValues($recurContrib->id, $contribution->id); } // next create the transaction record $paymentProcessor = $paymentProcessorId = ''; if (isset($objects['paymentProcessor'])) { if (is_array($objects['paymentProcessor'])) { $paymentProcessor = $objects['paymentProcessor']['payment_processor_type']; $paymentProcessorId = $objects['paymentProcessor']['id']; } else { $paymentProcessor = $objects['paymentProcessor']->payment_processor_type; $paymentProcessorId = $objects['paymentProcessor']->id; } } //it's hard to see how it could reach this point without a contributon id as it is saved in line 511 above // which raised the question as to whether this check preceded line 511 & if so whether something could be broken // From a lot of code reading /debugging I'm still not sure the intent WRT first & subsequent payments in this code // it would be good if someone added some comments or refactored this if ($contribution->id) { $contributionStatuses = CRM_Contribute_PseudoConstant::contributionStatus(NULL, 'name'); if (empty($input['prevContribution']) && $paymentProcessorId || !$input['prevContribution']->is_pay_later && $input['prevContribution']->contribution_status_id == array_search('Pending', $contributionStatuses)) { $input['payment_processor'] = $paymentProcessorId; } $input['contribution_status_id'] = array_search('Completed', $contributionStatuses); $input['total_amount'] = $input['amount']; $input['contribution'] = $contribution; $input['financial_type_id'] = $contribution->financial_type_id; if (CRM_Utils_Array::value('participant', $contribution->_relatedObjects)) { $input['contribution_mode'] = 'participant'; $input['participant_id'] = $contribution->_relatedObjects['participant']->id; $input['skipLineItem'] = 1; } //@todo writing a unit test I was unable to create a scenario where this line did not fatal on second // and subsequent payments. In this case the line items are created at $this->addRecurLineItems // and since the contribution is saved prior to this line there is always a contribution-id, // however there is never a prevContribution (which appears to mean original contribution not previous // contribution - or preUpdateContributionObject most accurately) // so, this is always called & only appears to succeed when prevContribution exists - which appears // to mean "are we updating an exisitng pending contribution" //I was able to make the unit test complete as fataling here doesn't prevent // the contribution being created - but activities would not be created or emails sent CRM_Contribute_BAO_Contribution::recordFinancialAccounts($input, NULL); } self::updateRecurLinkedPledge($contribution); // create an activity record if ($input['component'] == 'contribute') { //CRM-4027 $targetContactID = NULL; if (CRM_Utils_Array::value('related_contact', $ids)) { $targetContactID = $contribution->contact_id; $contribution->contact_id = $ids['related_contact']; } CRM_Activity_BAO_Activity::addActivity($contribution, NULL, $targetContactID); // event } else { CRM_Activity_BAO_Activity::addActivity($participant); } CRM_Core_Error::debug_log_message("Contribution record updated successfully"); $transaction->commit(); // CRM-9132 legacy behaviour was that receipts were sent out in all instances. Still sending // when array_key 'is_email_receipt doesn't exist in case some instances where is needs setting haven't been set if (!array_key_exists('is_email_receipt', $values) || $values['is_email_receipt'] == 1) { self::sendMail($input, $ids, $objects, $values, $recur, FALSE); CRM_Core_Error::debug_log_message("Receipt sent"); } CRM_Core_Error::debug_log_message("Success: Database updated"); }
/** * This function update contribution as well as related objects. */ function transitionComponents($params, $processContributionObject = false) { // get minimum required values. $contactId = CRM_Utils_Array::value('contact_id', $params); $componentId = CRM_Utils_Array::value('component_id', $params); $componentName = CRM_Utils_Array::value('componentName', $params); $contributionId = CRM_Utils_Array::value('contribution_id', $params); $contributionStatusId = CRM_Utils_Array::value('contribution_status_id', $params); // if we already processed contribution object pass previous status id. $previousContriStatusId = CRM_Utils_Array::value('previous_contribution_status_id', $params); $updateResult = array(); require_once 'CRM/Contribute/PseudoConstant.php'; $contributionStatuses = CRM_Contribute_PseudoConstant::contributionStatus(null, 'name'); // we process only ( Completed, Cancelled, or Failed ) contributions. if (!$contributionId || !in_array($contributionStatusId, array(array_search('Completed', $contributionStatuses), array_search('Cancelled', $contributionStatuses), array_search('Failed', $contributionStatuses)))) { return $updateResult; } if (!$componentName || !$componentId) { // get the related component details. $componentDetails = self::getComponentDetails($contributionId); } else { $componentDetails['contact_id'] = $contactId; $componentDetails['component'] = $componentName; if ($componentName = 'event') { $componentDetails['participant'] = $componentId; } else { $componentDetails['membership'] = $componentId; } } if (CRM_Utils_Array::value('contact_id', $componentDetails)) { $componentDetails['contact_id'] = CRM_Core_DAO::getFieldValue('CRM_Contribute_DAO_Contribution', $contributionId, 'contact_id'); } // do check for required ids. if (!CRM_Utils_Array::value('membership', $componentDetails) && !CRM_Utils_Array::value('participant', $componentDetails) && !CRM_Utils_Array::value('pledge_payment', $componentDetails) || !CRM_Utils_Array::value('contact_id', $componentDetails)) { return $updateResult; } //now we are ready w/ required ids, start processing. require_once 'CRM/Core/Payment/BaseIPN.php'; $baseIPN = new CRM_Core_Payment_BaseIPN(); $input = $ids = $objects = array(); $input['component'] = CRM_Utils_Array::value('component', $componentDetails); $ids['contribution'] = $contributionId; $ids['contact'] = CRM_Utils_Array::value('contact_id', $componentDetails); $ids['membership'] = CRM_Utils_Array::value('membership', $componentDetails); $ids['participant'] = CRM_Utils_Array::value('participant', $componentDetails); $ids['event'] = CRM_Utils_Array::value('event', $componentDetails); $ids['pledge_payment'] = CRM_Utils_Array::value('pledge_payment', $componentDetails); $ids['contributionRecur'] = null; $ids['contributionPage'] = null; if (!$baseIPN->validateData($input, $ids, $objects, false)) { CRM_Core_Error::fatal(); } $membership =& $objects['membership']; $participant =& $objects['participant']; $pledgePayment =& $objects['pledge_payment']; $contribution =& $objects['contribution']; if ($pledgePayment) { require_once 'CRM/Pledge/BAO/Payment.php'; $pledgePaymentIDs = array(); foreach ($pledgePayment as $key => $object) { $pledgePaymentIDs[] = $object->id; } $pledgeID = $pledgePayment[0]->pledge_id; } require_once 'CRM/Event/PseudoConstant.php'; require_once 'CRM/Event/BAO/Participant.php'; require_once 'CRM/Pledge/BAO/Pledge.php'; require_once 'CRM/Member/PseudoConstant.php'; require_once 'CRM/Member/BAO/Membership.php'; $membershipStatuses = CRM_Member_PseudoConstant::membershipStatus(); if ($participant) { $participantStatuses = CRM_Event_PseudoConstant::participantStatus(); $oldStatus = CRM_Core_DAO::getFieldValue("CRM_Event_DAO_Participant", $participant->id, 'status_id'); } // we might want to process contribution object. $processContribution = false; if ($contributionStatusId == array_search('Cancelled', $contributionStatuses)) { if ($membership) { $membership->status_id = array_search('Cancelled', $membershipStatuses); $membership->save(); $updateResult['updatedComponents']['CiviMember'] = $membership->status_id; if ($processContributionObject) { $processContribution = true; } } if ($participant) { $updatedStatusId = array_search('Cancelled', $participantStatuses); CRM_Event_BAO_Participant::updateParticipantStatus($participant->id, $oldStatus, $updatedStatusId, true); $updateResult['updatedComponents']['CiviEvent'] = $updatedStatusId; if ($processContributionObject) { $processContribution = true; } } if ($pledgePayment) { CRM_Pledge_BAO_Payment::updatePledgePaymentStatus($pledgeID, $pledgePaymentIDs, $contributionStatusId); $updateResult['updatedComponents']['CiviPledge'] = $contributionStatusId; if ($processContributionObject) { $processContribution = true; } } } else { if ($contributionStatusId == array_search('Failed', $contributionStatuses)) { if ($membership) { $membership->status_id = array_search('Expired', $membershipStatuses); $membership->save(); $updateResult['updatedComponents']['CiviMember'] = $membership->status_id; if ($processContributionObject) { $processContribution = true; } } if ($participant) { $updatedStatusId = array_search('Cancelled', $participantStatuses); CRM_Event_BAO_Participant::updateParticipantStatus($participant->id, $oldStatus, $updatedStatusId, true); $updateResult['updatedComponents']['CiviEvent'] = $updatedStatusId; if ($processContributionObject) { $processContribution = true; } } if ($pledgePayment) { CRM_Pledge_BAO_Payment::updatePledgePaymentStatus($pledgeID, $pledgePaymentIDs, $contributionStatusId); $updateResult['updatedComponents']['CiviPledge'] = $contributionStatusId; if ($processContributionObject) { $processContribution = true; } } } else { if ($contributionStatusId == array_search('Completed', $contributionStatuses)) { // only pending contribution related object processed. if ($previousContriStatusId && $previousContriStatusId != array_search('Pending', $contributionStatuses)) { // this is case when we already processed contribution object. return $updateResult; } else { if (!$previousContriStatusId && $contribution->contribution_status_id != array_search('Pending', $contributionStatuses)) { // this is case when we will going to process contribution object. return $updateResult; } } if ($membership) { $format = '%Y%m%d'; require_once 'CRM/Member/BAO/MembershipType.php'; //CRM-4523 $currentMembership = CRM_Member_BAO_Membership::getContactMembership($membership->contact_id, $membership->membership_type_id, $membership->is_test, $membership->id); if ($currentMembership) { CRM_Member_BAO_Membership::fixMembershipStatusBeforeRenew($currentMembership, $changeToday = null); $dates = CRM_Member_BAO_MembershipType::getRenewalDatesForMembershipType($membership->id, $changeToday = null); $dates['join_date'] = CRM_Utils_Date::customFormat($currentMembership['join_date'], $format); } else { $dates = CRM_Member_BAO_MembershipType::getDatesForMembershipType($membership->membership_type_id); } //get the status for membership. require_once 'CRM/Member/BAO/MembershipStatus.php'; $calcStatus = CRM_Member_BAO_MembershipStatus::getMembershipStatusByDate($dates['start_date'], $dates['end_date'], $dates['join_date'], 'today', true); $formatedParams = array('status_id' => CRM_Utils_Array::value('id', $calcStatus, array_search('Current', $membershipStatuses)), 'join_date' => CRM_Utils_Date::customFormat($dates['join_date'], $format), 'start_date' => CRM_Utils_Date::customFormat($dates['start_date'], $format), 'end_date' => CRM_Utils_Date::customFormat($dates['end_date'], $format), 'reminder_date' => CRM_Utils_Date::customFormat($dates['reminder_date'], $format)); $membership->copyValues($formatedParams); $membership->save(); //updating the membership log $membershipLog = array(); $membershipLog = $formatedParams; $logStartDate = CRM_Utils_Date::customFormat($dates['log_start_date'], $format); $logStartDate = $logStartDate ? CRM_Utils_Date::isoToMysql($logStartDate) : $formatedParams['start_date']; $membershipLog['start_date'] = $logStartDate; $membershipLog['membership_id'] = $membership->id; $membershipLog['modified_id'] = $membership->contact_id; $membershipLog['modified_date'] = date('Ymd'); require_once 'CRM/Member/BAO/MembershipLog.php'; CRM_Member_BAO_MembershipLog::add($membershipLog, CRM_Core_DAO::$_nullArray); //update related Memberships. CRM_Member_BAO_Membership::updateRelatedMemberships($membership->id, $formatedParams); $updateResult['membership_end_date'] = CRM_Utils_Date::customFormat($dates['end_date'], '%B %E%f, %Y'); $updateResult['updatedComponents']['CiviMember'] = $membership->status_id; if ($processContributionObject) { $processContribution = true; } } if ($participant) { $updatedStatusId = array_search('Registered', $participantStatuses); CRM_Event_BAO_Participant::updateParticipantStatus($participant->id, $oldStatus, $updatedStatusId, true); $updateResult['updatedComponents']['CiviEvent'] = $updatedStatusId; if ($processContributionObject) { $processContribution = true; } } if ($pledgePayment) { CRM_Pledge_BAO_Payment::updatePledgePaymentStatus($pledgeID, $pledgePaymentIDs, $contributionStatusId); $updateResult['updatedComponents']['CiviPledge'] = $contributionStatusId; if ($processContributionObject) { $processContribution = true; } } } } } // process contribution object. if ($processContribution) { require_once 'CRM/Contribute/BAO/Contribution.php'; $contributionParams = array(); $fields = array('contact_id', 'total_amount', 'receive_date', 'is_test', 'payment_instrument_id', 'trxn_id', 'invoice_id', 'contribution_type_id', 'contribution_status_id', 'non_deductible_amount', 'receipt_date', 'check_number'); foreach ($fields as $field) { if (!CRM_Utils_Array::value($field, $params)) { continue; } $contributionParams[$field] = $params[$field]; } $ids = array('contribution' => $contributionId); require_once 'CRM/Contribute/BAO/Contribution.php'; $contribution =& CRM_Contribute_BAO_Contribution::create($contributionParams, $ids); } return $updateResult; }
function completeTransaction(&$input, &$ids, &$objects, &$transaction, $recur = FALSE) { $contribution =& $objects['contribution']; $memberships =& $objects['membership']; if (is_numeric($memberships)) { $memberships = array($objects['membership']); } $participant =& $objects['participant']; $event =& $objects['event']; $changeToday = CRM_Utils_Array::value('trxn_date', $input, self::$_now); $recurContrib =& $objects['contributionRecur']; $values = array(); if ($input['component'] == 'contribute') { if ($contribution->contribution_page_id) { CRM_Contribute_BAO_ContributionPage::setValues($contribution->contribution_page_id, $values); $source = ts('Online Contribution') . ': ' . $values['title']; } elseif ($recurContrib->id) { $contribution->contribution_page_id = NULL; $values['amount'] = $recurContrib->amount; $values['contribution_type_id'] = $objects['contributionType']->id; $values['title'] = $source = ts('Offline Recurring Contribution'); $values['is_email_receipt'] = $recurContrib->is_email_receipt; $domainValues = CRM_Core_BAO_Domain::getNameAndEmail(); $values['receipt_from_name'] = $domainValues[0]; $values['receipt_from_email'] = $domainValues[1]; } $contribution->source = $source; if (CRM_Utils_Array::value('is_email_receipt', $values)) { $contribution->receipt_date = self::$_now; } if (!empty($memberships)) { foreach ($memberships as $membershipTypeIdKey => $membership) { if ($membership) { $format = '%Y%m%d'; $currentMembership = CRM_Member_BAO_Membership::getContactMembership($membership->contact_id, $membership->membership_type_id, $membership->is_test, $membership->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 $sql = "\nSELECT membership_type_id\nFROM civicrm_membership_log\nWHERE membership_id={$membership->id}\nORDER BY id DESC\nLIMIT 1;"; $dao = new CRM_Core_DAO(); $dao->query($sql); if ($dao->fetch()) { if (!empty($dao->membership_type_id)) { $membership->membership_type_id = $dao->membership_type_id; $membership->save(); } // else fall back to using current membership type } // else fall back to using current membership type $dao->free(); 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, $changeToday); $dates = CRM_Member_BAO_MembershipType::getRenewalDatesForMembershipType($membership->id, $changeToday); $dates['join_date'] = CRM_Utils_Date::customFormat($currentMembership['join_date'], $format); } else { $dates = CRM_Member_BAO_MembershipType::getDatesForMembershipType($membership->membership_type_id); } //get the status for membership. $calcStatus = CRM_Member_BAO_MembershipStatus::getMembershipStatusByDate($dates['start_date'], $dates['end_date'], $dates['join_date'], 'today', TRUE); $formatedParams = array('status_id' => CRM_Utils_Array::value('id', $calcStatus, 2), 'join_date' => CRM_Utils_Date::customFormat(CRM_Utils_Array::value('join_date', $dates), $format), 'start_date' => CRM_Utils_Date::customFormat(CRM_Utils_Array::value('start_date', $dates), $format), 'end_date' => CRM_Utils_Date::customFormat(CRM_Utils_Array::value('end_date', $dates), $format), 'reminder_date' => CRM_Utils_Date::customFormat(CRM_Utils_Array::value('reminder_date', $dates), $format)); //we might be renewing membership, //so make status override false. $formatedParams['is_override'] = FALSE; $membership->copyValues($formatedParams); $membership->save(); //updating the membership log $membershipLog = array(); $membershipLog = $formatedParams; $logStartDate = $formatedParams['start_date']; if (CRM_Utils_Array::value('log_start_date', $dates)) { $logStartDate = CRM_Utils_Date::customFormat($dates['log_start_date'], $format); $logStartDate = CRM_Utils_Date::isoToMysql($logStartDate); } $membershipLog['start_date'] = $logStartDate; $membershipLog['membership_id'] = $membership->id; $membershipLog['modified_id'] = $membership->contact_id; $membershipLog['modified_date'] = date('Ymd'); $membershipLog['membership_type_id'] = $membership->membership_type_id; CRM_Member_BAO_MembershipLog::add($membershipLog, CRM_Core_DAO::$_nullArray); //update related Memberships. CRM_Member_BAO_Membership::updateRelatedMemberships($membership->id, $formatedParams); //update the membership type key of membership relatedObjects array //if it has changed after membership update if ($membershipTypeIdKey != $membership->membership_type_id) { $memberships[$membership->membership_type_id] = $membership; $contribution->_relatedObjects['membership'][$membership->membership_type_id] = $membership; unset($contribution->_relatedObjects['membership'][$membershipTypeIdKey]); unset($memberships[$membershipTypeIdKey]); } } } } } else { // event $eventParams = array('id' => $objects['event']->id); $values['event'] = array(); CRM_Event_BAO_Event::retrieve($eventParams, $values['event']); $eventParams = array('id' => $objects['event']->id); $values['event'] = array(); CRM_Event_BAO_Event::retrieve($eventParams, $values['event']); //get location details $locationParams = array('entity_id' => $objects['event']->id, 'entity_table' => 'civicrm_event'); $values['location'] = CRM_Core_BAO_Location::getValues($locationParams); $ufJoinParams = array('entity_table' => 'civicrm_event', 'entity_id' => $ids['event'], 'module' => 'CiviEvent'); list($custom_pre_id, $custom_post_ids) = CRM_Core_BAO_UFJoin::getUFGroupIds($ufJoinParams); $values['custom_pre_id'] = $custom_pre_id; $values['custom_post_id'] = $custom_post_ids; $contribution->source = ts('Online Event Registration') . ': ' . $values['event']['title']; if ($values['event']['is_email_confirm']) { $contribution->receipt_date = self::$_now; $values['is_email_receipt'] = 1; } $participant->status_id = 1; $participant->save(); } if (CRM_Utils_Array::value('net_amount', $input, 0) == 0 && CRM_Utils_Array::value('fee_amount', $input, 0) != 0) { $input['net_amount'] = $input['amount'] - $input['fee_amount']; } $addLineItems = FALSE; if (empty($contribution->id)) { $addLineItems = TRUE; } $contribution->contribution_status_id = 1; $contribution->is_test = $input['is_test']; $contribution->fee_amount = CRM_Utils_Array::value('fee_amount', $input, 0); $contribution->net_amount = CRM_Utils_Array::value('net_amount', $input, 0); $contribution->trxn_id = $input['trxn_id']; $contribution->receive_date = CRM_Utils_Date::isoToMysql($contribution->receive_date); $contribution->thankyou_date = CRM_Utils_Date::isoToMysql($contribution->thankyou_date); $contribution->cancel_date = 'null'; if (CRM_Utils_Array::value('check_number', $input)) { $contribution->check_number = $input['check_number']; } if (CRM_Utils_Array::value('payment_instrument_id', $input)) { $contribution->payment_instrument_id = $input['payment_instrument_id']; } $contribution->save(); //add lineitems for recurring payments if (CRM_Utils_Array::value('contributionRecur', $objects) && $objects['contributionRecur']->id && $addLineItems) { $this->addrecurLineItems($objects['contributionRecur']->id, $contribution->id); } // next create the transaction record $paymentProcessor = ''; if (isset($objects['paymentProcessor'])) { if (is_array($objects['paymentProcessor'])) { $paymentProcessor = $objects['paymentProcessor']['payment_processor_type']; } else { $paymentProcessor = $objects['paymentProcessor']->payment_processor_type; } } if ($contribution->trxn_id) { $trxnParams = array('contribution_id' => $contribution->id, 'trxn_date' => isset($input['trxn_date']) ? $input['trxn_date'] : self::$_now, 'trxn_type' => 'Debit', 'total_amount' => $input['amount'], 'fee_amount' => $contribution->fee_amount, 'net_amount' => $contribution->net_amount, 'currency' => $contribution->currency, 'payment_processor' => $paymentProcessor, 'trxn_id' => $contribution->trxn_id); $trxn = CRM_Core_BAO_FinancialTrxn::create($trxnParams); } self::updateRecurLinkedPledge($contribution); // create an activity record if ($input['component'] == 'contribute') { //CRM-4027 $targetContactID = NULL; if (CRM_Utils_Array::value('related_contact', $ids)) { $targetContactID = $contribution->contact_id; $contribution->contact_id = $ids['related_contact']; } CRM_Activity_BAO_Activity::addActivity($contribution, NULL, $targetContactID); // event } else { CRM_Activity_BAO_Activity::addActivity($participant); } CRM_Core_Error::debug_log_message("Contribution record updated successfully"); $transaction->commit(); // CRM-9132 legacy behaviour was that receipts were sent out in all instances. Still sending // when array_key 'is_email_receipt doesn't exist in case some instances where is needs setting haven't been set if (!array_key_exists('is_email_receipt', $values) || $values['is_email_receipt'] == 1) { self::sendMail($input, $ids, $objects, $values, $recur, FALSE); } CRM_Core_Error::debug_log_message("Success: Database updated and mail sent"); }
/** * Complete an order. * * Do not call this directly - use the contribution.completetransaction api as this function is being refactored. * * Currently overloaded to complete a transaction & repeat a transaction - fix! * * Moving it out of the BaseIPN class is just the first step. * * @param array $input * @param array $ids * @param array $objects * @param CRM_Core_Transaction $transaction * @param int $recur * @param CRM_Contribute_BAO_Contribution $contribution * @param bool $isRecurring * Duplication of param needs review. Only used by AuthorizeNetIPN * @param int $isFirstOrLastRecurringPayment * Deprecated param only used by AuthorizeNetIPN. */ public static function completeOrder(&$input, &$ids, $objects, $transaction, $recur, $contribution, $isRecurring, $isFirstOrLastRecurringPayment) { $primaryContributionID = isset($contribution->id) ? $contribution->id : $objects['first_contribution']->id; // The previous details are used when calculating line items so keep it before any code that 'does something' if (!empty($contribution->id)) { $input['prevContribution'] = CRM_Contribute_BAO_Contribution::getValues(array('id' => $contribution->id), CRM_Core_DAO::$_nullArray, CRM_Core_DAO::$_nullArray); } $inputContributionWhiteList = array('fee_amount', 'net_amount', 'trxn_id', 'check_number', 'payment_instrument_id', 'is_test', 'campaign_id', 'receive_date'); $contributionParams = array_merge(array('contribution_status_id' => 'Completed'), array_intersect_key($input, array_fill_keys($inputContributionWhiteList, 1))); $participant = CRM_Utils_Array::value('participant', $objects); $memberships = CRM_Utils_Array::value('membership', $objects); $recurContrib = CRM_Utils_Array::value('contributionRecur', $objects); if (!empty($recurContrib->id)) { $contributionParams['contribution_recur_id'] = $recurContrib->id; } self::repeatTransaction($contribution, $input, $contributionParams); if (is_numeric($memberships)) { $memberships = array($objects['membership']); } $changeDate = CRM_Utils_Array::value('trxn_date', $input, date('YmdHis')); $values = array(); if (isset($input['is_email_receipt'])) { $values['is_email_receipt'] = $input['is_email_receipt']; } if ($input['component'] == 'contribute') { if ($contribution->contribution_page_id) { CRM_Contribute_BAO_ContributionPage::setValues($contribution->contribution_page_id, $values); $contributionParams['source'] = ts('Online Contribution') . ': ' . $values['title']; } elseif ($recurContrib && $recurContrib->id) { $contributionParams['contribution_page_id'] = NULL; $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'])) { //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; } if (!empty($values['is_email_receipt'])) { $contributionParams['receipt_date'] = $changeDate; } 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); $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 $sql = "\nSELECT membership_type_id\nFROM civicrm_membership_log\nWHERE membership_id={$membershipParams['id']}\nORDER BY id DESC\nLIMIT 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(); $membershipParams['num_terms'] = $contribution->getNumTermsByContributionAndMembershipType($membershipParams['membership_type_id'], $primaryContributionID); $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); $membershipParams['status_id'] = CRM_Utils_Array::value('id', $calcStatus, 'New'); //we might be renewing membership, //so make status override false. $membershipParams['is_override'] = FALSE; civicrm_api3('Membership', 'create', $membershipParams); //update related Memberships. CRM_Member_BAO_Membership::updateRelatedMemberships($membership->id, $membershipParams); } } } } else { if (empty($input['IAmAHorribleNastyBeyondExcusableHackInTheCRMEventFORMTaskClassThatNeedsToBERemoved'])) { $eventDetail = civicrm_api3('Event', 'getsingle', array('id' => $objects['event']->id)); $contributionParams['source'] = ts('Online Event Registration') . ': ' . $eventDetail['title']; if ($eventDetail['is_email_confirm']) { // @todo this should be set by the function that sends the mail after sending. $contributionParams['receipt_date'] = $changeDate; } $participantParams['id'] = $participant->id; $participantParams['status_id'] = 'Registered'; civicrm_api3('Participant', 'create', $participantParams); } } $contributionParams['id'] = $contribution->id; civicrm_api3('Contribution', 'create', $contributionParams); // Add new soft credit against current $contribution. if (CRM_Utils_Array::value('contributionRecur', $objects) && $objects['contributionRecur']->id) { CRM_Contribute_BAO_ContributionRecur::addrecurSoftCredit($objects['contributionRecur']->id, $contribution->id); } $paymentProcessorId = ''; if (isset($objects['paymentProcessor'])) { if (is_array($objects['paymentProcessor'])) { $paymentProcessorId = $objects['paymentProcessor']['id']; } else { $paymentProcessorId = $objects['paymentProcessor']->id; } } $contributionStatuses = CRM_Core_PseudoConstant::get('CRM_Contribute_DAO_Contribution', 'contribution_status_id', array('labelColumn' => 'name', 'flip' => 1)); if (empty($input['prevContribution']) && $paymentProcessorId || !$input['prevContribution']->is_pay_later && $input['prevContribution']->contribution_status_id == $contributionStatuses['Pending']) { $input['payment_processor'] = $paymentProcessorId; } $input['contribution_status_id'] = $contributionStatuses['Completed']; $input['total_amount'] = $input['amount']; $input['contribution'] = $contribution; $input['financial_type_id'] = $contribution->financial_type_id; if (!empty($contribution->_relatedObjects['participant'])) { $input['contribution_mode'] = 'participant'; $input['participant_id'] = $contribution->_relatedObjects['participant']->id; $input['skipLineItem'] = 1; } elseif (!empty($contribution->_relatedObjects['membership'])) { $input['skipLineItem'] = TRUE; $input['contribution_mode'] = 'membership'; } //@todo writing a unit test I was unable to create a scenario where this line did not fatal on second // and subsequent payments. In this case the line items are created at // CRM_Contribute_BAO_ContributionRecur::addRecurLineItems // and since the contribution is saved prior to this line there is always a contribution-id, // however there is never a prevContribution (which appears to mean original contribution not previous // contribution - or preUpdateContributionObject most accurately) // so, this is always called & only appears to succeed when prevContribution exists - which appears // to mean "are we updating an exisitng pending contribution" //I was able to make the unit test complete as fataling here doesn't prevent // the contribution being created - but activities would not be created or emails sent CRM_Contribute_BAO_Contribution::recordFinancialAccounts($input, NULL); CRM_Core_Error::debug_log_message("Contribution record updated successfully"); $transaction->commit(); CRM_Contribute_BAO_ContributionRecur::updateRecurLinkedPledge($contribution); // create an activity record if ($input['component'] == 'contribute') { //CRM-4027 $targetContactID = NULL; if (!empty($ids['related_contact'])) { $targetContactID = $contribution->contact_id; $contribution->contact_id = $ids['related_contact']; } CRM_Activity_BAO_Activity::addActivity($contribution, NULL, $targetContactID); // event } else { CRM_Activity_BAO_Activity::addActivity($participant); } // CRM-9132 legacy behaviour was that receipts were sent out in all instances. Still sending // when array_key 'is_email_receipt doesn't exist in case some instances where is needs setting haven't been set if (!array_key_exists('is_email_receipt', $values) || $values['is_email_receipt'] == 1) { self::sendMail($input, $ids, $objects['contribution'], $values, $recur, FALSE); CRM_Core_Error::debug_log_message("Receipt sent"); } CRM_Core_Error::debug_log_message("Success: Database updated"); if ($isRecurring) { CRM_Contribute_BAO_ContributionRecur::sendRecurringStartOrEndNotification($ids, $recur, $isFirstOrLastRecurringPayment); } }
/** * This method will renew / create the membership depending on * whether the given contact has membership or not. And will add * the modified dates for mebership and in the log table. * * @param int $contactID id of the contact * @param int $membershipTypeID id of the membership type * @param boolean $is_test if this is test contribution or live contribution * @param object $form form object * @param array $ipnParams array of name value pairs, to be used (for e.g source) when $form not present * @param int $modifiedID individual contact id in case of On Behalf signup (CRM-4027 ) * * @return object $membership object of membership * * @static * @access public * **/ static function renewMembership($contactID, $membershipTypeID, $is_test, &$form, $changeToday = null, $modifiedID = null) { require_once 'CRM/Utils/Hook.php'; $statusFormat = '%Y-%m-%d'; $format = '%Y%m%d'; $ids = array(); //get all active statuses of membership. require_once 'CRM/Member/PseudoConstant.php'; $allStatus = CRM_Member_PseudoConstant::membershipStatus(); // check is it pending. - CRM-4555 $pending = false; if (($form->_contributeMode == 'notify' || $form->_params['is_pay_later'] || $form->_params['is_recur'] && $form->_contributeMode == 'direct') && ($form->_values['is_monetary'] && $form->_amount > 0.0)) { $pending = true; } //decide status here, if needed. $updateStatusId = null; if ($currentMembership = CRM_Member_BAO_Membership::getContactMembership($contactID, $membershipTypeID, $is_test, $form->_membershipId)) { $activityType = 'Membership Renewal'; $form->set("renewal_mode", true); // Do NOT do anything. //1. membership with status : PENDING/CANCELLED (CRM-2395) //2. Paylater/IPN renew. CRM-4556. if ($pending || in_array($currentMembership['status_id'], array(array_search('Pending', $allStatus), array_search('Cancelled', $allStatus)))) { $membership = new CRM_Member_DAO_Membership(); $membership->id = $currentMembership['id']; $membership->find(true); return $membership; } //we might renew expired membership, CRM-6277 if (!$changeToday) { if ($form->get('renewDate')) { $changeToday = $form->get('renewDate'); } else { if (get_class($form) == 'CRM_Contribute_Form_Contribution_Confirm') { $changeToday = date('YmdHis'); } } } // Check and fix the membership if it is STALE self::fixMembershipStatusBeforeRenew($currentMembership, $changeToday); // Now Renew the membership if (!$currentMembership['is_current_member']) { // membership is not CURRENT $dates = CRM_Member_BAO_MembershipType::getRenewalDatesForMembershipType($currentMembership['id'], $changeToday); $currentMembership['join_date'] = CRM_Utils_Date::customFormat($currentMembership['join_date'], $format); $currentMembership['start_date'] = CRM_Utils_Array::value('start_date', $dates); $currentMembership['end_date'] = CRM_Utils_Array::value('end_date', $dates); $currentMembership['reminder_date'] = CRM_Utils_Array::value('reminder_date', $dates); $currentMembership['is_test'] = $is_test; if ($form->_params['membership_source']) { $currentMembership['source'] = $form->_params['membership_source']; } else { if ($form->_values['title']) { $currentMembership['source'] = ts('Online Contribution:') . ' ' . $form->_values['title']; } else { $currentMembership['source'] = CRM_Core_DAO::getFieldValue('CRM_Member_DAO_Membership', $currentMembership['id'], 'source'); } } if (CRM_Utils_Array::value('id', $currentMembership)) { $ids['membership'] = $currentMembership['id']; } $memParams = $currentMembership; //set the log start date. $memParams['log_start_date'] = CRM_Utils_Date::customFormat($dates['log_start_date'], $format); } else { // CURRENT Membership $membership = new CRM_Member_DAO_Membership(); $membership->id = $currentMembership['id']; $membership->find(true); require_once 'CRM/Member/BAO/MembershipType.php'; $dates = CRM_Member_BAO_MembershipType::getRenewalDatesForMembershipType($membership->id, $changeToday); // Insert renewed dates for CURRENT membership $memParams = array(); $memParams['join_date'] = CRM_Utils_Date::isoToMysql($membership->join_date); $memParams['start_date'] = CRM_Utils_Date::isoToMysql($membership->start_date); $memParams['end_date'] = CRM_Utils_Array::value('end_date', $dates); $memParams['reminder_date'] = CRM_Utils_Array::value('reminder_date', $dates); //set the log start date. $memParams['log_start_date'] = CRM_Utils_Date::customFormat($dates['log_start_date'], $format); if (empty($membership->source)) { if (CRM_Utils_Array::value('membership_source', $form->_params)) { $currentMembership['source'] = $form->_params['membership_source']; } else { if (CRM_Utils_Array::value('title', $form->_values)) { $currentMembership['source'] = ts('Online Contribution:') . ' ' . $form->_values['title']; } else { $currentMembership['source'] = CRM_Core_DAO::getFieldValue('CRM_Member_DAO_Membership', $currentMembership['id'], 'source'); } } } if (CRM_Utils_Array::value('id', $currentMembership)) { $ids['membership'] = $currentMembership['id']; } } //CRM-4555 if ($pending) { $updateStatusId = array_search('Pending', $allStatus); } } else { // NEW Membership $activityType = 'Membership Signup'; $memParams = array('contact_id' => $contactID, 'membership_type_id' => $membershipTypeID); if (!$pending) { require_once 'CRM/Member/BAO/MembershipType.php'; $dates = CRM_Member_BAO_MembershipType::getDatesForMembershipType($membershipTypeID); $memParams['join_date'] = CRM_Utils_Array::value('join_date', $dates); $memParams['start_date'] = CRM_Utils_Array::value('start_date', $dates); $memParams['end_date'] = CRM_Utils_Array::value('end_date', $dates); $memParams['reminder_date'] = CRM_Utils_Array::value('reminder_date', $dates); require_once 'CRM/Member/BAO/MembershipStatus.php'; $status = CRM_Member_BAO_MembershipStatus::getMembershipStatusByDate(CRM_Utils_Date::customFormat($dates['start_date'], $statusFormat), CRM_Utils_Date::customFormat($dates['end_date'], $statusFormat), CRM_Utils_Date::customFormat($dates['join_date'], $statusFormat), 'today', true); $updateStatusId = CRM_Utils_Array::value('id', $status); } else { // if IPN/Pay-Later set status to: PENDING $updateStatusId = array_search('Pending', $allStatus); } if (CRM_Utils_Array::value('membership_source', $form->_params)) { $memParams['source'] = $form->_params['membership_source']; } else { $memParams['source'] = ts('Online Contribution:') . ' ' . $form->_values['title']; } $memParams['contribution_recur_id'] = CRM_Utils_Array::value('contributionRecurID', $form->_params); $memParams['is_test'] = $is_test; $memParams['is_pay_later'] = $form->_params['is_pay_later']; } //CRM-4555 //if we decided status here and want to skip status //calculation in create( ); than need to pass 'skipStatusCal'. if ($updateStatusId) { $memParams['status_id'] = $updateStatusId; $memParams['skipStatusCal'] = true; } //since we are renewing, //make status override false. $memParams['is_override'] = false; //CRM-4027, create log w/ individual contact. if ($modifiedID) { $ids['userId'] = $modifiedID; $memParams['is_for_organization'] = true; } else { $ids['userId'] = $contactID; } $membership =& self::create($memParams, $ids, false, $activityType); // not sure why this statement is here, seems quite odd :( - Lobo: 12/26/2010 // related to: http://forum.civicrm.org/index.php/topic,11416.msg49072.html#msg49072 $membership->find(true); if (!empty($dates)) { $form->assign('mem_start_date', CRM_Utils_Date::customFormat($dates['start_date'], $format)); $form->assign('mem_end_date', CRM_Utils_Date::customFormat($dates['end_date'], $format)); } return $membership; }
/** * check function getRenewalDatesForMembershipType( ) * */ public function testGetRenewalDatesForMembershipType() { $ids = array(); $params = array('name' => 'General', 'domain_id' => 1, 'description' => NULL, 'minimum_fee' => 100, 'duration_unit' => 'year', 'member_of_contact_id' => $this->_orgContactID, 'period_type' => 'rolling', 'duration_interval' => 1, 'financial_type_id' => $this->_financialTypeId, 'relationship_type_id' => $this->_relationshipTypeId, 'visibility' => 'Public', 'is_active' => 1); $membershipType = CRM_Member_BAO_MembershipType::add($params, $ids); $params = array('contact_id' => $this->_indiviContactID, 'membership_type_id' => $membershipType->id, 'join_date' => '20060121000000', 'start_date' => '20060121000000', 'end_date' => '20070120000000', 'source' => 'Payment', 'is_override' => 1, 'status_id' => $this->_membershipStatusID); $ids = array(); $membership = CRM_Member_BAO_Membership::create($params, $ids); $membershipRenewDates = CRM_Member_BAO_MembershipType::getRenewalDatesForMembershipType($membership->id); $this->assertEquals($membershipRenewDates['start_date'], '20060121', 'Verify membership renewal start date.'); $this->assertEquals($membershipRenewDates['end_date'], '20080120', 'Verify membership renewal end date.'); $this->membershipDelete($membership->id); $this->membershipTypeDelete(array('id' => $membershipType->id)); }
/** * Update contribution as well as related objects. * * @param array $params * @param bool $processContributionObject * * @return array * @throws \Exception */ public static function transitionComponents($params, $processContributionObject = FALSE) { // get minimum required values. $contactId = CRM_Utils_Array::value('contact_id', $params); $componentId = CRM_Utils_Array::value('component_id', $params); $componentName = CRM_Utils_Array::value('componentName', $params); $contributionId = CRM_Utils_Array::value('contribution_id', $params); $contributionStatusId = CRM_Utils_Array::value('contribution_status_id', $params); // if we already processed contribution object pass previous status id. $previousContriStatusId = CRM_Utils_Array::value('previous_contribution_status_id', $params); $updateResult = array(); $contributionStatuses = CRM_Contribute_PseudoConstant::contributionStatus(NULL, 'name'); // we process only ( Completed, Cancelled, or Failed ) contributions. if (!$contributionId || !in_array($contributionStatusId, array(array_search('Completed', $contributionStatuses), array_search('Cancelled', $contributionStatuses), array_search('Failed', $contributionStatuses)))) { return $updateResult; } if (!$componentName || !$componentId) { // get the related component details. $componentDetails = self::getComponentDetails($contributionId); } else { $componentDetails['contact_id'] = $contactId; $componentDetails['component'] = $componentName; if ($componentName == 'event') { $componentDetails['participant'] = $componentId; } else { $componentDetails['membership'] = $componentId; } } if (!empty($componentDetails['contact_id'])) { $componentDetails['contact_id'] = CRM_Core_DAO::getFieldValue('CRM_Contribute_DAO_Contribution', $contributionId, 'contact_id'); } // do check for required ids. if (empty($componentDetails['membership']) && empty($componentDetails['participant']) && empty($componentDetails['pledge_payment']) || empty($componentDetails['contact_id'])) { return $updateResult; } //now we are ready w/ required ids, start processing. $baseIPN = new CRM_Core_Payment_BaseIPN(); $input = $ids = $objects = array(); $input['component'] = CRM_Utils_Array::value('component', $componentDetails); $ids['contribution'] = $contributionId; $ids['contact'] = CRM_Utils_Array::value('contact_id', $componentDetails); $ids['membership'] = CRM_Utils_Array::value('membership', $componentDetails); $ids['participant'] = CRM_Utils_Array::value('participant', $componentDetails); $ids['event'] = CRM_Utils_Array::value('event', $componentDetails); $ids['pledge_payment'] = CRM_Utils_Array::value('pledge_payment', $componentDetails); $ids['contributionRecur'] = NULL; $ids['contributionPage'] = NULL; if (!$baseIPN->validateData($input, $ids, $objects, FALSE)) { CRM_Core_Error::fatal(); } $memberships =& $objects['membership']; $participant =& $objects['participant']; $pledgePayment =& $objects['pledge_payment']; $contribution =& $objects['contribution']; if ($pledgePayment) { $pledgePaymentIDs = array(); foreach ($pledgePayment as $key => $object) { $pledgePaymentIDs[] = $object->id; } $pledgeID = $pledgePayment[0]->pledge_id; } $membershipStatuses = CRM_Member_PseudoConstant::membershipStatus(); if ($participant) { $participantStatuses = CRM_Event_PseudoConstant::participantStatus(); $oldStatus = CRM_Core_DAO::getFieldValue('CRM_Event_DAO_Participant', $participant->id, 'status_id'); } // we might want to process contribution object. $processContribution = FALSE; if ($contributionStatusId == array_search('Cancelled', $contributionStatuses)) { if (is_array($memberships)) { foreach ($memberships as $membership) { if ($membership) { $membership->status_id = array_search('Cancelled', $membershipStatuses); $membership->save(); $updateResult['updatedComponents']['CiviMember'] = $membership->status_id; if ($processContributionObject) { $processContribution = TRUE; } } } } if ($participant) { $updatedStatusId = array_search('Cancelled', $participantStatuses); CRM_Event_BAO_Participant::updateParticipantStatus($participant->id, $oldStatus, $updatedStatusId, TRUE); $updateResult['updatedComponents']['CiviEvent'] = $updatedStatusId; if ($processContributionObject) { $processContribution = TRUE; } } if ($pledgePayment) { CRM_Pledge_BAO_PledgePayment::updatePledgePaymentStatus($pledgeID, $pledgePaymentIDs, $contributionStatusId); $updateResult['updatedComponents']['CiviPledge'] = $contributionStatusId; if ($processContributionObject) { $processContribution = TRUE; } } } elseif ($contributionStatusId == array_search('Failed', $contributionStatuses)) { if (is_array($memberships)) { foreach ($memberships as $membership) { if ($membership) { $membership->status_id = array_search('Expired', $membershipStatuses); $membership->save(); $updateResult['updatedComponents']['CiviMember'] = $membership->status_id; if ($processContributionObject) { $processContribution = TRUE; } } } } if ($participant) { $updatedStatusId = array_search('Cancelled', $participantStatuses); CRM_Event_BAO_Participant::updateParticipantStatus($participant->id, $oldStatus, $updatedStatusId, TRUE); $updateResult['updatedComponents']['CiviEvent'] = $updatedStatusId; if ($processContributionObject) { $processContribution = TRUE; } } if ($pledgePayment) { CRM_Pledge_BAO_PledgePayment::updatePledgePaymentStatus($pledgeID, $pledgePaymentIDs, $contributionStatusId); $updateResult['updatedComponents']['CiviPledge'] = $contributionStatusId; if ($processContributionObject) { $processContribution = TRUE; } } } elseif ($contributionStatusId == array_search('Completed', $contributionStatuses)) { // only pending contribution related object processed. if ($previousContriStatusId && $previousContriStatusId != array_search('Pending', $contributionStatuses)) { // this is case when we already processed contribution object. return $updateResult; } elseif (!$previousContriStatusId && $contribution->contribution_status_id != array_search('Pending', $contributionStatuses)) { // this is case when we are going to process contribution object later. return $updateResult; } if (is_array($memberships)) { foreach ($memberships as $membership) { if ($membership) { $format = '%Y%m%d'; //CRM-4523 $currentMembership = CRM_Member_BAO_Membership::getContactMembership($membership->contact_id, $membership->membership_type_id, $membership->is_test, $membership->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 $sql = "\n SELECT membership_type_id\n FROM civicrm_membership_log\n WHERE membership_id={$membership->id}\n ORDER BY id DESC\n LIMIT 1;"; $dao = new CRM_Core_DAO(); $dao->query($sql); if ($dao->fetch()) { if (!empty($dao->membership_type_id)) { $membership->membership_type_id = $dao->membership_type_id; $membership->save(); } } // else fall back to using current membership type $dao->free(); // Figure out number of terms $numterms = 1; $lineitems = CRM_Price_BAO_LineItem::getLineItems($contributionId, 'contribution'); foreach ($lineitems as $lineitem) { if ($membership->membership_type_id == CRM_Utils_Array::value('membership_type_id', $lineitem)) { $numterms = CRM_Utils_Array::value('membership_num_terms', $lineitem); // in case membership_num_terms comes through as null or zero $numterms = $numterms >= 1 ? $numterms : 1; break; } } // CRM-15735-to update the membership status as per the contribution receive date $joinDate = NULL; if (!empty($params['receive_date'])) { $joinDate = $params['receive_date']; $status = CRM_Member_BAO_MembershipStatus::getMembershipStatusByDate($membership->start_date, $membership->end_date, $membership->join_date, $params['receive_date'], FALSE, $membership->membership_type_id, (array) $membership); $membership->status_id = CRM_Utils_Array::value('id', $status, $membership->status_id); $membership->save(); } if ($currentMembership) { CRM_Member_BAO_Membership::fixMembershipStatusBeforeRenew($currentMembership, NULL); $dates = CRM_Member_BAO_MembershipType::getRenewalDatesForMembershipType($membership->id, NULL, NULL, $numterms); $dates['join_date'] = CRM_Utils_Date::customFormat($currentMembership['join_date'], $format); } else { $dates = CRM_Member_BAO_MembershipType::getDatesForMembershipType($membership->membership_type_id, $joinDate, NULL, NULL, $numterms); } //get the status for membership. $calcStatus = CRM_Member_BAO_MembershipStatus::getMembershipStatusByDate($dates['start_date'], $dates['end_date'], $dates['join_date'], 'today', TRUE, $membership->membership_type_id, (array) $membership); $formattedParams = array('status_id' => CRM_Utils_Array::value('id', $calcStatus, array_search('Current', $membershipStatuses)), 'join_date' => CRM_Utils_Date::customFormat($dates['join_date'], $format), 'start_date' => CRM_Utils_Date::customFormat($dates['start_date'], $format), 'end_date' => CRM_Utils_Date::customFormat($dates['end_date'], $format)); CRM_Utils_Hook::pre('edit', 'Membership', $membership->id, $formattedParams); $membership->copyValues($formattedParams); $membership->save(); //updating the membership log $membershipLog = array(); $membershipLog = $formattedParams; $logStartDate = CRM_Utils_Date::customFormat(CRM_Utils_Array::value('log_start_date', $dates), $format); $logStartDate = $logStartDate ? CRM_Utils_Date::isoToMysql($logStartDate) : $formattedParams['start_date']; $membershipLog['start_date'] = $logStartDate; $membershipLog['membership_id'] = $membership->id; $membershipLog['modified_id'] = $membership->contact_id; $membershipLog['modified_date'] = date('Ymd'); $membershipLog['membership_type_id'] = $membership->membership_type_id; CRM_Member_BAO_MembershipLog::add($membershipLog, CRM_Core_DAO::$_nullArray); //update related Memberships. CRM_Member_BAO_Membership::updateRelatedMemberships($membership->id, $formattedParams); $updateResult['membership_end_date'] = CRM_Utils_Date::customFormat($dates['end_date'], '%B %E%f, %Y'); $updateResult['updatedComponents']['CiviMember'] = $membership->status_id; if ($processContributionObject) { $processContribution = TRUE; } CRM_Utils_Hook::post('edit', 'Membership', $membership->id, $membership); } } } if ($participant) { $updatedStatusId = array_search('Registered', $participantStatuses); CRM_Event_BAO_Participant::updateParticipantStatus($participant->id, $oldStatus, $updatedStatusId, TRUE); $updateResult['updatedComponents']['CiviEvent'] = $updatedStatusId; if ($processContributionObject) { $processContribution = TRUE; } } if ($pledgePayment) { CRM_Pledge_BAO_PledgePayment::updatePledgePaymentStatus($pledgeID, $pledgePaymentIDs, $contributionStatusId); $updateResult['updatedComponents']['CiviPledge'] = $contributionStatusId; if ($processContributionObject) { $processContribution = TRUE; } } } // process contribution object. if ($processContribution) { $contributionParams = array(); $fields = array('contact_id', 'total_amount', 'receive_date', 'is_test', 'campaign_id', 'payment_instrument_id', 'trxn_id', 'invoice_id', 'financial_type_id', 'contribution_status_id', 'non_deductible_amount', 'receipt_date', 'check_number'); foreach ($fields as $field) { if (empty($params[$field])) { continue; } $contributionParams[$field] = $params[$field]; } $ids = array('contribution' => $contributionId); $contribution = CRM_Contribute_BAO_Contribution::create($contributionParams, $ids); } return $updateResult; }
function completeTransaction(&$input, &$ids, &$objects, &$transaction, $recur = false) { $contribution =& $objects['contribution']; $membership =& $objects['membership']; $participant =& $objects['participant']; $event =& $objects['event']; $values = array(); if ($input['component'] == 'contribute') { require_once 'CRM/Contribute/BAO/ContributionPage.php'; CRM_Contribute_BAO_ContributionPage::setValues($contribution->contribution_page_id, $values); $contribution->source = ts('Online Contribution') . ': ' . $values['title']; if ($values['is_email_receipt']) { $contribution->receipt_date = self::$_now; } if ($membership) { $format = '%Y%m%d'; require_once 'CRM/Member/BAO/MembershipType.php'; require_once 'CRM/Member/BAO/Membership.php'; $currentMembership = CRM_Member_BAO_Membership::getContactMembership($membership->contact_id, $membership->membership_type_id, $membership->is_test, $membership->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, $changeToday = null); $dates = CRM_Member_BAO_MembershipType::getRenewalDatesForMembershipType($membership->id, $changeToday = null); $dates['join_date'] = CRM_Utils_Date::customFormat($currentMembership['join_date'], $format); } else { $dates = CRM_Member_BAO_MembershipType::getDatesForMembershipType($membership->membership_type_id); } //get the status for membership. require_once 'CRM/Member/BAO/MembershipStatus.php'; $calcStatus = CRM_Member_BAO_MembershipStatus::getMembershipStatusByDate($dates['start_date'], $dates['end_date'], $dates['join_date'], 'today', true); $formatedParams = array('status_id' => CRM_Utils_Array::value('id', $calcStatus, 2), 'join_date' => CRM_Utils_Date::customFormat($dates['join_date'], $format), 'start_date' => CRM_Utils_Date::customFormat($dates['start_date'], $format), 'end_date' => CRM_Utils_Date::customFormat($dates['end_date'], $format), 'reminder_date' => CRM_Utils_Date::customFormat($dates['reminder_date'], $format)); $membership->copyValues($formatedParams); $membership->save(); //updating the membership log $membershipLog = array(); $membershipLog = $formatedParams; $logStartDate = CRM_Utils_Date::customFormat($dates['log_start_date'], $format); $logStartDate = $logStartDate ? CRM_Utils_Date::isoToMysql($logStartDate) : $formatedParams['start_date']; $membershipLog['start_date'] = $logStartDate; $membershipLog['membership_id'] = $membership->id; $membershipLog['modified_id'] = $membership->contact_id; $membershipLog['modified_date'] = date('Ymd'); require_once 'CRM/Member/BAO/MembershipLog.php'; CRM_Member_BAO_MembershipLog::add($membershipLog, CRM_Core_DAO::$_nullArray); //update related Memberships. CRM_Member_BAO_Membership::updateRelatedMemberships($membership->id, $formatedParams); } } else { // event $eventParams = array('id' => $objects['event']->id); $values['event'] = array(); require_once 'CRM/Event/BAO/Event.php'; CRM_Event_BAO_Event::retrieve($eventParams, $values['event']); $eventParams = array('id' => $objects['event']->id); $values['event'] = array(); require_once 'CRM/Event/BAO/Event.php'; CRM_Event_BAO_Event::retrieve($eventParams, $values['event']); //get location details $locationParams = array('entity_id' => $objects['event']->id, 'entity_table' => 'civicrm_event'); require_once 'CRM/Core/BAO/Location.php'; require_once 'CRM/Event/Form/ManageEvent/Location.php'; $values['location'] = CRM_Core_BAO_Location::getValues($locationParams); require_once 'CRM/Core/BAO/UFJoin.php'; $ufJoinParams = array('entity_table' => 'civicrm_event', 'entity_id' => $ids['event'], 'weight' => 1); $values['custom_pre_id'] = CRM_Core_BAO_UFJoin::findUFGroupId($ufJoinParams); $ufJoinParams['weight'] = 2; $values['custom_post_id'] = CRM_Core_BAO_UFJoin::findUFGroupId($ufJoinParams); $contribution->source = ts('Online Event Registration') . ': ' . $values['event']['title']; if ($values['event']['is_email_confirm']) { $contribution->receipt_date = self::$_now; } $participant->status_id = 1; $participant->save(); } if ($input['net_amount'] == 0 && $input['fee_amount'] != 0) { $input['net_amount'] = $input['amount'] - $input['fee_amount']; } $contribution->contribution_status_id = 1; $contribution->is_test = $input['is_test']; $contribution->fee_amount = $input['fee_amount']; $contribution->net_amount = $input['net_amount']; $contribution->trxn_id = $input['trxn_id']; $contribution->receive_date = CRM_Utils_Date::isoToMysql($contribution->receive_date); $contribution->cancel_date = 'null'; if (CRM_Utils_Array::value('check_number', $input)) { $contribution->check_number = $input['check_number']; } if (CRM_Utils_Array::value('payment_instrument_id', $input)) { $contribution->payment_instrument_id = $input['payment_instrument_id']; } $contribution->save(); // next create the transaction record if (isset($objects['paymentProcessor'])) { $paymentProcessor = $objects['paymentProcessor']['payment_processor_type']; } else { $paymentProcessor = ''; } if ($contribution->trxn_id) { $trxnParams = array('contribution_id' => $contribution->id, 'trxn_date' => isset($input['trxn_date']) ? $input['trxn_date'] : self::$_now, 'trxn_type' => 'Debit', 'total_amount' => $input['amount'], 'fee_amount' => $contribution->fee_amount, 'net_amount' => $contribution->net_amount, 'currency' => $contribution->currency, 'payment_processor' => $paymentProcessor, 'trxn_id' => $contribution->trxn_id); require_once 'CRM/Contribute/BAO/FinancialTrxn.php'; $trxn =& CRM_Contribute_BAO_FinancialTrxn::create($trxnParams); } //update corresponding pledge payment record require_once 'CRM/Core/DAO.php'; $returnProperties = array('id', 'pledge_id'); if (CRM_Core_DAO::commonRetrieveAll('CRM_Pledge_DAO_Payment', 'contribution_id', $contribution->id, $paymentDetails, $returnProperties)) { $paymentIDs = array(); foreach ($paymentDetails as $key => $value) { $paymentIDs[] = $value['id']; $pledgeId = $value['pledge_id']; } // update pledge and corresponding payment statuses require_once 'CRM/Pledge/BAO/Payment.php'; CRM_Pledge_BAO_Payment::updatePledgePaymentStatus($pledgeId, $paymentIDs, $contribution->contribution_status_id); } // create an activity record require_once "CRM/Activity/BAO/Activity.php"; if ($input['component'] == 'contribute') { //CRM-4027 $targetContactID = null; if (CRM_Utils_Array::value('related_contact', $ids)) { $targetContactID = $contribution->contact_id; $contribution->contact_id = $ids['related_contact']; } CRM_Activity_BAO_Activity::addActivity($contribution, null, $targetContactID); } else { // event CRM_Activity_BAO_Activity::addActivity($participant); } CRM_Core_Error::debug_log_message("Contribution record updated successfully"); $transaction->commit(); self::sendMail($input, $ids, $objects, $values, $recur, false); CRM_Core_Error::debug_log_message("Success: Database updated and mail sent"); }
/** * @todo - this form method needs to have the interaction with the form layer removed from it * as a BAO function. Note that the api now supports membership renewals & it is not clear this function does anything * not done by the membership.create api (with a lot less unit tests) * * This method will renew / create the membership depending on * whether the given contact has a membership or not. And will add * the modified dates for membership and in the log table. * * @param int $contactID id of the contact * @param int $membershipTypeID id of the new membership type * @param boolean $is_test if this is test contribution or live contribution * @param object $form form object * @param array $ipnParams array of name value pairs, to be used (for e.g source) when $form not present * @param int $modifiedID individual contact id in case of On Behalf signup (CRM-4027 ) * @param int $numRenewTerms how many membership terms are being added to end date (default is 1) * * @return object $membership object of membership * * @static * @access public * **/ static function renewMembership($contactID, $membershipTypeID, $is_test, &$form, $changeToday = NULL, $modifiedID = NULL, $customFieldsFormatted = NULL, $numRenewTerms = 1, $paymentConfirmed = FALSE) { $statusFormat = '%Y-%m-%d'; $format = '%Y%m%d'; $ids = array(); //get all active statuses of membership. $allStatus = CRM_Member_PseudoConstant::membershipStatus(); $membershipTypeDetails = CRM_Member_BAO_MembershipType::getMembershipTypeDetails($membershipTypeID); // check is it pending. - CRM-4555 $pending = FALSE; //@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' || CRM_Utils_Array::value('is_pay_later', $form->_params) || CRM_Utils_Array::value('is_recur', $form->_params) && $form->_contributeMode == 'direct') && ($form->_values['is_monetary'] && $form->_amount > 0.0 || CRM_Utils_Array::value('separate_membership_payment', $form->_params) || CRM_Utils_Array::value('record_contribution', $form->_params))) { $pending = TRUE; } } if ($paymentConfirmed) { $pending = FALSE; } //decide status here, if needed. $updateStatusId = NULL; $membershipID = NULL; //@todo would be better to accept $membershipID as an FN param & make form layer responsible for extracting it if (isset($form->_membershipId)) { $membershipID = $form->_membershipId; } // CRM-7297 - allow membership type to be be changed during renewal so long as the parent org of new membershipType // is the same as the parent org of an existing membership of the contact $currentMembership = CRM_Member_BAO_Membership::getContactMembership($contactID, $membershipTypeID, $is_test, $membershipID, TRUE); if ($currentMembership) { $activityType = 'Membership Renewal'; $form->set('renewal_mode', TRUE); // Do NOT do anything. //1. membership with status : PENDING/CANCELLED (CRM-2395) //2. Paylater/IPN renew. CRM-4556. if ($pending || in_array($currentMembership['status_id'], array(array_search('Pending', $allStatus), array_search('Cancelled', $allStatus)))) { $membership = new CRM_Member_DAO_Membership(); $membership->id = $currentMembership['id']; $membership->find(TRUE); // CRM-8141 create a membership_log entry so that we will know the membership_type_id to change to when payment completed $format = '%Y%m%d'; // note that we are logging the requested new membership_type_id that may be different than current membership_type_id // it will be used when payment is received to update the membership_type_id to what was paid for $logParams = array('membership_id' => $membership->id, 'status_id' => $membership->status_id, 'start_date' => CRM_Utils_Date::customFormat($membership->start_date, $format), 'end_date' => CRM_Utils_Date::customFormat($membership->end_date, $format), 'modified_date' => CRM_Utils_Date::customFormat(date('Ymd'), $format), 'membership_type_id' => $membershipTypeID, 'max_related' => $membershipTypeDetails['max_related']); $session = CRM_Core_Session::singleton(); // If we have an authenticated session, set modified_id to that user's contact_id, else set to membership.contact_id if ($session->get('userID')) { $logParams['modified_id'] = $session->get('userID'); } else { $logParams['modified_id'] = $membership->contact_id; } CRM_Member_BAO_MembershipLog::add($logParams, CRM_Core_DAO::$_nullArray); if (CRM_Utils_Array::value('contributionRecurID', $form->_params)) { CRM_Core_DAO::setFieldValue('CRM_Member_DAO_Membership', $membership->id, 'contribution_recur_id', $form->_params['contributionRecurID']); } return $membership; } //we renew expired membership, CRM-6277 if (!$changeToday) { if ($form->get('renewalDate')) { $changeToday = $form->get('renewalDate'); } elseif (get_class($form) == 'CRM_Contribute_Form_Contribution_Confirm') { $changeToday = date('YmdHis'); } } // Check and fix the membership if it is STALE self::fixMembershipStatusBeforeRenew($currentMembership, $changeToday); // Now Renew the membership if (!$currentMembership['is_current_member']) { // membership is not CURRENT // CRM-7297 Membership Upsell - calculate dates based on new membership type $dates = CRM_Member_BAO_MembershipType::getRenewalDatesForMembershipType($currentMembership['id'], $changeToday, $membershipTypeID, $numRenewTerms); $currentMembership['join_date'] = CRM_Utils_Date::customFormat($currentMembership['join_date'], $format); $currentMembership['start_date'] = CRM_Utils_Array::value('start_date', $dates); $currentMembership['end_date'] = CRM_Utils_Array::value('end_date', $dates); $currentMembership['is_test'] = $is_test; if (CRM_Utils_Array::value('membership_source', $form->_params)) { $currentMembership['source'] = $form->_params['membership_source']; } elseif (isset($form->_values['title']) && !empty($form->_values['title'])) { $currentMembership['source'] = ts('Online Contribution:') . ' ' . $form->_values['title']; } else { $currentMembership['source'] = CRM_Core_DAO::getFieldValue('CRM_Member_DAO_Membership', $currentMembership['id'], 'source'); } if (CRM_Utils_Array::value('id', $currentMembership)) { $ids['membership'] = $currentMembership['id']; } $memParams = $currentMembership; $memParams['membership_type_id'] = $membershipTypeID; //set the log start date. $memParams['log_start_date'] = CRM_Utils_Date::customFormat($dates['log_start_date'], $format); } else { // CURRENT Membership $membership = new CRM_Member_DAO_Membership(); $membership->id = $currentMembership['id']; $membership->find(TRUE); // CRM-7297 Membership Upsell - calculate dates based on new membership type $dates = CRM_Member_BAO_MembershipType::getRenewalDatesForMembershipType($membership->id, $changeToday, $membershipTypeID, $numRenewTerms); // Insert renewed dates for CURRENT membership $memParams = array(); $memParams['join_date'] = CRM_Utils_Date::isoToMysql($membership->join_date); $memParams['start_date'] = CRM_Utils_Date::isoToMysql($membership->start_date); $memParams['end_date'] = CRM_Utils_Array::value('end_date', $dates); $memParams['membership_type_id'] = $membershipTypeID; //set the log start date. $memParams['log_start_date'] = CRM_Utils_Date::customFormat($dates['log_start_date'], $format); if (empty($membership->source)) { if (CRM_Utils_Array::value('membership_source', $form->_params)) { $memParams['source'] = $form->_params['membership_source']; } elseif (property_exists($form, '_values') && CRM_Utils_Array::value('title', $form->_values)) { $memParams['source'] = ts('Online Contribution:') . ' ' . $form->_values['title']; } else { $memParams['source'] = CRM_Core_DAO::getFieldValue('CRM_Member_DAO_Membership', $currentMembership['id'], 'source'); } } if (CRM_Utils_Array::value('id', $currentMembership)) { $ids['membership'] = $currentMembership['id']; } } //CRM-4555 if ($pending) { $updateStatusId = array_search('Pending', $allStatus); } } else { // NEW Membership $activityType = 'Membership Signup'; $memParams = array('contact_id' => $contactID, 'membership_type_id' => $membershipTypeID); if (!$pending) { $dates = CRM_Member_BAO_MembershipType::getDatesForMembershipType($membershipTypeID, NULL, NULL, NULL, $numRenewTerms); $memParams['join_date'] = CRM_Utils_Array::value('join_date', $dates); $memParams['start_date'] = CRM_Utils_Array::value('start_date', $dates); $memParams['end_date'] = CRM_Utils_Array::value('end_date', $dates); $status = CRM_Member_BAO_MembershipStatus::getMembershipStatusByDate(CRM_Utils_Date::customFormat($dates['start_date'], $statusFormat), CRM_Utils_Date::customFormat($dates['end_date'], $statusFormat), CRM_Utils_Date::customFormat($dates['join_date'], $statusFormat), 'today', TRUE, $membershipTypeID, $memParams); $updateStatusId = CRM_Utils_Array::value('id', $status); } else { // if IPN/Pay-Later set status to: PENDING $updateStatusId = array_search('Pending', $allStatus); } if (CRM_Utils_Array::value('membership_source', $form->_params)) { $memParams['source'] = $form->_params['membership_source']; } elseif (CRM_Utils_Array::value('title', $form->_values)) { $memParams['source'] = ts('Online Contribution:') . ' ' . $form->_values['title']; } $memParams['contribution_recur_id'] = CRM_Utils_Array::value('contributionRecurID', $form->_params); $memParams['is_test'] = $is_test; $memParams['is_pay_later'] = CRM_Utils_Array::value('is_pay_later', $form->_params); } //CRM-4555 //if we decided status here and want to skip status //calculation in create( ); then need to pass 'skipStatusCal'. if ($updateStatusId) { $memParams['status_id'] = $updateStatusId; $memParams['skipStatusCal'] = TRUE; } //since we are renewing, //make status override false. $memParams['is_override'] = FALSE; //CRM-4027, create log w/ individual contact. if ($modifiedID) { $ids['userId'] = $modifiedID; $memParams['is_for_organization'] = TRUE; } else { $ids['userId'] = $contactID; } //inherit campaign from contrib page. if (isset($form->_values) && is_array($form->_values) && !empty($form->_values)) { $campaignId = CRM_Utils_Array::value('campaign_id', $form->_params); if (!array_key_exists('campaign_id', $form->_params)) { $campaignId = CRM_Utils_Array::value('campaign_id', $form->_values); } $memParams['campaign_id'] = $campaignId; } $memParams['custom'] = $customFieldsFormatted; $membership = self::create($memParams, $ids, FALSE, $activityType); // not sure why this statement is here, seems quite odd :( - Lobo: 12/26/2010 // related to: http://forum.civicrm.org/index.php/topic,11416.msg49072.html#msg49072 $membership->find(TRUE); if (!empty($dates)) { $form->assign('mem_start_date', CRM_Utils_Date::customFormat($dates['start_date'], $format)); $form->assign('mem_end_date', CRM_Utils_Date::customFormat($dates['end_date'], $format)); } return $membership; }
/** * Complete an order. * * Do not call this directly - use the contribution.completetransaction api as this function is being refactored. * * Currently overloaded to complete a transaction & repeat a transaction - fix! * * Moving it out of the BaseIPN class is just the first step. * * @param array $input * @param array $ids * @param array $objects * @param CRM_Core_Transaction $transaction * @param int $recur * @param CRM_Contribute_BAO_Contribution $contribution * @param bool $isRecurring * Duplication of param needs review. Only used by AuthorizeNetIPN * @param int $isFirstOrLastRecurringPayment * Deprecated param only used by AuthorizeNetIPN. */ public static function completeOrder(&$input, &$ids, $objects, $transaction, $recur, $contribution, $isRecurring, $isFirstOrLastRecurringPayment) { $primaryContributionID = isset($contribution->id) ? $contribution->id : $objects['first_contribution']->id; // The previous details are used when calculating line items so keep it before any code that 'does something' if (!empty($contribution->id)) { $input['prevContribution'] = CRM_Contribute_BAO_Contribution::getValues(array('id' => $contribution->id), CRM_Core_DAO::$_nullArray, CRM_Core_DAO::$_nullArray); } $inputContributionWhiteList = array('fee_amount', 'net_amount', 'trxn_id', 'check_number', 'payment_instrument_id', 'is_test', 'campaign_id', 'receive_date', 'receipt_date', 'contribution_status_id'); if (self::isSingleLineItem($primaryContributionID)) { $inputContributionWhiteList[] = 'financial_type_id'; } $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); $paymentProcessorId = ''; if (isset($objects['paymentProcessor'])) { if (is_array($objects['paymentProcessor'])) { $paymentProcessorId = $objects['paymentProcessor']['id']; } else { $paymentProcessorId = $objects['paymentProcessor']->id; } } $completedContributionStatusID = CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'contribution_status_id', 'Completed'); $contributionParams = array_merge(array('contribution_status_id' => $completedContributionStatusID, 'source' => self::getRecurringContributionDescription($contribution, $event)), array_intersect_key($input, array_fill_keys($inputContributionWhiteList, 1))); $contributionParams['payment_processor'] = $input['payment_processor'] = $paymentProcessorId; if ($recurringContributionID) { $contributionParams['contribution_recur_id'] = $recurringContributionID; } $changeDate = CRM_Utils_Array::value('trxn_date', $input, date('YmdHis')); if (empty($contributionParams['receive_date']) && $changeDate) { $contributionParams['receive_date'] = $changeDate; } self::repeatTransaction($contribution, $input, $contributionParams, $paymentProcessorId); $contributionParams['financial_type_id'] = $contribution->financial_type_id; if (is_numeric($memberships)) { $memberships = array($objects['membership']); } $values = array(); if (isset($input['is_email_receipt'])) { $values['is_email_receipt'] = $input['is_email_receipt']; } if ($input['component'] == 'contribute') { if ($contribution->contribution_page_id) { // Figure out what we gain from this. CRM_Contribute_BAO_ContributionPage::setValues($contribution->contribution_page_id, $values); } elseif ($recurContrib && $recurringContributionID) { $values['amount'] = $recurContrib->amount; $values['financial_type_id'] = $objects['contributionType']->id; $values['title'] = $source = ts('Offline Recurring Contribution'); } 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; } 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); $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 $sql = "\nSELECT membership_type_id\nFROM civicrm_membership_log\nWHERE membership_id={$membershipParams['id']}\nORDER BY id DESC\nLIMIT 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(); $membershipParams['num_terms'] = $contribution->getNumTermsByContributionAndMembershipType($membershipParams['membership_type_id'], $primaryContributionID); $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); $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() $var = TRUE; CRM_Member_BAO_Membership::createRelatedMemberships($var, $var, TRUE); civicrm_api3('Membership', 'create', $membershipParams); } } } } else { if (empty($input['IAmAHorribleNastyBeyondExcusableHackInTheCRMEventFORMTaskClassThatNeedsToBERemoved'])) { if ($event->is_email_confirm) { // @todo this should be set by the function that sends the mail after sending. $contributionParams['receipt_date'] = $changeDate; } $participantParams['id'] = $participant->id; $participantParams['status_id'] = 'Registered'; civicrm_api3('Participant', 'create', $participantParams); } } $contributionParams['id'] = $contribution->id; // CRM-19309 - if you update the contribution here with financial_type_id it can/will mess with $lineItem // unsetting it here does NOT cause any other contribution test to fail! unset($contributionParams['financial_type_id']); $contributionResult = civicrm_api3('Contribution', 'create', $contributionParams); // Add new soft credit against current $contribution. if (CRM_Utils_Array::value('contributionRecur', $objects) && $objects['contributionRecur']->id) { CRM_Contribute_BAO_ContributionRecur::addrecurSoftCredit($objects['contributionRecur']->id, $contribution->id); } $contributionStatuses = CRM_Core_PseudoConstant::get('CRM_Contribute_DAO_Contribution', 'contribution_status_id', array('labelColumn' => 'name', 'flip' => 1)); if (isset($input['prevContribution']) && (!$input['prevContribution']->is_pay_later && $input['prevContribution']->contribution_status_id == $contributionStatuses['Pending'])) { $input['payment_processor'] = $paymentProcessorId; } if (!empty($contribution->_relatedObjects['participant'])) { $input['contribution_mode'] = 'participant'; $input['participant_id'] = $contribution->_relatedObjects['participant']->id; } elseif (!empty($contribution->_relatedObjects['membership'])) { $input['contribution_mode'] = 'membership'; $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); } CRM_Core_Error::debug_log_message("Contribution record updated successfully"); $transaction->commit(); CRM_Contribute_BAO_ContributionRecur::updateRecurLinkedPledge($contribution->id, $recurringContributionID, $contributionParams['contribution_status_id'], $input['amount']); // create an activity record if ($input['component'] == 'contribute') { //CRM-4027 $targetContactID = NULL; if (!empty($ids['related_contact'])) { $targetContactID = $contribution->contact_id; $contribution->contact_id = $ids['related_contact']; } CRM_Activity_BAO_Activity::addActivity($contribution, NULL, $targetContactID); // event } else { CRM_Activity_BAO_Activity::addActivity($participant); } // CRM-9132 legacy behaviour was that receipts were sent out in all instances. Still sending // when array_key 'is_email_receipt doesn't exist in case some instances where is needs setting haven't been set if (!array_key_exists('is_email_receipt', $values) || $values['is_email_receipt'] == 1) { civicrm_api3('Contribution', 'sendconfirmation', array('id' => $contribution->id, 'payment_processor_id' => $paymentProcessorId)); CRM_Core_Error::debug_log_message("Receipt sent"); } CRM_Core_Error::debug_log_message("Success: Database updated"); if ($isRecurring) { CRM_Contribute_BAO_ContributionRecur::sendRecurringStartOrEndNotification($ids, $recur, $isFirstOrLastRecurringPayment); } return $contributionResult; }
function testGetRenewalDatesForMembershipType() { require_once 'CRM/Member/BAO/Membership.php'; $ids = array('memberOfContact' => $this->_orgContactID); $params = array('name' => 'General', 'description' => null, 'minimum_fee' => 100, 'duration_unit' => 'year', 'period_type' => 'rolling', 'duration_interval' => 1, 'contribution_type_id' => $this->_contributionTypeId, 'relationship_type_id' => $this->_relationshipTypeId, 'visibility' => 'Public', 'is_active' => 1); $membershipType = CRM_Member_BAO_MembershipType::add($params, $ids); $params = array('contact_id' => $this->_indiviContactID, 'membership_type_id' => $membershipType->id, 'join_date' => '2006-01-21', 'start_date' => '2006-01-21', 'end_date' => '2006-12-21', 'source' => 'Payment', 'is_override' => 1, 'status_id' => $this->_membershipStatusID); $ids = array(); $membership = CRM_Member_BAO_Membership::create($params, $ids); $membershipRenewDates = CRM_Member_BAO_MembershipType::getRenewalDatesForMembershipType($membership->id); $this->assertEquals($membershipRenewDates['start_date'], '20060121', 'Verify membership renewal start date.'); $this->assertEquals($membershipRenewDates['end_date'], '20071221', 'Verify membership renewal end date.'); }