/** * Create all financial accounts entry. * * @param array $params * Contribution object, line item array and params for trxn. * * * @param array $financialTrxnValues * * @return null|object */ public static function recordFinancialAccounts(&$params, $financialTrxnValues = NULL) { $skipRecords = $update = $return = $isRelatedId = FALSE; $additionalParticipantId = array(); $contributionStatuses = CRM_Contribute_PseudoConstant::contributionStatus(NULL, 'name'); $contributionStatus = empty($params['contribution_status_id']) ? NULL : $contributionStatuses[$params['contribution_status_id']]; if (CRM_Utils_Array::value('contribution_mode', $params) == 'participant') { $entityId = $params['participant_id']; $entityTable = 'civicrm_participant'; $additionalParticipantId = CRM_Event_BAO_Participant::getAdditionalParticipantIds($entityId); } elseif (!empty($params['membership_id'])) { //so far $params['membership_id'] should only be set coming in from membershipBAO::create so the situation where multiple memberships // are created off one contribution should be handled elsewhere $entityId = $params['membership_id']; $entityTable = 'civicrm_membership'; } else { $entityId = $params['contribution']->id; $entityTable = 'civicrm_contribution'; } if (CRM_Utils_Array::value('contribution_mode', $params) == 'membership') { $isRelatedId = TRUE; } $entityID[] = $entityId; if (!empty($additionalParticipantId)) { $entityID += $additionalParticipantId; } // prevContribution appears to mean - original contribution object- ie copy of contribution from before the update started that is being updated if (empty($params['prevContribution'])) { $entityID = NULL; } else { $update = TRUE; } $statusId = $params['contribution']->contribution_status_id; // CRM-13964 partial payment if ($contributionStatus == 'Partially paid' && !empty($params['partial_payment_total']) && !empty($params['partial_amount_pay'])) { $partialAmtPay = $params['partial_amount_pay']; $partialAmtTotal = $params['partial_payment_total']; $relationTypeId = key(CRM_Core_PseudoConstant::accountOptionValues('account_relationship', NULL, " AND v.name LIKE 'Accounts Receivable Account is' ")); $fromFinancialAccountId = CRM_Contribute_PseudoConstant::financialAccountType($params['financial_type_id'], $relationTypeId); $statusId = CRM_Core_OptionGroup::getValue('contribution_status', 'Completed', 'name'); $params['total_amount'] = $partialAmtPay; $balanceTrxnInfo = CRM_Core_BAO_FinancialTrxn::getBalanceTrxnAmt($params['contribution']->id, $params['financial_type_id']); if (empty($balanceTrxnInfo['trxn_id'])) { // create new balance transaction record $relationTypeId = key(CRM_Core_PseudoConstant::accountOptionValues('account_relationship', NULL, " AND v.name LIKE 'Accounts Receivable Account is' ")); $toFinancialAccount = CRM_Contribute_PseudoConstant::financialAccountType($params['financial_type_id'], $relationTypeId); $balanceTrxnParams['total_amount'] = $partialAmtTotal; $balanceTrxnParams['to_financial_account_id'] = $toFinancialAccount; $balanceTrxnParams['contribution_id'] = $params['contribution']->id; $balanceTrxnParams['trxn_date'] = !empty($params['contribution']->receive_date) ? $params['contribution']->receive_date : date('YmdHis'); $balanceTrxnParams['fee_amount'] = CRM_Utils_Array::value('fee_amount', $params); $balanceTrxnParams['net_amount'] = CRM_Utils_Array::value('net_amount', $params); $balanceTrxnParams['currency'] = $params['contribution']->currency; $balanceTrxnParams['trxn_id'] = $params['contribution']->trxn_id; $balanceTrxnParams['status_id'] = $statusId; $balanceTrxnParams['payment_instrument_id'] = $params['contribution']->payment_instrument_id; $balanceTrxnParams['check_number'] = CRM_Utils_Array::value('check_number', $params); if (!empty($balanceTrxnParams['from_financial_account_id']) && ($statusId == array_search('Completed', $contributionStatuses) || $statusId == array_search('Partially paid', $contributionStatuses))) { $balanceTrxnParams['is_payment'] = 1; } if (!empty($params['payment_processor'])) { $balanceTrxnParams['payment_processor_id'] = $params['payment_processor']; } $financialTxn = CRM_Core_BAO_FinancialTrxn::create($balanceTrxnParams); } } // build line item array if its not set in $params if (empty($params['line_item']) || $additionalParticipantId) { CRM_Price_BAO_LineItem::getLineItemArray($params, $entityID, str_replace('civicrm_', '', $entityTable), $isRelatedId); } if ($contributionStatus != 'Failed' && !($contributionStatus == 'Pending' && !$params['contribution']->is_pay_later)) { $skipRecords = TRUE; $pendingStatus = array('Pending', 'In Progress'); if (in_array($contributionStatus, $pendingStatus)) { $relationTypeId = key(CRM_Core_PseudoConstant::accountOptionValues('account_relationship', NULL, " AND v.name LIKE 'Accounts Receivable Account is' ")); $params['to_financial_account_id'] = CRM_Contribute_PseudoConstant::financialAccountType($params['financial_type_id'], $relationTypeId); } elseif (!empty($params['payment_processor'])) { $params['to_financial_account_id'] = CRM_Financial_BAO_FinancialTypeAccount::getFinancialAccount($params['payment_processor'], 'civicrm_payment_processor', 'financial_account_id'); } elseif (!empty($params['payment_instrument_id'])) { $params['to_financial_account_id'] = CRM_Financial_BAO_FinancialTypeAccount::getInstrumentFinancialAccount($params['payment_instrument_id']); } else { $relationTypeId = key(CRM_Core_PseudoConstant::accountOptionValues('financial_account_type', NULL, " AND v.name LIKE 'Asset' ")); $queryParams = array(1 => array($relationTypeId, 'Integer')); $params['to_financial_account_id'] = CRM_Core_DAO::singleValueQuery("SELECT id FROM civicrm_financial_account WHERE is_default = 1 AND financial_account_type_id = %1", $queryParams); } $totalAmount = CRM_Utils_Array::value('total_amount', $params); if (!isset($totalAmount) && !empty($params['prevContribution'])) { $totalAmount = $params['total_amount'] = $params['prevContribution']->total_amount; } //build financial transaction params $trxnParams = array('contribution_id' => $params['contribution']->id, 'to_financial_account_id' => $params['to_financial_account_id'], 'trxn_date' => !empty($params['contribution']->receive_date) ? $params['contribution']->receive_date : date('YmdHis'), 'total_amount' => $totalAmount, 'fee_amount' => CRM_Utils_Array::value('fee_amount', $params), 'net_amount' => CRM_Utils_Array::value('net_amount', $params, $totalAmount), 'currency' => $params['contribution']->currency, 'trxn_id' => $params['contribution']->trxn_id, 'status_id' => $statusId, 'payment_instrument_id' => $params['contribution']->payment_instrument_id, 'check_number' => CRM_Utils_Array::value('check_number', $params)); if ($contributionStatus == 'Refunded') { $trxnParams['trxn_date'] = !empty($params['contribution']->cancel_date) ? $params['contribution']->cancel_date : date('YmdHis'); if (isset($params['refund_trxn_id'])) { // CRM-17751 allow a separate trxn_id for the refund to be passed in via api & form. $trxnParams['trxn_id'] = $params['refund_trxn_id']; } } //CRM-16259, set is_payment flag for non pending status if (!in_array($contributionStatus, $pendingStatus)) { $trxnParams['is_payment'] = 1; } if (!empty($params['payment_processor'])) { $trxnParams['payment_processor_id'] = $params['payment_processor']; } if (isset($fromFinancialAccountId)) { $trxnParams['from_financial_account_id'] = $fromFinancialAccountId; } // consider external values passed for recording transaction entry if (!empty($financialTrxnValues)) { $trxnParams = array_merge($trxnParams, $financialTrxnValues); } $params['trxnParams'] = $trxnParams; if (!empty($params['prevContribution'])) { $updated = FALSE; $params['trxnParams']['total_amount'] = $trxnParams['total_amount'] = $params['total_amount'] = $params['prevContribution']->total_amount; $params['trxnParams']['fee_amount'] = $params['prevContribution']->fee_amount; $params['trxnParams']['net_amount'] = $params['prevContribution']->net_amount; if (!isset($params['trxnParams']['trxn_id'])) { // Actually I have no idea why we are overwriting any values from the previous contribution. // (filling makes sense to me). However, only protecting this value as I really really know we // don't want this one overwritten. // CRM-17751. $params['trxnParams']['trxn_id'] = $params['prevContribution']->trxn_id; } $params['trxnParams']['status_id'] = $params['prevContribution']->contribution_status_id; if (!(($params['prevContribution']->contribution_status_id == array_search('Pending', $contributionStatuses) || $params['prevContribution']->contribution_status_id == array_search('In Progress', $contributionStatuses)) && $params['contribution']->contribution_status_id == array_search('Completed', $contributionStatuses))) { $params['trxnParams']['payment_instrument_id'] = $params['prevContribution']->payment_instrument_id; $params['trxnParams']['check_number'] = $params['prevContribution']->check_number; } //if financial type is changed if (!empty($params['financial_type_id']) && $params['contribution']->financial_type_id != $params['prevContribution']->financial_type_id) { $incomeTypeId = key(CRM_Core_PseudoConstant::accountOptionValues('account_relationship', NULL, " AND v.name LIKE 'Income Account is' ")); $oldFinancialAccount = CRM_Contribute_PseudoConstant::financialAccountType($params['prevContribution']->financial_type_id, $incomeTypeId); $newFinancialAccount = CRM_Contribute_PseudoConstant::financialAccountType($params['financial_type_id'], $incomeTypeId); if ($oldFinancialAccount != $newFinancialAccount) { $params['total_amount'] = 0; if (in_array($params['contribution']->contribution_status_id, $pendingStatus)) { $params['trxnParams']['to_financial_account_id'] = CRM_Contribute_PseudoConstant::financialAccountType($params['prevContribution']->financial_type_id, $relationTypeId); } else { $lastFinancialTrxnId = CRM_Core_BAO_FinancialTrxn::getFinancialTrxnId($params['prevContribution']->id, 'DESC'); if (!empty($lastFinancialTrxnId['financialTrxnId'])) { $params['trxnParams']['to_financial_account_id'] = CRM_Core_DAO::getFieldValue('CRM_Financial_DAO_FinancialTrxn', $lastFinancialTrxnId['financialTrxnId'], 'to_financial_account_id'); } } self::updateFinancialAccounts($params, 'changeFinancialType'); /* $params['trxnParams']['to_financial_account_id'] = $trxnParams['to_financial_account_id']; */ $params['financial_account_id'] = $newFinancialAccount; $params['total_amount'] = $params['trxnParams']['total_amount'] = $trxnParams['total_amount']; self::updateFinancialAccounts($params); $params['trxnParams']['to_financial_account_id'] = $trxnParams['to_financial_account_id']; $updated = TRUE; } } //Update contribution status $params['trxnParams']['status_id'] = $params['contribution']->contribution_status_id; if (!isset($params['refund_trxn_id'])) { // CRM-17751 This has previously been deliberately set. No explanation as to why one variant // gets preference over another so I am only 'protecting' a very specific tested flow // and letting natural justice take care of the rest. $params['trxnParams']['trxn_id'] = $params['contribution']->trxn_id; } if (!empty($params['contribution_status_id']) && $params['prevContribution']->contribution_status_id != $params['contribution']->contribution_status_id) { //Update Financial Records self::updateFinancialAccounts($params, 'changedStatus'); $updated = TRUE; } // change Payment Instrument for a Completed contribution // first handle special case when contribution is changed from Pending to Completed status when initial payment // 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 Change contribution amount $params['trxnParams']['fee_amount'] = CRM_Utils_Array::value('fee_amount', $params); $params['trxnParams']['net_amount'] = CRM_Utils_Array::value('net_amount', $params); $params['trxnParams']['total_amount'] = $trxnParams['total_amount'] = $params['total_amount'] = $totalAmount; $params['trxnParams']['trxn_id'] = $params['contribution']->trxn_id; if (isset($totalAmount) && $totalAmount != $params['prevContribution']->total_amount) { //Update Financial Records $params['trxnParams']['from_financial_account_id'] = NULL; self::updateFinancialAccounts($params, 'changedAmount'); $updated = TRUE; } if (!$updated) { // Looks like we might have a data correction update. // This would be a case where a transaction id has been entered but it is incorrect & // the person goes back in & fixes it, as opposed to a new transaction. // Currently the UI doesn't support multiple refunds against a single transaction & we are only supporting // the data fix scenario. // CRM-17751. if (isset($params['refund_trxn_id'])) { $refundIDs = CRM_Core_BAO_FinancialTrxn::getRefundTransactionIDs($params['id']); if ($refundIDs['trxn_id'] != $params['refund_trxn_id']) { civicrm_api3('FinancialTrxn', 'create', array('id' => $refundIDs['financialTrxnId'], 'trxn_id' => $params['refund_trxn_id'])); } } } } if (!$update) { // records finanical trxn and entity financial trxn // also make it available as return value $return = $financialTxn = CRM_Core_BAO_FinancialTrxn::create($trxnParams); $params['entity_id'] = $financialTxn->id; } } // record line items and financial items if (empty($params['skipLineItem'])) { CRM_Price_BAO_LineItem::processPriceSet($entityId, CRM_Utils_Array::value('line_item', $params), $params['contribution'], $entityTable, $update); } // create batch entry if batch_id is passed and // ensure no batch entry is been made on 'Pending' or 'Failed' contribution, CRM-16611 if (!empty($params['batch_id']) && !empty($financialTxn)) { $entityParams = array('batch_id' => $params['batch_id'], 'entity_table' => 'civicrm_financial_trxn', 'entity_id' => $financialTxn->id); CRM_Batch_BAO_Batch::addBatchEntity($entityParams); } // when a fee is charged if (!empty($params['fee_amount']) && (empty($params['prevContribution']) || $params['contribution']->fee_amount != $params['prevContribution']->fee_amount) && $skipRecords) { CRM_Core_BAO_FinancialTrxn::recordFees($params); } if (!empty($params['prevContribution']) && $entityTable == 'civicrm_participant' && $params['prevContribution']->contribution_status_id != $params['contribution']->contribution_status_id) { $eventID = CRM_Core_DAO::getFieldValue('CRM_Event_DAO_Participant', $entityId, 'event_id'); $feeLevel[] = str_replace('', '', $params['prevContribution']->amount_level); CRM_Event_BAO_Participant::createDiscountTrxn($eventID, $params, $feeLevel); } unset($params['line_item']); return $return; }
/** * Create all financial accounts entry. * * @param array $params * Contribution object, line item array and params for trxn. * * * @param array $financialTrxnValues * * @return null|object */ public static function recordFinancialAccounts(&$params, $financialTrxnValues = NULL) { $skipRecords = $update = $return = $isRelatedId = FALSE; $additionalParticipantId = array(); $contributionStatuses = CRM_Contribute_PseudoConstant::contributionStatus(NULL, 'name'); if (CRM_Utils_Array::value('contribution_mode', $params) == 'participant') { $entityId = $params['participant_id']; $entityTable = 'civicrm_participant'; $additionalParticipantId = CRM_Event_BAO_Participant::getAdditionalParticipantIds($entityId); } elseif (!empty($params['membership_id'])) { //so far $params['membership_id'] should only be set coming in from membershipBAO::create so the situation where multiple memberships // are created off one contribution should be handled elsewhere $entityId = $params['membership_id']; $entityTable = 'civicrm_membership'; } else { $entityId = $params['contribution']->id; $entityTable = 'civicrm_contribution'; } if (CRM_Utils_Array::value('contribution_mode', $params) == 'membership') { $isRelatedId = TRUE; } $entityID[] = $entityId; if (!empty($additionalParticipantId)) { $entityID += $additionalParticipantId; } // prevContribution appears to mean - original contribution object- ie copy of contribution from before the update started that is being updated if (empty($params['prevContribution'])) { $entityID = NULL; } else { $update = TRUE; } $statusId = $params['contribution']->contribution_status_id; // CRM-13964 partial payment if (CRM_Utils_Array::value('contribution_status_id', $params) == array_search('Partially paid', $contributionStatuses) && !empty($params['partial_payment_total']) && !empty($params['partial_amount_pay'])) { $partialAmtPay = $params['partial_amount_pay']; $partialAmtTotal = $params['partial_payment_total']; $relationTypeId = key(CRM_Core_PseudoConstant::accountOptionValues('account_relationship', NULL, " AND v.name LIKE 'Accounts Receivable Account is' ")); $fromFinancialAccountId = CRM_Contribute_PseudoConstant::financialAccountType($params['financial_type_id'], $relationTypeId); $statusId = CRM_Core_OptionGroup::getValue('contribution_status', 'Completed', 'name'); $params['total_amount'] = $partialAmtPay; $balanceTrxnInfo = CRM_Core_BAO_FinancialTrxn::getBalanceTrxnAmt($params['contribution']->id, $params['financial_type_id']); if (empty($balanceTrxnInfo['trxn_id'])) { // create new balance transaction record $relationTypeId = key(CRM_Core_PseudoConstant::accountOptionValues('account_relationship', NULL, " AND v.name LIKE 'Accounts Receivable Account is' ")); $toFinancialAccount = CRM_Contribute_PseudoConstant::financialAccountType($params['financial_type_id'], $relationTypeId); $balanceTrxnParams['total_amount'] = $partialAmtTotal; $balanceTrxnParams['to_financial_account_id'] = $toFinancialAccount; $balanceTrxnParams['contribution_id'] = $params['contribution']->id; $balanceTrxnParams['trxn_date'] = !empty($params['contribution']->receive_date) ? $params['contribution']->receive_date : date('YmdHis'); $balanceTrxnParams['fee_amount'] = CRM_Utils_Array::value('fee_amount', $params); $balanceTrxnParams['net_amount'] = CRM_Utils_Array::value('net_amount', $params); $balanceTrxnParams['currency'] = $params['contribution']->currency; $balanceTrxnParams['trxn_id'] = $params['contribution']->trxn_id; $balanceTrxnParams['status_id'] = $statusId; $balanceTrxnParams['payment_instrument_id'] = $params['contribution']->payment_instrument_id; $balanceTrxnParams['check_number'] = CRM_Utils_Array::value('check_number', $params); if (!empty($params['payment_processor'])) { $balanceTrxnParams['payment_processor_id'] = $params['payment_processor']; } $financialTxn = CRM_Core_BAO_FinancialTrxn::create($balanceTrxnParams); } } // build line item array if its not set in $params if (empty($params['line_item']) || $additionalParticipantId) { CRM_Price_BAO_LineItem::getLineItemArray($params, $entityID, str_replace('civicrm_', '', $entityTable), $isRelatedId); } if (CRM_Utils_Array::value('contribution_status_id', $params) != array_search('Failed', $contributionStatuses) && !(CRM_Utils_Array::value('contribution_status_id', $params) == array_search('Pending', $contributionStatuses) && !$params['contribution']->is_pay_later)) { $skipRecords = TRUE; $pendingStatus = array(array_search('Pending', $contributionStatuses), array_search('In Progress', $contributionStatuses)); if (in_array(CRM_Utils_Array::value('contribution_status_id', $params), $pendingStatus)) { $relationTypeId = key(CRM_Core_PseudoConstant::accountOptionValues('account_relationship', NULL, " AND v.name LIKE 'Accounts Receivable Account is' ")); $params['to_financial_account_id'] = CRM_Contribute_PseudoConstant::financialAccountType($params['financial_type_id'], $relationTypeId); } elseif (!empty($params['payment_processor'])) { $params['to_financial_account_id'] = CRM_Financial_BAO_FinancialTypeAccount::getFinancialAccount($params['payment_processor'], 'civicrm_payment_processor', 'financial_account_id'); } elseif (!empty($params['payment_instrument_id'])) { $params['to_financial_account_id'] = CRM_Financial_BAO_FinancialTypeAccount::getInstrumentFinancialAccount($params['payment_instrument_id']); } else { $relationTypeId = key(CRM_Core_PseudoConstant::accountOptionValues('financial_account_type', NULL, " AND v.name LIKE 'Asset' ")); $queryParams = array(1 => array($relationTypeId, 'Integer')); $params['to_financial_account_id'] = CRM_Core_DAO::singleValueQuery("SELECT id FROM civicrm_financial_account WHERE is_default = 1 AND financial_account_type_id = %1", $queryParams); } $totalAmount = CRM_Utils_Array::value('total_amount', $params); if (!isset($totalAmount) && !empty($params['prevContribution'])) { $totalAmount = $params['total_amount'] = $params['prevContribution']->total_amount; } //build financial transaction params $trxnParams = array('contribution_id' => $params['contribution']->id, 'to_financial_account_id' => $params['to_financial_account_id'], 'trxn_date' => !empty($params['contribution']->receive_date) ? $params['contribution']->receive_date : date('YmdHis'), 'total_amount' => $totalAmount, 'fee_amount' => CRM_Utils_Array::value('fee_amount', $params), 'net_amount' => CRM_Utils_Array::value('net_amount', $params, $totalAmount), 'currency' => $params['contribution']->currency, 'trxn_id' => $params['contribution']->trxn_id, 'status_id' => $statusId, 'payment_instrument_id' => $params['contribution']->payment_instrument_id, 'check_number' => CRM_Utils_Array::value('check_number', $params)); if (!empty($params['payment_processor'])) { $trxnParams['payment_processor_id'] = $params['payment_processor']; } if (isset($fromFinancialAccountId)) { $trxnParams['from_financial_account_id'] = $fromFinancialAccountId; } // consider external values passed for recording transaction entry if (!empty($financialTrxnValues)) { $trxnParams = array_merge($trxnParams, $financialTrxnValues); } $params['trxnParams'] = $trxnParams; if (!empty($params['prevContribution'])) { $params['trxnParams']['total_amount'] = $trxnParams['total_amount'] = $params['total_amount'] = $params['prevContribution']->total_amount; $params['trxnParams']['fee_amount'] = $params['prevContribution']->fee_amount; $params['trxnParams']['net_amount'] = $params['prevContribution']->net_amount; $params['trxnParams']['trxn_id'] = $params['prevContribution']->trxn_id; $params['trxnParams']['status_id'] = $params['prevContribution']->contribution_status_id; if (!(($params['prevContribution']->contribution_status_id == array_search('Pending', $contributionStatuses) || $params['prevContribution']->contribution_status_id == array_search('In Progress', $contributionStatuses)) && $params['contribution']->contribution_status_id == array_search('Completed', $contributionStatuses))) { $params['trxnParams']['payment_instrument_id'] = $params['prevContribution']->payment_instrument_id; $params['trxnParams']['check_number'] = $params['prevContribution']->check_number; } //if financial type is changed if (!empty($params['financial_type_id']) && $params['contribution']->financial_type_id != $params['prevContribution']->financial_type_id) { $incomeTypeId = key(CRM_Core_PseudoConstant::accountOptionValues('account_relationship', NULL, " AND v.name LIKE 'Income Account is' ")); $oldFinancialAccount = CRM_Contribute_PseudoConstant::financialAccountType($params['prevContribution']->financial_type_id, $incomeTypeId); $newFinancialAccount = CRM_Contribute_PseudoConstant::financialAccountType($params['financial_type_id'], $incomeTypeId); if ($oldFinancialAccount != $newFinancialAccount) { $params['total_amount'] = 0; if (in_array($params['contribution']->contribution_status_id, $pendingStatus)) { $params['trxnParams']['to_financial_account_id'] = CRM_Contribute_PseudoConstant::financialAccountType($params['prevContribution']->financial_type_id, $relationTypeId); } else { $lastFinancialTrxnId = CRM_Core_BAO_FinancialTrxn::getFinancialTrxnId($params['prevContribution']->id, 'DESC'); if (!empty($lastFinancialTrxnId['financialTrxnId'])) { $params['trxnParams']['to_financial_account_id'] = CRM_Core_DAO::getFieldValue('CRM_Financial_DAO_FinancialTrxn', $lastFinancialTrxnId['financialTrxnId'], 'to_financial_account_id'); } } self::updateFinancialAccounts($params, 'changeFinancialType'); /* $params['trxnParams']['to_financial_account_id'] = $trxnParams['to_financial_account_id']; */ $params['financial_account_id'] = $newFinancialAccount; $params['total_amount'] = $params['trxnParams']['total_amount'] = $trxnParams['total_amount']; self::updateFinancialAccounts($params); $params['trxnParams']['to_financial_account_id'] = $trxnParams['to_financial_account_id']; } } //Update contribution status $params['trxnParams']['status_id'] = $params['contribution']->contribution_status_id; $params['trxnParams']['trxn_id'] = $params['contribution']->trxn_id; if (!empty($params['contribution_status_id']) && $params['prevContribution']->contribution_status_id != $params['contribution']->contribution_status_id) { //Update Financial Records self::updateFinancialAccounts($params, 'changedStatus'); } // change Payment Instrument for a Completed contribution // first handle special case when contribution is changed from Pending to Completed status when initial payment // 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'); } } 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'); } 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'); } } //if Change contribution amount $params['trxnParams']['fee_amount'] = CRM_Utils_Array::value('fee_amount', $params); $params['trxnParams']['net_amount'] = CRM_Utils_Array::value('net_amount', $params); $params['trxnParams']['total_amount'] = $trxnParams['total_amount'] = $params['total_amount'] = $totalAmount; $params['trxnParams']['trxn_id'] = $params['contribution']->trxn_id; if (isset($totalAmount) && $totalAmount != $params['prevContribution']->total_amount) { //Update Financial Records $params['trxnParams']['from_financial_account_id'] = NULL; self::updateFinancialAccounts($params, 'changedAmount'); } } if (!$update) { // records finanical trxn and entity financial trxn // also make it available as return value $return = $financialTxn = CRM_Core_BAO_FinancialTrxn::create($trxnParams); $params['entity_id'] = $financialTxn->id; } } // record line items and financial items if (empty($params['skipLineItem'])) { CRM_Price_BAO_LineItem::processPriceSet($entityId, CRM_Utils_Array::value('line_item', $params), $params['contribution'], $entityTable, $update); } // create batch entry if batch_id is passed and // ensure no batch entry is been made on 'Pending' or 'Failed' contribution, CRM-16611 if (!empty($params['batch_id']) && !empty($financialTxn)) { $entityParams = array('batch_id' => $params['batch_id'], 'entity_table' => 'civicrm_financial_trxn', 'entity_id' => $financialTxn->id); CRM_Batch_BAO_Batch::addBatchEntity($entityParams); } // when a fee is charged if (!empty($params['fee_amount']) && (empty($params['prevContribution']) || $params['contribution']->fee_amount != $params['prevContribution']->fee_amount) && $skipRecords) { CRM_Core_BAO_FinancialTrxn::recordFees($params); } if (!empty($params['prevContribution']) && $entityTable == 'civicrm_participant' && $params['prevContribution']->contribution_status_id != $params['contribution']->contribution_status_id) { $eventID = CRM_Core_DAO::getFieldValue('CRM_Event_DAO_Participant', $entityId, 'event_id'); $feeLevel[] = str_replace('', '', $params['prevContribution']->amount_level); CRM_Event_BAO_Participant::createDiscountTrxn($eventID, $params, $feeLevel); } unset($params['line_item']); return $return; }
public static function bulkAssignRemove() { $checkIDs = $_REQUEST['ID']; $entityID = CRM_Utils_Type::escape($_REQUEST['entityID'], 'String'); $action = CRM_Utils_Type::escape($_REQUEST['action'], 'String'); foreach ($checkIDs as $key => $value) { if (substr($value, 0, 7) == "mark_x_" && $action == 'Assign' || substr($value, 0, 7) == "mark_y_" && $action == 'Remove') { $contributions = explode("_", $value); $cIDs[] = $contributions[2]; } } $batchPID = CRM_Core_DAO::getFieldValue('CRM_Batch_DAO_Batch', $entityID, 'payment_instrument_id'); $paymentInstrument = CRM_Core_OptionGroup::getLabel('payment_instrument', $batchPID); foreach ($cIDs as $key => $value) { $recordPID = CRM_Core_DAO::getFieldValue('CRM_Financial_DAO_FinancialTrxn', $value, 'payment_instrument_id'); if ($action == 'Remove' || $recordPID == $batchPID && $action == 'Assign' || !isset($batchPID)) { $params = array('entity_id' => $value, 'entity_table' => 'civicrm_financial_trxn', 'batch_id' => $entityID); if ($action == 'Assign') { $updated = CRM_Batch_BAO_Batch::addBatchEntity($params); } else { $updated = CRM_Batch_BAO_Batch::removeBatchEntity($params); } } } if ($updated) { $status = array('status' => 'record-updated-success'); } else { $status = array('status' => ts("This batch is configured to include only transactions using %1 payment method. If you want to include other transactions, please edit the batch first and modify the Payment Method.", array(1 => $paymentInstrument))); } CRM_Utils_JSON::output($status); }