From cd6621a4daf429510707b085428703d2b17f2fdc Mon Sep 17 00:00:00 2001 From: eileen Date: Mon, 31 Dec 2018 10:45:47 +1300 Subject: [PATCH] [REF] extract internals of Payment.create into function on BAO class. This is a partial of https://github.com/civicrm/civicrm-core/pull/13330 - trying to separate out the main code move from the changes. My only change was to change the name to addPayment since that is what we are doing but here are some additionaly thoughts. 1) I'm inclined to put the class onto a new pseudo-bao CRM_Finanial_BAO_Payment. We already have this pseudo-entity on the api level & it gives us a way to build up a place for the functions we are migrating towards. 2) I think we should consider changing the input parameters to this function to be - contributionID, total_amount & line_items or in some way limiting the parameters tha t get passed through. We have historically gotten ourselves in trouble by having people hacking in another parameter to go through whereas the strength of the api is clear inputs & outputs. I note the api will need to support 'is_email_receipt' as will this fn & the CRM_Contribute_Form_AdditionalPayment::emailReceipt should be moved off the form layer - possibly to our new BAO 3) I think the exceptions need to be CRM_Core_Exceptions if thrown in the BAO although this is kinda cosmetic --- CRM/Contribute/BAO/Contribution.php | 86 ++++++++++++++++++ api/v3/Payment.php | 70 +-------------- tests/phpunit/CRMTraits/PCP/PCPTestTrait.php | 91 ++++++++++++++++++++ 3 files changed, 179 insertions(+), 68 deletions(-) create mode 100644 tests/phpunit/CRMTraits/PCP/PCPTestTrait.php 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); diff --git a/tests/phpunit/CRMTraits/PCP/PCPTestTrait.php b/tests/phpunit/CRMTraits/PCP/PCPTestTrait.php new file mode 100644 index 000000000000..522a553d415a --- /dev/null +++ b/tests/phpunit/CRMTraits/PCP/PCPTestTrait.php @@ -0,0 +1,91 @@ +id; + $supporterProfile = CRM_Core_DAO::createTestObject('CRM_Core_DAO_UFGroup'); + $supporterProfileId = $supporterProfile->id; + + $params = array( + 'entity_table' => 'civicrm_contribution_page', + 'entity_id' => $contribPageId, + 'supporter_profile_id' => $supporterProfileId, + 'target_entity_id' => 1, + 'is_approval_needed' => 1, + 'is_tellfriend_enabled' => 1, + 'tellfriend_limit' => 1, + 'link_text' => 'Create your own PCP', + 'is_active' => 1, + ); + + return $params; + } + + /** + * Build and return pcp params. + * + * Create the necessary initial objects for a pcp page, then return the + * params needed to create the pcp page. + */ + public function pcpParams() { + $contact = CRM_Core_DAO::createTestObject('CRM_Contact_DAO_Contact'); + $contactId = $contact->id; + $contribPage = CRM_Core_DAO::createTestObject('CRM_Contribute_DAO_ContributionPage'); + $contribPageId = $contribPage->id; + + $params = array( + 'contact_id' => $contactId, + 'status_id' => '1', + 'title' => 'My PCP', + 'intro_text' => 'Hey you, contribute now!', + 'page_text' => 'You better give more.', + 'donate_link_text' => 'Donate Now', + 'page_id' => $contribPageId, + 'is_thermometer' => 1, + 'is_honor_roll' => 1, + 'goal_amount' => 10000.00, + 'is_active' => 1, + ); + + return $params; + } + +}