From c60d3584fb9544223745ed7e1bd7cc5267edc73f Mon Sep 17 00:00:00 2001 From: Pradeep Nayak Date: Thu, 28 Jan 2016 04:02:27 +0530 Subject: [PATCH] CRM-16259, changes for pending status for adding payments and added unit test CRM-16259# ---------------------------------------- * CRM-16259: Create Payment API https://issues.civicrm.org/jira/browse/CRM-16259 Conflicts: tests/phpunit/api/v3/PaymentTest.php --- api/v3/Payment.php | 97 ++++++++++------- tests/phpunit/api/v3/PaymentTest.php | 152 +++++++++++++++++++-------- 2 files changed, 168 insertions(+), 81 deletions(-) diff --git a/api/v3/Payment.php b/api/v3/Payment.php index 4de7545221..ade66f0f22 100644 --- a/api/v3/Payment.php +++ b/api/v3/Payment.php @@ -134,51 +134,72 @@ function civicrm_api3_payment_create(&$params) { } // Get contribution $contribution = civicrm_api3('Contribution', 'getsingle', array('id' => $params['contribution_id'])); - if ($contribution['contribution_status'] != 'Partially paid') { - throw new API_Exception('Please select a contribution which has a partial payment'); + $contributionStatus = CRM_Contribute_PseudoConstant::contributionStatus(NULL, 'name'); + if ($contributionStatus[$contribution['contribution_status_id']] != 'Partially paid' + && !($contributionStatus[$contribution['contribution_status_id']] = 'Pending' && $contribution['is_pay_later'] == TRUE) + ) { + throw new API_Exception('Please select a contribution which has a partial or pending payment'); } else { - $trxn = CRM_Contribute_BAO_Contribution::recordPartialPayment($contribution, $params); - $paid = CRM_Core_BAO_FinancialTrxn::getTotalPayments($params['contribution_id']); - $total = CRM_Core_DAO::getFieldValue('CRM_Contribute_DAO_Contribution', $params['contribution_id'], 'total_amount'); - $cmp = bccomp($total, $paid, 5); - if ($cmp == 0 || $cmp == -1) {// If paid amount is greater or equal to total amount - civicrm_api3('Contribution', 'completetransaction', array('id' => $contribution['id'])); + // Check if pending contribution + $fullyPaidPayLater = FALSE; + if ($contributionStatus[$contribution['contribution_status_id']] == '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' => array_search('Partially paid', $contributionStatus), + ) + ); + } } - } - 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.'); + 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 + 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); + } } - // get financial item - $sql = "SELECT fi.id - FROM civicrm_financial_item fi - INNER JOIN civicrm_line_item li ON li.id = fi.entity_id - 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, $contribution); } } } - elseif (!empty($trxn)) { - // Assign the lineitems proportionally - CRM_Contribute_BAO_Contribution::assignProportionalLineItems($params, $trxn, $contribution); - } $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/api/v3/PaymentTest.php b/tests/phpunit/api/v3/PaymentTest.php index 3ad33a7380..672e54eab7 100644 --- a/tests/phpunit/api/v3/PaymentTest.php +++ b/tests/phpunit/api/v3/PaymentTest.php @@ -84,16 +84,19 @@ class api_v3_PaymentTest extends CiviUnitTestCase { $payment = $this->callAPIFailure('payment', 'get', $params, 'API permission check failed for Payment/get call; insufficient permission: require access CiviCRM and access CiviContribute'); array_push(CRM_Core_Config::singleton()->userPermissionClass->permissions, 'access CiviContribute'); + $payment = $this->callAPISuccess('payment', 'get', $params); $payment = $this->callAPIAndDocument('payment', 'get', $params, __FUNCTION__, __FILE__); $this->assertEquals(1, $payment['count']); $expectedResult = array( - 'total_amount' => 100, - 'trxn_id' => 23456, - 'trxn_date' => '2010-01-20 00:00:00', - 'contribution_id' => $contribution['id'], - 'is_payment' => 1, + $contribution['id'] => array( + 'total_amount' => 100, + 'trxn_id' => 23456, + 'trxn_date' => '2010-01-20 00:00:00', + 'contribution_id' => $contribution['id'], + 'is_payment' => 1, + ), ); $this->checkPaymentResult($payment, $expectedResult); $this->callAPISuccess('Contribution', 'Delete', array( @@ -112,13 +115,15 @@ class api_v3_PaymentTest extends CiviUnitTestCase { 'contribution_id' => $contribution['id'], 'total_amount' => 50, ); - $payment = $this->callAPIAndDocument('payment', 'create', $params, __FUNCTION__, __FILE__); + $payment = $this->callAPISuccess('payment', 'create', $params); $expectedResult = array( - 'from_financial_account_id' => 7, - 'to_financial_account_id' => 6, - 'total_amount' => 50, - 'status_id' => 1, - 'is_payment' => 1, + $payment['id'] => array( + 'from_financial_account_id' => 7, + 'to_financial_account_id' => 6, + 'total_amount' => 50, + 'status_id' => 1, + 'is_payment' => 1, + ), ); $this->checkPaymentResult($payment, $expectedResult); @@ -148,13 +153,15 @@ class api_v3_PaymentTest extends CiviUnitTestCase { 'contribution_id' => $contribution['id'], 'total_amount' => 100, ); - $payment = $this->callAPIAndDocument('payment', 'create', $params, __FUNCTION__, __FILE__); + $payment = $this->callAPISuccess('payment', 'create', $params); $expectedResult = array( - 'from_financial_account_id' => 7, - 'to_financial_account_id' => 6, - 'total_amount' => 100, - 'status_id' => 1, - 'is_payment' => 1, + $payment['id'] => array( + 'from_financial_account_id' => 7, + 'to_financial_account_id' => 6, + 'total_amount' => 100, + 'status_id' => 1, + 'is_payment' => 1, + ), ); $this->checkPaymentResult($payment, $expectedResult); $params = array( @@ -186,7 +193,7 @@ class api_v3_PaymentTest extends CiviUnitTestCase { * Function to assert db values */ public function checkPaymentResult($payment, $expectedResult) { - foreach ($expectedResult as $key => $value) { + foreach ($expectedResult[$payment['id']] as $key => $value) { $this->assertEquals($payment['values'][$payment['id']][$key], $value); } } @@ -207,13 +214,15 @@ class api_v3_PaymentTest extends CiviUnitTestCase { foreach ($lineItems['values'] as $id => $ignore) { $params['line_item'][] = array($id => array_pop($amounts)); } - $payment = $this->callAPIAndDocument('payment', 'create', $params, __FUNCTION__, __FILE__); + $payment = $this->callAPISuccess('payment', 'create', $params); $expectedResult = array( - 'from_financial_account_id' => 7, - 'to_financial_account_id' => 6, - 'total_amount' => 50, - 'status_id' => 1, - 'is_payment' => 1, + $payment['id'] => array( + 'from_financial_account_id' => 7, + 'to_financial_account_id' => 6, + 'total_amount' => 50, + 'status_id' => 1, + 'is_payment' => 1, + ), ); $this->checkPaymentResult($payment, $expectedResult); @@ -247,13 +256,15 @@ class api_v3_PaymentTest extends CiviUnitTestCase { foreach ($lineItems['values'] as $id => $ignore) { $params['line_item'][] = array($id => array_pop($amounts)); } - $payment = $this->callAPIAndDocument('payment', 'create', $params, __FUNCTION__, __FILE__); + $payment = $this->callAPISuccess('payment', 'create', $params); $expectedResult = array( - 'from_financial_account_id' => 7, - 'to_financial_account_id' => 6, - 'total_amount' => 100, - 'status_id' => 1, - 'is_payment' => 1, + $payment['id'] => array( + 'from_financial_account_id' => 7, + 'to_financial_account_id' => 6, + 'total_amount' => 100, + 'status_id' => 1, + 'is_payment' => 1, + ), ); $this->checkPaymentResult($payment, $expectedResult); $params = array( @@ -303,9 +314,9 @@ class api_v3_PaymentTest extends CiviUnitTestCase { array_push(CRM_Core_Config::singleton()->userPermissionClass->permissions, 'access CiviCRM', 'edit contributions'); - $this->callAPIAndDocument('payment', 'cancel', $cancelParams, __FUNCTION__, __FILE__); + $this->callAPIAndDocument('payment', 'cancel', $cancelParams); - $payment = $this->callAPIAndDocument('payment', 'get', $params, __FUNCTION__, __FILE__); + $payment = $this->callAPISuccess('payment', 'get', $params); $this->assertEquals(2, $payment['count']); $amounts = array(-150.00, 150.00); foreach ($payment['values'] as $value) { @@ -328,7 +339,7 @@ class api_v3_PaymentTest extends CiviUnitTestCase { 'contribution_id' => $contribution['id'], ); - $payment = $this->callAPIAndDocument('payment', 'get', $params, __FUNCTION__, __FILE__); + $payment = $this->callAPISuccess('payment', 'get', $params); $this->assertEquals(1, $payment['count']); $deleteParams = array( @@ -338,9 +349,9 @@ class api_v3_PaymentTest extends CiviUnitTestCase { $payment = $this->callAPIFailure('payment', 'delete', $deleteParams, 'API permission check failed for Payment/get call; insufficient permission: require access CiviCRM and delete in CiviContribute'); array_push(CRM_Core_Config::singleton()->userPermissionClass->permissions, 'access CiviCRM', 'delete in CiviContribute'); - $this->callAPIAndDocument('payment', 'delete', $deleteParams, __FUNCTION__, __FILE__); + $this->callAPISuccess('payment', 'delete', $cancelParams); - $payment = $this->callAPIAndDocument('payment', 'get', $params, __FUNCTION__, __FILE__); + $payment = $this->callAPISuccess('payment', 'get', $params); $this->assertEquals(0, $payment['count']); $this->callAPISuccess('Contribution', 'Delete', array( @@ -361,13 +372,15 @@ class api_v3_PaymentTest extends CiviUnitTestCase { 'total_amount' => 50, ); - $payment = $this->callAPIAndDocument('payment', 'create', $params, __FUNCTION__, __FILE__); + $payment = $this->callAPISuccess('payment', 'create', $params); $expectedResult = array( - 'from_financial_account_id' => 7, - 'to_financial_account_id' => 6, - 'total_amount' => 50, - 'status_id' => 1, - 'is_payment' => 1, + $payment['id'] => array( + 'from_financial_account_id' => 7, + 'to_financial_account_id' => 6, + 'total_amount' => 50, + 'status_id' => 1, + 'is_payment' => 1, + ), ); $this->checkPaymentResult($payment, $expectedResult); @@ -392,7 +405,7 @@ class api_v3_PaymentTest extends CiviUnitTestCase { $payment = $this->callAPIFailure('payment', 'create', $params, 'API permission check failed for Payment/get call; insufficient permission: require access CiviCRM and edit contributions'); array_push(CRM_Core_Config::singleton()->userPermissionClass->permissions, 'access CiviCRM', 'edit contributions'); - $payment = $this->callAPIAndDocument('payment', 'create', $params, __FUNCTION__, __FILE__); + $payment = $this->callAPISuccess('payment', 'create', $params); $params = array( 'entity_table' => 'civicrm_financial_item', @@ -407,7 +420,7 @@ class api_v3_PaymentTest extends CiviUnitTestCase { $params = array( 'contribution_id' => $contribution['id'], ); - $payment = $this->callAPIAndDocument('payment', 'get', $params, __FUNCTION__, __FILE__); + $payment = $this->callAPISuccess('payment', 'get', $params); $amounts = array(100.00, -50.00, 50.00, 150.00); foreach ($payment['values'] as $value) { $amount = array_pop($amounts); @@ -428,4 +441,57 @@ class api_v3_PaymentTest extends CiviUnitTestCase { )); } + /** + * Test create payment api for paylater contribution + */ + public function testCreatePaymentPayLater() { + $this->createLoggedInUser(); + $contributionParams = array( + 'total_amount' => 100, + 'currency' => 'USD', + 'contact_id' => $this->_individualId, + 'financial_type_id' => 1, + 'contribution_status_id' => 2, + 'is_pay_later' => 1, + ); + $contribution = $this->callAPISuccess('Contribution', 'create', $contributionParams); + //Create partial payment + $params = array( + 'contribution_id' => $contribution['id'], + 'total_amount' => 100, + ); + $payment = $this->callAPISuccess('Payment', 'create', $params); + $expectedResult = array( + $payment['id'] => array( + 'from_financial_account_id' => 7, + 'to_financial_account_id' => 6, + 'total_amount' => 100, + 'status_id' => 1, + 'is_payment' => 1, + ), + ); + $this->checkPaymentResult($payment, $expectedResult); + // Check entity financial trxn created properly + $params = array( + 'entity_id' => $contribution['id'], + 'entity_table' => 'civicrm_contribution', + 'financial_trxn_id' => $payment['id'], + ); + $eft = $this->callAPISuccess('EntityFinancialTrxn', 'get', $params); + $this->assertEquals($eft['values'][$eft['id']]['amount'], 100); + $params = array( + 'entity_table' => 'civicrm_financial_item', + 'financial_trxn_id' => $payment['id'], + ); + $eft = $this->callAPISuccess('EntityFinancialTrxn', 'get', $params); + $this->assertEquals($eft['values'][$eft['id']]['amount'], 100); + // Check contribution for completed status + $contribution = $this->callAPISuccess('contribution', 'get', array('id' => $contribution['id'])); + $this->assertEquals($contribution['values'][$contribution['id']]['contribution_status'], 'Completed'); + $this->assertEquals($contribution['values'][$contribution['id']]['total_amount'], 100.00); + $this->callAPISuccess('Contribution', 'Delete', array( + 'id' => $contribution['id'], + )); + } + } -- 2.25.1