Skip to content

Commit

Permalink
Merge pull request civicrm#28461 from eileenmcnaughton/add_payment
Browse files Browse the repository at this point in the history
Fix tests calling AdditionalPayment form to use full flow, add standard ID get functions
  • Loading branch information
mattwire authored Dec 4, 2023
2 parents 6ef0fa1 + 6876b7b commit cef269a
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 58 deletions.
88 changes: 59 additions & 29 deletions CRM/Contribute/Form/AdditionalPayment.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
* @copyright CiviCRM LLC https://civicrm.org/licensing
*/

use Civi\Payment\Exception\PaymentProcessorException;

/**
* This form records additional payments needed when event/contribution is partially paid.
*/
Expand Down Expand Up @@ -48,7 +50,14 @@ class CRM_Contribute_Form_AdditionalPayment extends CRM_Contribute_Form_Abstract

protected $_paymentType = NULL;

protected $_contributionId = NULL;
/**
* Internal property for contribution ID - use getContributionID().
*
* @var int
*
* @internal
*/
protected $_contributionId;

protected $fromEmailId = NULL;

Expand All @@ -72,17 +81,11 @@ public function preProcess() {
$this->assign('id', $this->_id);
$this->assign('suppressPaymentFormButtons', $this->isBeingCalledFromSelectorContext());

if ($this->_view == 'transaction' && ($this->_action & CRM_Core_Action::BROWSE)) {
if ($this->_view === 'transaction' && ($this->_action & CRM_Core_Action::BROWSE)) {
$title = $this->assignPaymentInfoBlock();
$this->setTitle($title);
return;
}
if ($this->_component == 'event') {
$this->_contributionId = CRM_Core_DAO::getFieldValue('CRM_Event_DAO_ParticipantPayment', $this->_id, 'contribution_id', 'participant_id');
}
else {
$this->_contributionId = $this->_id;
}

$paymentAmt = $this->getAmountDue();

Expand All @@ -96,7 +99,7 @@ public function preProcess() {
throw new CRM_Core_Exception(ts('Credit card payment is not for Refund payments use'));
}

list($this->_contributorDisplayName, $this->_contributorEmail) = CRM_Contact_BAO_Contact_Location::getEmailDetails($this->_contactID);
[$this->_contributorDisplayName, $this->_contributorEmail] = CRM_Contact_BAO_Contact_Location::getEmailDetails($this->_contactID);

$this->assign('contributionMode', $this->_mode);
$this->assign('contactId', $this->_contactID);
Expand Down Expand Up @@ -134,7 +137,7 @@ protected function isBeingCalledFromSelectorContext() {
* @throws \CRM_Core_Exception
*/
public function setDefaultValues() {
if ($this->_view == 'transaction' && ($this->_action & CRM_Core_Action::BROWSE)) {
if ($this->_view === 'transaction' && ($this->_action & CRM_Core_Action::BROWSE)) {
return NULL;
}
$defaults = [];
Expand Down Expand Up @@ -309,9 +312,6 @@ public function postProcess() {
public function submit($submittedValues) {
$this->_params = $submittedValues;
$this->beginPostProcess();
// _contributorContactID may no longer need to be set - setting it here
// was for use in processBillingAddress
$this->_contributorContactID = $this->_contactID;
$this->processBillingAddress($this->_contactID, (string) $this->_contributorEmail);
$participantId = NULL;
if ($this->_component === 'event') {
Expand All @@ -334,13 +334,13 @@ public function submit($submittedValues) {
$trxnsData['is_send_contribution_notification'] = FALSE;
$paymentID = civicrm_api3('Payment', 'create', $trxnsData)['id'];

if ($this->_contributionId && CRM_Core_Permission::access('CiviMember')) {
if ($this->getContributionID() && CRM_Core_Permission::access('CiviMember')) {
$membershipPaymentCount = civicrm_api3('MembershipPayment', 'getCount', ['contribution_id' => $this->_contributionId]);
if ($membershipPaymentCount) {
$this->ajaxResponse['updateTabs']['#tab_member'] = CRM_Contact_BAO_Contact::getCountComponent('membership', $this->_contactID);
}
}
if ($this->_contributionId && CRM_Core_Permission::access('CiviEvent')) {
if ($this->getContributionID() && CRM_Core_Permission::access('CiviEvent')) {
$participantPaymentCount = civicrm_api3('ParticipantPayment', 'getCount', ['contribution_id' => $this->_contributionId]);
if ($participantPaymentCount) {
$this->ajaxResponse['updateTabs']['#tab_participant'] = CRM_Contact_BAO_Contact::getCountComponent('participant', $this->_contactID);
Expand All @@ -359,7 +359,7 @@ public function submit($submittedValues) {
CRM_Core_Session::setStatus($statusMsg, ts('Saved'), 'success');
}

public function processCreditCard() {
public function processCreditCard(): ?array {
$config = CRM_Core_Config::singleton();
$session = CRM_Core_Session::singleton();

Expand Down Expand Up @@ -409,11 +409,11 @@ public function processCreditCard() {

if ($paymentParams['amount'] > 0.0) {
try {
// force a reset of the payment processor in case the form changed it, CRM-7179
$payment = Civi\Payment\System::singleton()->getByProcessor($this->_paymentProcessor);
// Re-retrieve the payment processor in case the form changed it, CRM-7179
$payment = \Civi\Payment\System::singleton()->getById($this->getPaymentProcessorID());
$result = $payment->doPayment($paymentParams);
}
catch (\Civi\Payment\Exception\PaymentProcessorException $e) {
catch (PaymentProcessorException $e) {
Civi::log()->error('Payment processor exception: ' . $e->getMessage());
$urlParams = "action=add&cid={$this->_contactId}&id={$this->_contributionId}&component={$this->_component}&mode={$this->_mode}";
CRM_Core_Error::statusBounce($e->getMessage(), CRM_Utils_System::url('civicrm/payment/add', $urlParams));
Expand All @@ -425,27 +425,26 @@ public function processCreditCard() {
}

$this->set('params', $this->_params);

// set source if not set
if (empty($this->_params['source'])) {
$userID = $session->get('userID');
$userSortName = CRM_Core_DAO::getFieldValue('CRM_Contact_DAO_Contact', $userID,
'sort_name'
);
$this->_params['source'] = ts('Submit Credit Card Payment by: %1', [1 => $userSortName]);
}
return [
'fee_amount' => $result['fee_amount'] ?? 0,
'trxn_id' => $result['trxn_id'] ?? NULL,
'trxn_result_code' => $result['trxn_result_code'] ?? NULL,
];
}

/**
* Wrapper for unit testing the post process submit function.
*
* @deprecated since 5.69 will be removed around 5.75
*
* @param array $params
* @param string|null $creditCardMode
* @param string $entityType
*
* @throws \CRM_Core_Exception
*/
public function testSubmit($params, $creditCardMode = NULL, $entityType = 'contribute') {
CRM_Core_Error::deprecatedFunctionWarning('use FormTrait in tests');
$this->_bltID = 5;
// Required because processCreditCard calls set method on this.
$_SERVER['REQUEST_METHOD'] = 'GET';
Expand Down Expand Up @@ -516,9 +515,40 @@ protected function isARefund() {
*/
protected function getAmountDue(): float {
if (!isset($this->amountDue)) {
$this->amountDue = CRM_Contribute_BAO_Contribution::getContributionBalance($this->_contributionId);
$this->amountDue = CRM_Contribute_BAO_Contribution::getContributionBalance($this->getContributionID());
}
return $this->amountDue;
}

/**
* Get the selected Contribution ID.
*
* @api This function will not change in a minor release and is supported for
* use outside of core. This annotation / external support for properties
* is only given where there is specific test cover.
*
* @noinspection PhpUnhandledExceptionInspection
*/
public function getContributionID(): int {
if (!$this->_contributionId) {
$component = CRM_Utils_Request::retrieve('component', 'String', $this, FALSE, 'contribution');
if ($component === 'event') {
$this->_contributionId = CRM_Core_DAO::getFieldValue('CRM_Event_DAO_ParticipantPayment', $this->_id, 'contribution_id', 'participant_id');
}
else {
$this->_contributionId = $this->_id;
}
}
return (int) $this->_contributionId;
}

/**
* Get the payment processor ID.
*
* @return int
*/
public function getPaymentProcessorID(): int {
return (int) ($this->getSubmittedValue('payment_processor_id') ?: $this->_paymentProcessor['id']);
}

}
11 changes: 3 additions & 8 deletions tests/phpunit/CRM/Contribute/Form/ContributionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -959,8 +959,6 @@ protected function getCreditCardParams(): array {

/**
* Test the submit function that completes the partially paid payment using Credit Card
*
* @throws \CRM_Core_Exception
*/
public function testPartialPaymentWithCreditCard(): void {
// create a partially paid contribution by using back-office form
Expand All @@ -979,11 +977,7 @@ public function testPartialPaymentWithCreditCard(): void {
$this->callAPISuccess('Payment', 'create', ['contribution_id' => $contribution['id'], 'total_amount' => 10, 'payment_instrument_id' => 'Cash']);
$contribution = $this->callAPISuccessGetSingle('Contribution', ['id' => $contribution['id']]);
$this->assertEquals('Partially paid', $contribution['contribution_status']);
// pay additional amount by using Credit Card
$form = new CRM_Contribute_Form_AdditionalPayment();
$form->testSubmit([
'contribution_id' => $contribution['id'],
'contact_id' => $this->_individualId,
$form = $this->getTestForm('CRM_Contribute_Form_AdditionalPayment', [
'total_amount' => 40,
'currency' => 'USD',
'financial_type_id' => 1,
Expand All @@ -998,7 +992,8 @@ public function testPartialPaymentWithCreditCard(): void {
'billing_postal_code-5' => 1321312,
'billing_country_id-5' => 1228,
'trxn_date' => '2017-04-11 13:05:11',
], 'live');
], ['id' => $contribution['id'], 'mode' => 'live'])->processForm();
$this->assertEquals($contribution['id'], $form->getContributionID());
$contribution = $this->callAPISuccessGetSingle('Contribution', []);
$this->assertNotEmpty($contribution);
$this->assertEquals('Completed', $contribution['contribution_status']);
Expand Down
40 changes: 19 additions & 21 deletions tests/phpunit/CRM/Member/Form/MembershipTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
use Civi\Api4\Membership;
use Civi\Api4\MembershipType;
use Civi\Api4\PriceFieldValue;
use Civi\Test\FormTrait;

/**
* Test CRM_Member_Form_Membership functions.
Expand All @@ -32,6 +33,7 @@ class CRM_Member_Form_MembershipTest extends CiviUnitTestCase {

use CRMTraits_Financial_OrderTrait;
use CRMTraits_Financial_PriceSetTrait;
use FormTrait;

/**
* @var int
Expand Down Expand Up @@ -799,20 +801,18 @@ public function testSubmitPartialPayment(string $thousandSeparator): void {

// Step 2: submit the other half of the partial payment
// via AdditionalPayment form to complete the related contribution
$form = new CRM_Contribute_Form_AdditionalPayment();
$submitParams = [
'contribution_id' => $contribution['contribution_id'],
'contact_id' => $this->_individualId,
'total_amount' => $this->formatMoneyInput(25),
'currency' => 'USD',
'financial_type_id' => 2,
'receive_date' => '2015-04-21 23:27:00',
$this->getTestForm('CRM_Contribute_Form_AdditionalPayment', [
'total_amount' => 150.00,
'trxn_date' => '2017-04-11 13:05:11',
'payment_processor_id' => 0,
'payment_instrument_id' => array_search('Check', $this->paymentInstruments, TRUE),
'payment_instrument_id' => CRM_Core_PseudoConstant::getKey('CRM_Financial_BAO_FinancialTrxn', 'payment_instrument_id', 'Check'),
'check_number' => 'check-12345',
];
$form->testSubmit($submitParams);
'trxn_id' => '',
'currency' => 'USD',
'fee_amount' => '',
'net_amount' => '',
'payment_processor_id' => 0,
'contact_id' => $this->_individualId,
], ['id' => $contribution['id']])->processForm();
$membership = $this->callAPISuccessGetSingle('Membership', ['contact_id' => $this->_individualId]);
// check the membership status after additional payment, if its changed to 'New'
$this->assertEquals(array_search('New', CRM_Member_PseudoConstant::membershipStatus(), TRUE), $membership['status_id']);
Expand Down Expand Up @@ -1511,7 +1511,7 @@ public function testLineItemAmountOnSalesTax(): void {
'price_' . $fieldOption['price_field_id'] => $fieldOption['id'],
'total_amount' => 55,
'receive_date' => date('Y-m-d') . ' 20:36:00',
'payment_instrument_id' => array_search('Check', $this->paymentInstruments, TRUE),
'payment_instrument_id' => CRM_Core_PseudoConstant::getKey('CRM_Financial_BAO_FinancialTrxn', 'payment_instrument_id', 'Check'),
'contribution_status_id' => CRM_Core_PseudoConstant::getKey('CRM_Contribute_BAO_Contribution', 'contribution_status_id', 'Completed'),
//Member dues, see data.xml
'financial_type_id' => 2,
Expand Down Expand Up @@ -1648,16 +1648,15 @@ public function testCreatePendingWithMultipleTerms(): void {
'contact_id' => $this->_individualId,
]);
$endDate = (new DateTime(date('Y-m-d')))->modify('+3 years')->modify('-1 day');
$endDate = $endDate->format("Y-m-d");
$endDate = $endDate->format('Y-m-d');

$this->assertEquals($endDate, $membership['end_date'], 'Membership Expiration Date should be ' . $endDate);
$this->assertEquals(1, count($contribution['values']), 'Pending contribution should be created.');
$this->assertCount(1, $contribution['values'], 'Pending contribution should be created.');
$contribution = $contribution['values'][$contribution['id']];
$additionalPaymentForm = new CRM_Contribute_Form_AdditionalPayment();
$additionalPaymentForm->testSubmit([
$this->getTestForm('CRM_Contribute_Form_AdditionalPayment', [
'total_amount' => 150.00,
'trxn_date' => date("Y-m-d H:i:s"),
'payment_instrument_id' => array_search('Check', $this->paymentInstruments),
'trxn_date' => date('Y-m-d H:i:s'),
'payment_instrument_id' => CRM_Core_PseudoConstant::getKey('CRM_Financial_BAO_FinancialTrxn', 'payment_instrument_id', 'Check'),
'check_number' => 'check-12345',
'trxn_id' => '',
'currency' => 'USD',
Expand All @@ -1666,8 +1665,7 @@ public function testCreatePendingWithMultipleTerms(): void {
'net_amount' => '',
'payment_processor_id' => 0,
'contact_id' => $this->_individualId,
'contribution_id' => $contribution['id'],
]);
], ['id' => $contribution['id']])->processForm();
$membership = $this->callAPISuccessGetSingle('Membership', ['contact_id' => $this->_individualId]);
$contribution = $this->callAPISuccess('Contribution', 'get', [
'contact_id' => $this->_individualId,
Expand Down

0 comments on commit cef269a

Please sign in to comment.