X-Git-Url: https://vcs.fsf.org/?a=blobdiff_plain;f=CRM%2FContribute%2FBAO%2FContribution.php;h=8416ad9341004516e32448bbd5e3db79659465c5;hb=1e9b7f9fe925bfab0458df70a15ecc16e0a59f05;hp=374296ed5890a3454a8a127e0039a5c07a5d8434;hpb=08578573bc28f4962c116ce94f85bda3496b2287;p=civicrm-core.git diff --git a/CRM/Contribute/BAO/Contribution.php b/CRM/Contribute/BAO/Contribution.php index 374296ed58..8416ad9341 100644 --- a/CRM/Contribute/BAO/Contribution.php +++ b/CRM/Contribute/BAO/Contribution.php @@ -1835,13 +1835,13 @@ LEFT JOIN civicrm_contribution contribution ON ( componentPayment.contribution_ // only pending contribution related object processed. if ($previousContriStatusId && - ($previousContriStatusId != array_search('Pending', $contributionStatuses)) + !in_array($contributionStatuses[$previousContriStatusId], array('Pending', 'Partially paid')) ) { // this is case when we already processed contribution object. return $updateResult; } elseif (!$previousContriStatusId && - $contribution->contribution_status_id != array_search('Pending', $contributionStatuses) + !in_array($contributionStatuses[$contribution->contribution_status_id], array('Pending', 'Partially paid')) ) { // this is case when we are going to process contribution object later. return $updateResult; @@ -3377,46 +3377,9 @@ INNER JOIN civicrm_activity ON civicrm_activity_contact.activity_id = civicrm_ac // instrument is null and now new payment instrument is added along with the payment $params['trxnParams']['payment_instrument_id'] = $params['contribution']->payment_instrument_id; $params['trxnParams']['check_number'] = CRM_Utils_Array::value('check_number', $params); - if (array_key_exists('payment_instrument_id', $params)) { - $params['trxnParams']['total_amount'] = -$trxnParams['total_amount']; - if (CRM_Utils_System::isNull($params['prevContribution']->payment_instrument_id) && - !CRM_Utils_System::isNull($params['contribution']->payment_instrument_id) - ) { - //check if status is changed from Pending to Completed - // do not update payment instrument changes for Pending to Completed - if (!($params['contribution']->contribution_status_id == array_search('Completed', $contributionStatuses) && - in_array($params['prevContribution']->contribution_status_id, $pendingStatus)) - ) { - // for all other statuses create new financial records - self::updateFinancialAccounts($params, 'changePaymentInstrument'); - $params['total_amount'] = $params['trxnParams']['total_amount'] = $trxnParams['total_amount']; - self::updateFinancialAccounts($params, 'changePaymentInstrument'); - $updated = TRUE; - } - } - elseif ((!CRM_Utils_System::isNull($params['contribution']->payment_instrument_id) || - !CRM_Utils_System::isNull($params['prevContribution']->payment_instrument_id)) && - $params['contribution']->payment_instrument_id != $params['prevContribution']->payment_instrument_id - ) { - // for any other payment instrument changes create new financial records - self::updateFinancialAccounts($params, 'changePaymentInstrument'); - $params['total_amount'] = $params['trxnParams']['total_amount'] = $trxnParams['total_amount']; - self::updateFinancialAccounts($params, 'changePaymentInstrument'); - $updated = TRUE; - } - elseif (!CRM_Utils_System::isNull($params['contribution']->check_number) && - $params['contribution']->check_number != $params['prevContribution']->check_number - ) { - // another special case when check number is changed, create new financial records - // create financial trxn with negative amount - $params['trxnParams']['check_number'] = $params['prevContribution']->check_number; - self::updateFinancialAccounts($params, 'changePaymentInstrument'); - // create financial trxn with positive amount - $params['trxnParams']['check_number'] = $params['contribution']->check_number; - $params['total_amount'] = $params['trxnParams']['total_amount'] = $trxnParams['total_amount']; - self::updateFinancialAccounts($params, 'changePaymentInstrument'); - $updated = TRUE; - } + + if (self::isPaymentInstrumentChange($params, $pendingStatus)) { + $updated = CRM_Core_BAO_FinancialTrxn::updateFinancialAccountsOnPaymentInstrumentChange($params); } //if Change contribution amount @@ -3563,24 +3526,6 @@ INNER JOIN civicrm_activity ON civicrm_activity_contact.activity_id = civicrm_ac } } } - elseif ($context == 'changePaymentInstrument') { - $params['trxnParams']['net_amount'] = $params['trxnParams']['total_amount']; - $deferredFinancialAccount = CRM_Utils_Array::value('deferred_financial_account_id', $params); - if (empty($deferredFinancialAccount)) { - $deferredFinancialAccount = CRM_Contribute_PseudoConstant::getRelationalFinancialAccount($params['prevContribution']->financial_type_id, 'Deferred Revenue Account is'); - } - $lastFinancialTrxnId = CRM_Core_BAO_FinancialTrxn::getFinancialTrxnId($params['prevContribution']->id, 'DESC', FALSE, NULL, $deferredFinancialAccount); - if (!empty($lastFinancialTrxnId['financialTrxnId'])) { - if ($params['total_amount'] != $params['trxnParams']['total_amount']) { - $params['trxnParams']['to_financial_account_id'] = CRM_Core_DAO::getFieldValue('CRM_Financial_DAO_FinancialTrxn', $lastFinancialTrxnId['financialTrxnId'], 'to_financial_account_id'); - $params['trxnParams']['payment_instrument_id'] = $params['prevContribution']->payment_instrument_id; - } - else { - $params['trxnParams']['to_financial_account_id'] = $params['to_financial_account_id']; - $params['trxnParams']['payment_instrument_id'] = $params['contribution']->payment_instrument_id; - } - } - } if ($context == 'changedStatus') { if (($previousContributionStatus == 'Pending' @@ -3633,6 +3578,7 @@ INNER JOIN civicrm_activity ON civicrm_activity_contact.activity_id = civicrm_ac if ($context != 'changePaymentInstrument') { $itemParams['entity_table'] = 'civicrm_line_item'; $trxnIds['id'] = $params['entity_id']; + $previousLineItems = CRM_Price_BAO_LineItem::getLineItemsByContributionID($params['contribution']->id); foreach ($params['line_item'] as $fieldId => $fields) { foreach ($fields as $fieldValueId => $lineItemDetails) { $prevFinancialItem = CRM_Financial_BAO_FinancialItem::getPreviousFinancialItem($lineItemDetails['id']); @@ -3641,19 +3587,19 @@ INNER JOIN civicrm_activity ON civicrm_activity_contact.activity_id = civicrm_ac $receiveDate = CRM_Utils_Date::isoToMysql($params['contribution']->receive_date); } - $financialAccount = self::getFinancialAccountForStatusChangeTrxn($params, $prevFinancialItem['financial_account_id']); + $financialAccount = self::getFinancialAccountForStatusChangeTrxn($params, CRM_Utils_Array::value('financial_account_id', $prevFinancialItem)); $currency = $params['prevContribution']->currency; if ($params['contribution']->currency) { $currency = $params['contribution']->currency; } - + $previousLineItemTotal = CRM_Utils_Array::value('line_total', CRM_Utils_Array::value($fieldValueId, $previousLineItems), 0); $itemParams = array( 'transaction_date' => $receiveDate, 'contact_id' => $params['prevContribution']->contact_id, 'currency' => $currency, - 'amount' => self::getFinancialItemAmountFromParams($inputParams, $context, $lineItemDetails, $isARefund), - 'description' => $prevFinancialItem['description'], + 'amount' => self::getFinancialItemAmountFromParams($inputParams, $context, $lineItemDetails, $isARefund, $previousLineItemTotal), + 'description' => CRM_Utils_Array::value('description', $prevFinancialItem), 'status_id' => $prevFinancialItem['status_id'], 'financial_account_id' => $financialAccount, 'entity_table' => 'civicrm_line_item', @@ -3663,10 +3609,18 @@ INNER JOIN civicrm_activity ON civicrm_activity_contact.activity_id = civicrm_ac $params['line_item'][$fieldId][$fieldValueId]['deferred_line_total'] = $itemParams['amount']; $params['line_item'][$fieldId][$fieldValueId]['financial_item_id'] = $financialItem->id; - if ($lineItemDetails['tax_amount'] && $lineItemDetails['tax_amount'] !== 'null') { + if (($lineItemDetails['tax_amount'] && $lineItemDetails['tax_amount'] !== 'null') || ($context == 'changeFinancialType')) { $invoiceSettings = Civi::settings()->get('contribution_invoice_settings'); $taxTerm = CRM_Utils_Array::value('tax_term', $invoiceSettings); - $itemParams['amount'] = self::getMultiplier($params['contribution']->contribution_status_id, $context) * $lineItemDetails['tax_amount']; + $taxAmount = $lineItemDetails['tax_amount']; + if ($context == 'changeFinancialType' && $lineItemDetails['tax_amount'] === 'null') { + // reverse the Sale Tax amount if there is no tax rate associated with new Financial Type + $taxAmount = CRM_Utils_Array::value('tax_amount', CRM_Utils_Array::value($fieldValueId, $previousLineItems), 0); + } + elseif ($previousLineItemTotal != $lineItemDetails['line_total']) { + $taxAmount -= CRM_Utils_Array::value('tax_amount', CRM_Utils_Array::value($fieldValueId, $previousLineItems), 0); + } + $itemParams['amount'] = self::getMultiplier($params['contribution']->contribution_status_id, $context) * $taxAmount; $itemParams['description'] = $taxTerm; if ($lineItemDetails['financial_type_id']) { $itemParams['financial_account_id'] = CRM_Contribute_PseudoConstant::getRelationalFinancialAccount( @@ -3687,14 +3641,7 @@ INNER JOIN civicrm_activity ON civicrm_activity_contact.activity_id = civicrm_ac } } } - if ($context == 'changePaymentInstrument') { - // store financial item Proportionaly. - $trxnParams = array( - 'total_amount' => $trxn->total_amount, - 'contribution_id' => $params['contribution']->id, - ); - self::assignProportionalLineItems($trxnParams, $trxn->id, $params['prevContribution']->total_amount); - } + CRM_Core_BAO_FinancialTrxn::createDeferredTrxn(CRM_Utils_Array::value('line_item', $params), $params['contribution'], TRUE, $context); } @@ -5353,9 +5300,16 @@ LEFT JOIN civicrm_contribution on (civicrm_contribution.contact_id = civicrm_co * * @return float */ - protected static function getFinancialItemAmountFromParams($params, $context, $lineItemDetails, $isARefund) { - if ($context == 'changedAmount' || $context == 'changeFinancialType') { - return $params['total_amount'] - $params['prevContribution']->total_amount; + protected static function getFinancialItemAmountFromParams($params, $context, $lineItemDetails, $isARefund, $previousLineItemTotal) { + if ($context == 'changedAmount') { + $lineTotal = $lineItemDetails['line_total']; + if ($lineTotal != $previousLineItemTotal) { + $lineTotal -= $previousLineItemTotal; + } + return $lineTotal; + } + elseif ($context == 'changeFinancialType') { + return -$lineItemDetails['line_total']; } elseif ($context == 'changedStatus') { $cancelledTaxAmount = 0; @@ -5366,7 +5320,7 @@ LEFT JOIN civicrm_contribution on (civicrm_contribution.contact_id = civicrm_co } elseif ($context === NULL) { // erm, yes because? but, hey, it's tested. - return $params['total_amount']; + return $lineItemDetails['line_total']; } elseif (empty($lineItemDetails['line_total'])) { // follow legacy code path @@ -5400,6 +5354,46 @@ LEFT JOIN civicrm_contribution on (civicrm_contribution.contact_id = civicrm_co return 1; } + /** + * Does this transaction reflect a payment instrument change. + * + * @param array $params + * @param array $pendingStatuses + * + * @return bool + */ + protected static function isPaymentInstrumentChange(&$params, $pendingStatuses) { + $contributionStatus = CRM_Core_PseudoConstant::getName('CRM_Contribute_BAO_Contribution', 'contribution_status_id', $params['contribution']->contribution_status_id); + + if (array_key_exists('payment_instrument_id', $params)) { + if (CRM_Utils_System::isNull($params['prevContribution']->payment_instrument_id) && + !CRM_Utils_System::isNull($params['payment_instrument_id']) + ) { + //check if status is changed from Pending to Completed + // do not update payment instrument changes for Pending to Completed + if (!($contributionStatus == 'Completed' && + in_array($params['prevContribution']->contribution_status_id, $pendingStatuses)) + ) { + return TRUE; + } + } + elseif ((!CRM_Utils_System::isNull($params['payment_instrument_id']) && + !CRM_Utils_System::isNull($params['prevContribution']->payment_instrument_id)) && + $params['contribution']->payment_instrument_id != $params['prevContribution']->payment_instrument_id + ) { + return TRUE; + } + elseif (!CRM_Utils_System::isNull($params['contribution']->check_number) && + $params['contribution']->check_number != $params['prevContribution']->check_number + ) { + // another special case when check number is changed, create new financial records + // create financial trxn with negative amount + return TRUE; + } + } + return FALSE; + } + /** * Assign Test Value. *