$setPrevContribution = TRUE;
// CRM-13964 partial payment
- if (!empty($params['partial_payment_total']) && !empty($params['partial_amount_pay'])) {
+ if (!empty($params['partial_payment_total']) && !empty($params['partial_amount_to_pay'])) {
$partialAmtTotal = $params['partial_payment_total'];
- $partialAmtPay = $params['partial_amount_pay'];
+ $partialAmtPay = $params['partial_amount_to_pay'];
$params['total_amount'] = $partialAmtTotal;
if ($partialAmtPay < $partialAmtTotal) {
$params['contribution_status_id'] = CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'contribution_status_id', 'Partially paid');
if (self::isUpdateToRecurringContribution($params)) {
CRM_Contribute_BAO_ContributionRecur::updateOnNewPayment(
(!empty($params['contribution_recur_id']) ? $params['contribution_recur_id'] : $params['prevContribution']->contribution_recur_id),
- $contributionStatus[$params['contribution_status_id']]
+ $contributionStatus[$params['contribution_status_id']],
+ CRM_Utils_Array::value('receive_date', $params)
);
}
CRM_Core_DAO::setFieldValue('CRM_Activity_BAO_Activity', $activity['id'], 'campaign_id', $contribution->campaign_id);
$contribution->activity_id = $activity['id'];
}
+
if (empty($contribution->contact_id)) {
$contribution->find(TRUE);
}
- CRM_Activity_BAO_Activity::addActivity($contribution, 'Offline');
+ CRM_Activity_BAO_Activity::addActivity($contribution, 'Contribution');
// do not add to recent items for import, CRM-4399
if (empty($params['skipRecentView'])) {
if ($contributionStatusId == array_search('Cancelled', $contributionStatuses)) {
if (is_array($memberships)) {
foreach ($memberships as $membership) {
- if ($membership) {
+ $update = TRUE;
+ //Update Membership status if there is no other completed contribution associated with the membership.
+ $relatedContributions = CRM_Member_BAO_Membership::getMembershipContributionId($membership->id, TRUE);
+ foreach ($relatedContributions as $contriId) {
+ if ($contriId == $contributionId) {
+ continue;
+ }
+ if (CRM_Core_PseudoConstant::getName('CRM_Contribute_BAO_Contribution', 'contribution_status_id', $contriId) === 'Completed') {
+ $update = FALSE;
+ }
+ }
+ if ($membership && $update) {
$newStatus = array_search('Cancelled', $membershipStatuses);
// Create activity
elseif ($contributionStatusId == array_search('Failed', $contributionStatuses)) {
if (is_array($memberships)) {
foreach ($memberships as $membership) {
- if ($membership) {
+ $update = TRUE;
+ //Update Membership status if there is no other completed contribution associated with the membership.
+ $relatedContributions = CRM_Member_BAO_Membership::getMembershipContributionId($membership->id, TRUE);
+ foreach ($relatedContributions as $contriId) {
+ if ($contriId == $contributionId) {
+ continue;
+ }
+ if (CRM_Core_PseudoConstant::getName('CRM_Contribute_BAO_Contribution', 'contribution_status_id', $contriId) === 'Completed') {
+ $update = FALSE;
+ }
+ }
+ if ($membership && $update) {
$membership->status_id = array_search('Expired', $membershipStatuses);
$membership->save();
// CRM-15735-to update the membership status as per the contribution receive date
$joinDate = NULL;
+ $oldStatus = $membership->status_id;
if (!empty($params['receive_date'])) {
$joinDate = $params['receive_date'];
$status = CRM_Member_BAO_MembershipStatus::getMembershipStatusByDate($membership->start_date,
//update related Memberships.
CRM_Member_BAO_Membership::updateRelatedMemberships($membership->id, $formattedParams);
- //CRM-19678: No Membership Renewal Activity is created when a Pay Later is set to Completed
- CRM_Activity_BAO_Activity::addActivity($membership, 'Membership Renewal', $membership->contact_id);
+ foreach (array('Membership Signup', 'Membership Renewal') as $activityType) {
+ $scheduledActivityID = CRM_Utils_Array::value('id',
+ civicrm_api3('Activity', 'Get',
+ array(
+ 'source_record_id' => $membership->id,
+ 'activity_type_id' => $activityType,
+ 'status_id' => 'Scheduled',
+ 'options' => array(
+ 'limit' => 1,
+ 'sort' => 'id DESC',
+ ),
+ )
+ )
+ );
+ // 1. Update Schedule Membership Signup/Renewal activity to completed on successful payment of pending membership
+ // 2. OR Create renewal activity scheduled if its membership renewal will be paid later
+ if ($scheduledActivityID) {
+ CRM_Activity_BAO_Activity::addActivity($membership, $activityType, $membership->contact_id, array('id' => $scheduledActivityID));
+ break;
+ }
+ }
+
+ // track membership status change if any
+ if (!empty($oldStatus) && $membership->status_id != $oldStatus) {
+ $allStatus = CRM_Member_BAO_Membership::buildOptions('status_id', 'get');
+ CRM_Activity_BAO_Activity::addActivity($membership,
+ 'Change Membership Status',
+ NULL,
+ array(
+ 'subject' => "Status changed from {$allStatus[$oldStatus]} to {$allStatus[$membership->status_id]}",
+ 'source_contact_id' => $membershipLog['modified_id'],
+ 'priority_id' => 'Normal',
+ )
+ );
+ }
$updateResult['membership_end_date'] = CRM_Utils_Date::customFormat($dates['end_date'],
'%B %E%f, %Y'
$statusId = $params['contribution']->contribution_status_id;
// CRM-13964 partial payment
if ($contributionStatus == 'Partially paid'
- && !empty($params['partial_payment_total']) && !empty($params['partial_amount_pay'])
+ && !empty($params['partial_payment_total']) && !empty($params['partial_amount_to_pay'])
) {
- $partialAmtPay = CRM_Utils_Rule::cleanMoney($params['partial_amount_pay']);
+ $partialAmtPay = CRM_Utils_Rule::cleanMoney($params['partial_amount_to_pay']);
$partialAmtTotal = CRM_Utils_Rule::cleanMoney($params['partial_payment_total']);
$fromFinancialAccountId = CRM_Contribute_PseudoConstant::getRelationalFinancialAccount($params['financial_type_id'], 'Accounts Receivable Account is');
$trxnParams['card_type_id'] = CRM_Utils_Array::value('card_type_id', $params);
$return = $financialTxn = CRM_Core_BAO_FinancialTrxn::create($trxnParams);
$params['entity_id'] = $financialTxn->id;
- if (empty($params['partial_payment_total']) && empty($params['partial_amount_pay'])) {
+ if (empty($params['partial_payment_total']) && empty($params['partial_amount_to_pay'])) {
self::$_trxnIDs[] = $financialTxn->id;
}
}
'entity_table' => 'civicrm_financial_trxn',
'entity_id' => $financialTxn->id,
);
- CRM_Batch_BAO_Batch::addBatchEntity($entityParams);
+ CRM_Batch_BAO_EntityBatch::create($entityParams);
}
// when a fee is charged
* @param string $context
* Update scenarios.
*
- * @param null $skipTrxn
- *
*/
- public static function updateFinancialAccounts(&$params, $context = NULL, $skipTrxn = NULL) {
- $itemAmount = $trxnID = NULL;
- //get all the statuses
- $contributionStatus = CRM_Contribute_PseudoConstant::contributionStatus(NULL, 'name');
+ public static function updateFinancialAccounts(&$params, $context = NULL) {
+ $trxnID = NULL;
+ $inputParams = $params;
+ $isARefund = FALSE;
+ $currentContributionStatus = CRM_Core_PseudoConstant::getLabel('CRM_Contribute_BAO_Contribution', 'contribution_status_id', $params['contribution']->contribution_status_id);
$previousContributionStatus = CRM_Contribute_PseudoConstant::contributionStatus($params['prevContribution']->contribution_status_id, 'name');
+
if (($previousContributionStatus == 'Pending'
|| $previousContributionStatus == 'In Progress')
- && $params['contribution']->contribution_status_id == array_search('Completed', $contributionStatus)
+ && $currentContributionStatus == 'Completed'
&& $context == 'changePaymentInstrument'
) {
return;
}
if ((($previousContributionStatus == 'Partially paid'
- && $params['contribution']->contribution_status_id == array_search('Completed', $contributionStatus))
+ && $currentContributionStatus == 'Completed')
|| ($previousContributionStatus == 'Pending' && $params['prevContribution']->is_pay_later == TRUE
- && $params['contribution']->contribution_status_id == array_search('Partially paid', $contributionStatus)))
+ && $currentContributionStatus == 'Partially paid'))
&& $context == 'changedStatus'
) {
return;
}
if ($context == 'changedAmount' || $context == 'changeFinancialType') {
- $itemAmount = $params['trxnParams']['total_amount'] = $params['trxnParams']['net_amount'] = $params['total_amount'] - $params['prevContribution']->total_amount;
+ $params['trxnParams']['total_amount'] = $params['trxnParams']['net_amount'] = ($params['total_amount'] - $params['prevContribution']->total_amount);
}
if ($context == 'changedStatus') {
- //get all the statuses
- $contributionStatus = CRM_Contribute_PseudoConstant::contributionStatus(NULL, 'name');
- $cancelledTaxAmount = 0;
if ($previousContributionStatus == 'Completed'
&& (self::isContributionStatusNegative($params['contribution']->contribution_status_id))
) {
+ $isARefund = TRUE;
$params['trxnParams']['total_amount'] = -$params['total_amount'];
- $cancelledTaxAmount = CRM_Utils_Array::value('tax_amount', $params, '0.00');
if (empty($params['contribution']->creditnote_id) || $params['contribution']->creditnote_id == "null") {
$creditNoteId = self::createCreditNoteId();
CRM_Core_DAO::setFieldValue('CRM_Contribute_DAO_Contribution', $params['contribution']->id, 'creditnote_id', $creditNoteId);
$financialTypeID = CRM_Utils_Array::value('financial_type_id', $params) ? $params['financial_type_id'] : $params['prevContribution']->financial_type_id;
$arAccountId = CRM_Contribute_PseudoConstant::getRelationalFinancialAccount($financialTypeID, 'Accounts Receivable Account is');
- if ($params['contribution']->contribution_status_id == array_search('Cancelled', $contributionStatus)) {
+ if ($currentContributionStatus == 'Cancelled') {
$params['trxnParams']['to_financial_account_id'] = $arAccountId;
$params['trxnParams']['total_amount'] = -$params['total_amount'];
if (is_null($params['contribution']->creditnote_id) || $params['contribution']->creditnote_id == "null") {
$params['trxnParams']['from_financial_account_id'] = $arAccountId;
}
}
- $itemAmount = $params['trxnParams']['total_amount'] + $cancelledTaxAmount;
}
elseif ($context == 'changePaymentInstrument') {
$params['trxnParams']['net_amount'] = $params['trxnParams']['total_amount'];
if ($context == 'changedStatus') {
if (($previousContributionStatus == 'Pending'
|| $previousContributionStatus == 'In Progress')
- && ($params['contribution']->contribution_status_id == array_search('Completed', $contributionStatus))
+ && ($currentContributionStatus == 'Completed')
) {
if (empty($params['line_item'])) {
//CRM-15296
if ($params['contribution']->currency) {
$currency = $params['contribution']->currency;
}
- $diff = 1;
- if ($context == 'changeFinancialType' || self::isContributionStatusNegative($params['contribution']->contribution_status_id)) {
- $diff = -1;
- }
- if (!empty($params['is_quick_config'])) {
- $amount = $itemAmount;
- if (!$amount) {
- $amount = $params['total_amount'];
- }
- }
- else {
- $amount = $diff * $lineItemDetails['line_total'];
- }
$itemParams = array(
'transaction_date' => $receiveDate,
'contact_id' => $params['prevContribution']->contact_id,
'currency' => $currency,
- 'amount' => $amount,
+ 'amount' => self::getFinancialItemAmountFromParams($inputParams, $context, $lineItemDetails, $isARefund),
'description' => $prevFinancialItem['description'],
'status_id' => $prevFinancialItem['status_id'],
'financial_account_id' => $financialAccount,
'entity_id' => $lineItemDetails['id'],
);
$financialItem = CRM_Financial_BAO_FinancialItem::create($itemParams, NULL, $trxnIds);
- $params['line_item'][$fieldId][$fieldValueId]['deferred_line_total'] = $amount;
+ $params['line_item'][$fieldId][$fieldValueId]['deferred_line_total'] = $itemParams['amount'];
$params['line_item'][$fieldId][$fieldValueId]['financial_item_id'] = $financialItem->id;
- if ($lineItemDetails['tax_amount']) {
+ if ($lineItemDetails['tax_amount'] && $lineItemDetails['tax_amount'] !== 'null') {
$invoiceSettings = Civi::settings()->get('contribution_invoice_settings');
$taxTerm = CRM_Utils_Array::value('tax_term', $invoiceSettings);
- $itemParams['amount'] = $diff * $lineItemDetails['tax_amount'];
+ $itemParams['amount'] = self::getMultiplier($params['contribution']->contribution_status_id, $context) * $lineItemDetails['tax_amount'];
$itemParams['description'] = $taxTerm;
if ($lineItemDetails['financial_type_id']) {
$itemParams['financial_account_id'] = self::getFinancialAccountId($lineItemDetails['financial_type_id']);
$arAccountId = CRM_Contribute_PseudoConstant::getRelationalFinancialAccount($contributionDAO->financial_type_id, 'Accounts Receivable Account is');
if ($paymentType == 'owed') {
$params['partial_payment_total'] = $contributionDAO->total_amount;
- $params['partial_amount_pay'] = $trxnsData['total_amount'];
+ $params['partial_amount_to_pay'] = $trxnsData['total_amount'];
$trxnsData['net_amount'] = !empty($trxnsData['net_amount']) ? $trxnsData['net_amount'] : $trxnsData['total_amount'];
$params['pan_truncation'] = CRM_Utils_Array::value('pan_truncation', $trxnsData);
$params['card_type_id'] = CRM_Utils_Array::value('card_type_id', $trxnsData);
$var = TRUE;
CRM_Member_BAO_Membership::createRelatedMemberships($var, $var, TRUE);
civicrm_api3('Membership', 'create', $membershipParams);
- //CRM-19600: Add Membership Renewal activity
- CRM_Activity_BAO_Activity::addActivity($membership, 'Membership Renewal', $membership->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
return self::getValues(array('id' => $contributionID), CRM_Core_DAO::$_nullArray, CRM_Core_DAO::$_nullArray);
}
+ /**
+ * Get the amount for the financial item row.
+ *
+ * Helper function to start to break down recordFinancialTransactions for readability.
+ *
+ * The logic is more historical than .. logical. Paths other than the deprecated one are tested.
+ *
+ * Codewise, several somewhat disimmilar things have been squished into recordFinancialAccounts
+ * for historical reasons. Going forwards we can hope to add tests & improve readibility
+ * of that function
+ *
+ * @todo move recordFinancialAccounts & helper functions to their own class?
+ *
+ * @param array $params
+ * Params as passed to contribution.create
+ *
+ * @param string $context
+ * changeFinancialType| changedAmount
+ * @param array $lineItemDetails
+ * Line items.
+ * @param bool $isARefund
+ * Is this a refund / negative transaction.
+ *
+ * @return float
+ */
+ protected static function getFinancialItemAmountFromParams($params, $context, $lineItemDetails, $isARefund) {
+ if ($context == 'changedAmount' || $context == 'changeFinancialType') {
+ return $params['total_amount'] - $params['prevContribution']->total_amount;
+ }
+ elseif ($context == 'changedStatus') {
+ $cancelledTaxAmount = 0;
+ if ($isARefund) {
+ $cancelledTaxAmount = CRM_Utils_Array::value('tax_amount', $params, '0.00');
+ }
+ return self::getMultiplier($params['contribution']->contribution_status_id, $context) * ($params['trxnParams']['total_amount'] + $cancelledTaxAmount);
+ }
+ elseif ($context === NULL) {
+ // erm, yes because? but, hey, it's tested.
+ return $params['total_amount'];
+ }
+ elseif (empty($lineItemDetails['line_total'])) {
+ // follow legacy code path
+ Civi::log()
+ ->warning('Deprecated bit of code, please log a ticket explaining how you got here!', array('civi.tag' => 'deprecated'));
+ return $params['total_amount'];
+ }
+ else {
+ return self::getMultiplier($params['contribution']->contribution_status_id, $context) * $lineItemDetails['line_total'];
+ }
+ }
+
+ /**
+ * Get the multiplier for adjusting rows.
+ *
+ * If we are dealing with a refund or cancellation then it will be a negative
+ * amount to reflect the negative transaction.
+ *
+ * If we are changing Financial Type it will be a negative amount to
+ * adjust down the old type.
+ *
+ * @param int $contribution_status_id
+ * @param string $context
+ *
+ * @return int
+ */
+ protected static function getMultiplier($contribution_status_id, $context) {
+ if ($context == 'changeFinancialType' || self::isContributionStatusNegative($contribution_status_id)) {
+ return -1;
+ }
+ return 1;
+ }
+
/**
* Assign Test Value.
*