diff --git a/CRM/Contribute/BAO/Contribution.php b/CRM/Contribute/BAO/Contribution.php index 9440b936b0bb..c7a653d6a0dc 100644 --- a/CRM/Contribute/BAO/Contribution.php +++ b/CRM/Contribute/BAO/Contribution.php @@ -4477,6 +4477,92 @@ public static function isSingleLineItem($id) { return ($lineItemCount == 1); } + /** + * Function to process additional payment for partial and refund contributions. + * + * This function is called via API payment.create function. All forms that add payments + * should use this. + * + * @param array $params + * - contribution_id + * - total_amount + * - line_item + * @return \CRM_Financial_DAO_FinancialTrxn + * + * @throws \API_Exception + * @throws \CRM_Core_Exception + */ + public static function addPayment($params) { + $contribution = civicrm_api3('Contribution', 'getsingle', ['id' => $params['contribution_id']]); + $contributionStatus = CRM_Contribute_PseudoConstant::contributionStatus($contribution['contribution_status_id'], 'name'); + if ($contributionStatus != 'Partially paid' + && !($contributionStatus == 'Pending' && $contribution['is_pay_later'] == TRUE) + ) { + throw new API_Exception('Please select a contribution which has a partial or pending payment'); + } + else { + // Check if pending contribution + $fullyPaidPayLater = FALSE; + if ($contributionStatus == 'Pending') { + $cmp = bccomp($contribution['total_amount'], $params['total_amount'], 5); + // Total payment amount is the whole amount paid against pending contribution + if ($cmp == 0 || $cmp == -1) { + civicrm_api3('Contribution', 'completetransaction', ['id' => $contribution['id']]); + // Get the trxn + $trxnId = CRM_Core_BAO_FinancialTrxn::getFinancialTrxnId($contribution['id'], 'DESC'); + $ftParams = ['id' => $trxnId['financialTrxnId']]; + $trxn = CRM_Core_BAO_FinancialTrxn::retrieve($ftParams, CRM_Core_DAO::$_nullArray); + $fullyPaidPayLater = TRUE; + } + else { + civicrm_api3('Contribution', 'create', + [ + 'id' => $contribution['id'], + 'contribution_status_id' => 'Partially paid', + ] + ); + } + } + if (!$fullyPaidPayLater) { + $trxn = CRM_Core_BAO_FinancialTrxn::getPartialPaymentTrxn($contribution, $params); + if (CRM_Utils_Array::value('line_item', $params) && !empty($trxn)) { + foreach ($params['line_item'] as $values) { + foreach ($values as $id => $amount) { + $p = ['id' => $id]; + $check = CRM_Price_BAO_LineItem::retrieve($p, $defaults); + if (empty($check)) { + throw new API_Exception('Please specify a valid Line Item.'); + } + // get financial item + $sql = "SELECT fi.id + FROM civicrm_financial_item fi + INNER JOIN civicrm_line_item li ON li.id = fi.entity_id and fi.entity_table = 'civicrm_line_item' + WHERE li.contribution_id = %1 AND li.id = %2"; + $sqlParams = [ + 1 => [$params['contribution_id'], 'Integer'], + 2 => [$id, 'Integer'], + ]; + $fid = CRM_Core_DAO::singleValueQuery($sql, $sqlParams); + // Record Entity Financial Trxn + $eftParams = [ + 'entity_table' => 'civicrm_financial_item', + 'financial_trxn_id' => $trxn->id, + 'amount' => $amount, + 'entity_id' => $fid, + ]; + civicrm_api3('EntityFinancialTrxn', 'create', $eftParams); + } + } + } + elseif (!empty($trxn)) { + CRM_Contribute_BAO_Contribution::assignProportionalLineItems($params, $trxn->id, $contribution['total_amount']); + } + } + } + return $trxn; + + } + /** * Complete an order. * diff --git a/api/v3/Payment.php b/api/v3/Payment.php index 1c144b43bc07..b80e899aa6ca 100644 --- a/api/v3/Payment.php +++ b/api/v3/Payment.php @@ -132,74 +132,8 @@ function civicrm_api3_payment_create(&$params) { civicrm_api3('Payment', 'cancel', $params); $params['total_amount'] = $amount; } - // Get contribution - $contribution = civicrm_api3('Contribution', 'getsingle', array('id' => $params['contribution_id'])); - $contributionStatus = CRM_Contribute_PseudoConstant::contributionStatus($contribution['contribution_status_id'], 'name'); - if ($contributionStatus != 'Partially paid' - && !($contributionStatus == 'Pending' && $contribution['is_pay_later'] == TRUE) - ) { - throw new API_Exception('Please select a contribution which has a partial or pending payment'); - } - else { - // Check if pending contribution - $fullyPaidPayLater = FALSE; - if ($contributionStatus == 'Pending') { - $cmp = bccomp($contribution['total_amount'], $params['total_amount'], 5); - // Total payment amount is the whole amount paid against pending contribution - if ($cmp == 0 || $cmp == -1) { - civicrm_api3('Contribution', 'completetransaction', array('id' => $contribution['id'])); - // Get the trxn - $trxnId = CRM_Core_BAO_FinancialTrxn::getFinancialTrxnId($contribution['id'], 'DESC'); - $ftParams = array('id' => $trxnId['financialTrxnId']); - $trxn = CRM_Core_BAO_FinancialTrxn::retrieve($ftParams, CRM_Core_DAO::$_nullArray); - $fullyPaidPayLater = TRUE; - } - else { - civicrm_api3('Contribution', 'create', - array( - 'id' => $contribution['id'], - 'contribution_status_id' => 'Partially paid', - ) - ); - } - } - if (!$fullyPaidPayLater) { - $trxn = CRM_Core_BAO_FinancialTrxn::getPartialPaymentTrxn($contribution, $params); - if (CRM_Utils_Array::value('line_item', $params) && !empty($trxn)) { - foreach ($params['line_item'] as $values) { - foreach ($values as $id => $amount) { - $p = array('id' => $id); - $check = CRM_Price_BAO_LineItem::retrieve($p, $defaults); - if (empty($check)) { - throw new API_Exception('Please specify a valid Line Item.'); - } - // get financial item - $sql = "SELECT fi.id - FROM civicrm_financial_item fi - INNER JOIN civicrm_line_item li ON li.id = fi.entity_id and fi.entity_table = 'civicrm_line_item' - WHERE li.contribution_id = %1 AND li.id = %2"; - $sqlParams = array( - 1 => array($params['contribution_id'], 'Integer'), - 2 => array($id, 'Integer'), - ); - $fid = CRM_Core_DAO::singleValueQuery($sql, $sqlParams); - // Record Entity Financial Trxn - $eftParams = array( - 'entity_table' => 'civicrm_financial_item', - 'financial_trxn_id' => $trxn->id, - 'amount' => $amount, - 'entity_id' => $fid, - ); - civicrm_api3('EntityFinancialTrxn', 'create', $eftParams); - } - } - } - elseif (!empty($trxn)) { - // Assign the lineitems proportionally - CRM_Contribute_BAO_Contribution::assignProportionalLineItems($params, $trxn->id, $contribution['total_amount']); - } - } - } + $trxn = CRM_Contribute_BAO_Contribution::addPayment($params); + $values = array(); _civicrm_api3_object_to_array_unique_fields($trxn, $values[$trxn->id]); return civicrm_api3_create_success($values, $params, 'Payment', 'create', $trxn);