4 * Test CRM_Event_Form_Registration functions.
9 class CRM_Event_Form_ParticipantTest
extends CiviUnitTestCase
{
12 * Options on the from Email address array.
16 protected $fromEmailAddressOptions = [];
18 public function setUp() {
19 $this->useTransaction(TRUE);
24 * CHeck that all tests that have created payments have created them with the right financial entities.
26 * Ideally this would be on CiviUnitTestCase but many classes would still fail. Also, it might
27 * be good if it only ran on tests that created at least one contribution.
29 * @throws \CRM_Core_Exception
31 protected function assertPostConditions() {
32 $this->validateAllPayments();
33 $this->validateAllContributions();
37 * Initial test of submit function.
41 public function testSubmit() {
42 $form = $this->getForm();
44 'register_date' => date('Ymd'),
47 'event_id' => $form->_eventId
,
49 $this->callAPISuccessGetSingle('Participant', []);
53 * Test financial items pending transaction is later altered.
57 public function testSubmitUnpaidPriceChangeWhileStillPending() {
58 $form = $this->getForm(['is_monetary' => 1, 'financial_type_id' => 1]);
59 $form->_quickConfig
= TRUE;
64 'price_field_id' => $this->getPriceFieldID(),
65 'price_field_value_id' => $this->_ids
['price_field_value'][0],
66 'label' => 'Tiny-tots (ages 5-8)',
67 'field_title' => 'Tournament Fees',
68 'description' => NULL,
70 'unit_price' => '800.000000000',
71 'line_total' => 800.0,
72 'participant_count' => 0,
74 'membership_type_id' => NULL,
75 'membership_num_terms' => NULL,
77 'html_type' => 'Radio',
78 'financial_type_id' => '4',
80 'non_deductible_amount' => '0.00',
84 $form->setAction(CRM_Core_Action
::ADD
);
85 $form->_priceSetId
= $this->getPriceSetID();
87 'register_date' => date('Ymd'),
90 'event_id' => $form->_eventId
,
91 'priceSetId' => $this->getPriceSetID(),
92 $this->getPriceFieldKey() => $this->_ids
['price_field_value'][0],
94 'amount_level' => 'Too much',
97 'payment_processor_id' => 0,
98 'record_contribution' => TRUE,
99 'financial_type_id' => 1,
100 'contribution_status_id' => 2,
101 'payment_instrument_id' => 1,
102 'receive_date' => date('Y-m-d'),
104 $participant = $this->callAPISuccessGetSingle('Participant', []);
105 $contribution = $this->callAPISuccessGetSingle('Contribution', []);
106 $this->assertEquals(2, $contribution['contribution_status_id']);
107 $this->callAPISuccessGetSingle('FinancialItem', []);
109 $priceSetParams[$this->getPriceFieldKey()] = $this->getPriceFieldValueID();
110 $lineItem = CRM_Price_BAO_LineItem
::getLineItems($participant['id'], 'participant');
111 $this->assertEquals(55, $lineItem[1]['subTotal']);
112 $financialItems = $this->callAPISuccess('FinancialItem', 'get', []);
114 foreach ($financialItems['values'] as $financialItem) {
115 $sum +
= $financialItem['amount'];
117 $this->assertEquals(55, $sum);
119 CRM_Price_BAO_LineItem
::changeFeeSelections($priceSetParams, $participant['id'], 'participant', $contribution['id'], $this->eventFeeBlock
, $lineItem);
120 // Check that no payment records have been created.
121 // In https://lab.civicrm.org/dev/financial/issues/94 we had an issue where payments were created when none happend.
122 $payments = $this->callAPISuccess('Payment', 'get', [])['values'];
123 $this->assertCount(0, $payments);
124 $lineItem = CRM_Price_BAO_LineItem
::getLineItems($participant['id'], 'participant');
125 // Participants is updated to 0 but line remains.
126 $this->assertEquals(0, $lineItem[1]['subTotal']);
127 $this->assertEquals(1550.55, $lineItem[2]['subTotal']);
128 $financialItems = $this->callAPISuccess('FinancialItem', 'get', []);
131 foreach ($financialItems['values'] as $financialItem) {
132 $sum +
= $financialItem['amount'];
134 $this->assertEquals(1550.55, $sum);
138 * (dev/core#310) : Test to ensure payments are correctly allocated, when a event fee is changed for a mult-line item event registration
140 * @throws \CRM_Core_Exception
141 * @throws \CiviCRM_API3_Exception
143 public function testPaymentAllocationOnMultiLineItemEvent() {
145 // 1. Create a Price set with two price fields
146 // 2. Register for a Event using both the price field A($55 - qty 1) and B($10 - qty 1)
147 // 3. Now after registration, edit the participant, change the fee of price B from $10 to $50 (i.e. change qty from 1 to 5)
148 // 4. After submission check that related contribution's status is changed to 'Partially Paid'
149 // 5. Record the additional amount which $40 ($50-$10)
150 // Expected : Check the amount of new Financial Item created is $40
151 $this->createParticipantRecordsFromTwoFieldPriceSet();
152 $priceSetBlock = CRM_Price_BAO_PriceSet
::getSetDetail($this->getPriceSetID(), TRUE, FALSE)[$this->getPriceSetID()]['fields'];
155 'priceSetId' => $this->getPriceSetID(),
156 // The 1 & 5 refer to qty as they are text fields.
157 'price_' . $this->_ids
['price_field']['first_text_field'] => 5,
158 'price_' . $this->_ids
['price_field']['second_text_field'] => 1,
160 $participant = $this->callAPISuccess('Participant', 'get', []);
161 $lineItem = CRM_Price_BAO_LineItem
::getLineItems($participant['id'], 'participant');
162 $contribution = $this->callAPISuccessGetSingle('Contribution', []);
163 CRM_Price_BAO_LineItem
::changeFeeSelections($priceSetParams, $participant['id'], 'participant', $contribution['id'], $priceSetBlock, $lineItem);
165 $financialItems = $this->callAPISuccess('FinancialItem', 'get', [])['values'];
167 foreach ($financialItems as $financialItem) {
168 $sum +
= $financialItem['amount'];
170 $this->assertEquals(105, $sum);
171 $this->assertCount(3, $financialItems);
173 $contribution = $this->callAPISuccessGetSingle('Contribution', []);
174 $this->assertEquals('Partially paid', $contribution['contribution_status']);
176 $this->callAPISuccess('Payment', 'create', [
177 'contribution_id' => $contribution['id'],
178 'participant_id' => $participant['id'],
179 'total_amount' => 40.00,
181 'payment_instrument_id' => 'Check',
182 'check_number' => '#123',
185 $result = $this->callAPISuccess('EntityFinancialTrxn', 'get', ['entity_table' => 'civicrm_financial_item', 'sequential' => 1, 'return' => ['entity_table', 'amount']])['values'];
186 $this->assertEquals(40, $result[2]['amount']);
187 $this->assertCount(4, $result);
191 * Initial test of submit function.
193 * @param string $thousandSeparator
195 * @dataProvider getThousandSeparators
199 public function testSubmitWithPayment($thousandSeparator) {
200 $this->setCurrencySeparators($thousandSeparator);
201 $form = $this->getForm(['is_monetary' => 1, 'financial_type_id' => 1]);
202 $form->_mode
= 'Live';
203 $form->_quickConfig
= TRUE;
204 $paymentProcessorID = $this->processorCreate(['is_test' => 0]);
205 $form->submit($this->getSubmitParamsForCreditCardPayment($paymentProcessorID));
206 $participant = $this->callAPISuccessGetSingle('Participant', []);
207 $this->assertEquals('2018-09-04 00:00:00', $participant['participant_register_date']);
208 $this->assertEquals('Offline Registration for Event: Annual CiviCRM meet by: ', $participant['participant_source']);
209 $contribution = $this->callAPISuccessGetSingle('Contribution', []);
210 $this->assertEquals(1550.55, $contribution['total_amount']);
211 $this->assertEquals('Debit Card', $contribution['payment_instrument']);
212 $lineItem = $this->callAPISuccessGetSingle('LineItem', []);
214 'contribution_id' => $contribution['id'],
215 'entity_table' => 'civicrm_participant',
218 'unit_price' => 1550.55,
219 'line_total' => 1550.55,
220 'participant_count' => 0,
221 'price_field_id' => $this->_ids
['price_field'][0],
222 'price_field_value_id' => $this->_ids
['price_field_value'][1],
224 // Interestingly the financial_type_id set in this test is ignored but currently locking in what is happening with this test so setting to 'actual'
225 'financial_type_id' => CRM_Core_PseudoConstant
::getKey('CRM_Contribute_BAO_Contribution', 'financial_type_id', 'Event Fee'),
227 foreach ($expected as $key => $value) {
228 $this->assertEquals($value, $lineItem[$key], $key);
233 * Initial test of submit function.
235 * @param string $thousandSeparator
236 * @param array $fromEmails From Emails array to overwrite the default.
238 * @dataProvider getThousandSeparators
242 public function testSubmitWithFailedPayment($thousandSeparator, $fromEmails = []) {
243 $this->setCurrencySeparators($thousandSeparator);
244 $form = $this->getForm(['is_monetary' => 1, 'financial_type_id' => 1]);
245 $form->_mode
= 'Live';
246 $form->_quickConfig
= TRUE;
247 $paymentProcessorID = $this->processorCreate(['is_test' => 0]);
248 Civi\Payment\System
::singleton()->getById($paymentProcessorID)->setDoDirectPaymentResult(['payment_status_id' => 'failed']);
250 $form->_fromEmails
= [
251 'from_email_id' => ['abc@gmail.com' => 1],
254 $form->submit($this->getSubmitParamsForCreditCardPayment($paymentProcessorID));
256 catch (CRM_Core_Exception_PrematureExitException
$e) {
259 $this->fail('should have hit premature exit');
263 * Test offline participant mail.
265 * @param string $thousandSeparator
267 * @dataProvider getThousandSeparators
270 public function testParticipantOfflineReceipt($thousandSeparator) {
271 $this->setCurrencySeparators($thousandSeparator);
272 $mut = new CiviMailUtils($this, TRUE);
273 // Create an email associated with the logged in contact
274 $loggedInContactID = $this->createLoggedInUser();
275 $email = $this->callAPISuccess('Email', 'create', [
276 'contact_id' => $loggedInContactID,
278 'email' => 'testLoggedInReceiptEmail@civicrm.org',
279 'location_type_id' => 1,
282 //Get workflow id of event_offline receipt.
283 $workflowId = $this->callAPISuccess('OptionValue', 'get', [
285 'option_group_id' => 'msg_tpl_workflow_event',
286 'name' => 'event_offline_receipt',
289 //Modify html to contain event_type_id token.
290 $result = $this->callAPISuccess('MessageTemplate', 'get', [
292 'return' => ['id', 'msg_html'],
293 'workflow_id' => $workflowId['id'],
296 $oldMsg = $result['values'][0]['msg_html'];
297 $pos = strpos($oldMsg, 'Please print this confirmation');
298 $newMsg = substr_replace($oldMsg, '<p>Test event type - {$event.event_type_id}</p>', $pos, 0);
299 $this->callAPISuccess('MessageTemplate', 'create', [
300 'id' => $result['id'],
301 'msg_html' => $newMsg,
304 // Use the email created as the from email ensuring we are passing a numeric from to test dev/core#1069
305 $this->setCurrencySeparators($thousandSeparator);
306 $form = $this->getForm(['is_monetary' => 1, 'financial_type_id' => 1]);
307 $form->_mode
= 'Live';
308 $form->_quickConfig
= TRUE;
309 $form->_fromEmails
= [
310 'from_email_id' => [$email['id'] => 1],
312 $paymentProcessorID = $this->processorCreate(['is_test' => 0]);
313 $submitParams = $this->getSubmitParamsForCreditCardPayment($paymentProcessorID);
314 $submitParams['from_email_address'] = $email['id'];
315 $form->submit($submitParams);
316 //Check if type is correctly populated in mails.
317 //Also check the string email is present not numeric from.
319 '<p>Test event type - 1</p>',
320 'testloggedinreceiptemail@civicrm.org',
321 $this->formatMoneyInput(1550.55),
323 $this->callAPISuccess('Email', 'delete', ['id' => $email['id']]);
327 * Get prepared form object.
329 * @param array $eventParams
331 * @return CRM_Event_Form_Participant
333 * @throws \CRM_Core_Exception
335 protected function getForm($eventParams = []) {
336 if (!empty($eventParams['is_monetary'])) {
337 $event = $this->eventCreatePaid($eventParams, [['name' => 'big', 'amount' => 1550.55]]);
340 $event = $this->eventCreate($eventParams);
343 $this->ids
['contact']['event'] = (int) $this->individualCreate();
344 /** @var CRM_Event_Form_Participant $form */
345 $form = $this->getFormObject('CRM_Event_Form_Participant');
346 $form->_single
= TRUE;
347 $form->_contactID
= $form->_contactId
= $this->ids
['contact']['event'];
348 $form->setCustomDataTypes();
349 $form->_eventId
= $event['id'];
350 if (!empty($eventParams['is_monetary'])) {
352 $form->_isPaidEvent
= TRUE;
353 CRM_Event_Form_EventFees
::preProcess($form);
354 $form->buildEventFeeForm($form);
357 $form->_fromEmails
= [
358 'from_email_id' => ['abc@gmail.com' => 1],
361 $this->fromEmailAddressOptions
= $form->_fromEmails
['from_email_id'];
366 * Get a valid value for from_email_address.
370 public function getFromEmailAddress() {
371 return key($this->fromEmailAddressOptions
);
375 * Create a Price set with two price field of type Text.
377 * Financial Type: 'Event Fee' and 'Event Fee 2' respectively.
379 * @throws \CRM_Core_Exception
380 * @throws \CiviCRM_API3_Exception
382 protected function createParticipantRecordsFromTwoFieldPriceSet() {
383 // Create financial type - Event Fee 2
384 $form = $this->getForm(['is_monetary' => 1, 'financial_type_id' => 1]);
386 $textFieldsToCreate = [['amount' => 10, 'label' => 'First Text field'], ['amount' => 55, 'label' => 'Second Text field']];
387 foreach ($textFieldsToCreate as $fieldToCreate) {
389 'option_label' => ['1' => 'Price Field'],
390 'option_value' => ['1' => $fieldToCreate['amount']],
391 'option_name' => ['1' => $fieldToCreate['amount']],
392 'option_amount' => ['1' => $fieldToCreate['amount']],
393 'option_weight' => ['1' => $fieldToCreate['amount']],
394 'is_display_amounts' => 1,
395 'price_set_id' => $this->_ids
['price_set'],
397 'html_type' => 'Text',
398 'financial_type_id' => CRM_Core_PseudoConstant
::getKey('CRM_Contribute_BAO_Contribution', 'financial_type_id', 'Campaign Contribution'),
400 $fieldParams['label'] = $fieldToCreate['label'];
401 $fieldParams['name'] = CRM_Utils_String
::titleToVar($fieldToCreate['label']);
402 $fieldParams['price'] = $fieldToCreate['amount'];
403 $this->_ids
['price_field'][strtolower(CRM_Utils_String
::titleToVar($fieldToCreate['label']))] = $textPriceFieldID = $this->callAPISuccess('PriceField', 'create', $fieldParams)['id'];
404 $this->_ids
['price_field_value'][strtolower(CRM_Utils_String
::titleToVar($fieldToCreate['label']))] = (int) $this->callAPISuccess('PriceFieldValue', 'getsingle', ['price_field_id' => $textPriceFieldID])['id'];
410 'price_field_id' => $this->_ids
['price_field']['second_text_field'],
411 'price_field_value_id' => $this->_ids
['price_field_value']['second_text_field'],
412 'label' => 'Event Fee 1',
413 'field_title' => 'Event Fee 1',
414 'description' => NULL,
416 'unit_price' => 55.00,
418 'participant_count' => 0,
420 'membership_type_id' => NULL,
421 'membership_num_terms' => NULL,
422 'auto_renew' => NULL,
423 'html_type' => 'Text',
424 'financial_type_id' => CRM_Core_PseudoConstant
::getKey('CRM_Contribute_BAO_Contribution', 'financial_type_id', 'Campaign Contribution'),
425 'tax_amount' => NULL,
426 'non_deductible_amount' => '0.00',
429 'price_field_id' => $this->_ids
['price_field']['first_text_field'],
430 'price_field_value_id' => $this->_ids
['price_field_value']['first_text_field'],
431 'label' => 'Event Fee 2',
432 'field_title' => 'Event Fee 2',
433 'description' => NULL,
435 'unit_price' => 10.00,
437 'participant_count' => 0,
439 'membership_type_id' => NULL,
440 'membership_num_terms' => NULL,
441 'auto_renew' => NULL,
442 'html_type' => 'Text',
443 'financial_type_id' => CRM_Core_PseudoConstant
::getKey('CRM_Contribute_BAO_Contribution', 'financial_type_id', 'Campaign Contribution'),
444 'tax_amount' => NULL,
445 'non_deductible_amount' => '0.00',
449 $form->setAction(CRM_Core_Action
::ADD
);
450 $form->_priceSetId
= $this->_ids
['price_set'];
453 'register_date' => date('Ymd'),
454 'receive_date' => '2018-09-01',
457 'event_id' => $this->getEventID(),
458 'priceSetId' => $this->_ids
['price_set'],
459 'price_' . $this->_ids
['price_field']['first_text_field'] => [$this->_ids
['price_field_value']['first_text_field'] => 1],
460 'price_' . $this->_ids
['price_field']['second_text_field'] => [$this->_ids
['price_field_value']['second_text_field'] => 1],
461 'amount_level' => 'Too much',
463 'total_amount' => 65,
464 'payment_processor_id' => 0,
465 'record_contribution' => TRUE,
466 'financial_type_id' => 1,
467 'contribution_status_id' => CRM_Core_PseudoConstant
::getKey('CRM_Contribute_BAO_Contribution', 'contribution_status_id', 'Completed'),
468 'payment_instrument_id' => CRM_Core_PseudoConstant
::getKey('CRM_Contribute_BAO_Contribution', 'payment_instrument_id', 'Check'),
473 * Get params for submit function.
475 * @param int $paymentProcessorID
479 private function getSubmitParamsForCreditCardPayment(int $paymentProcessorID): array {
481 'register_date' => '2018-09-04',
484 'event_id' => $this->getEventID(),
485 'credit_card_number' => 4444333322221111,
487 'credit_card_exp_date' => [
491 'credit_card_type' => 'Visa',
492 'billing_first_name' => 'Junko',
493 'billing_middle_name' => '',
494 'billing_last_name' => 'Adams',
495 'billing_street_address-5' => '790L Lincoln St S',
496 'billing_city-5' => 'Maryknoll',
497 'billing_state_province_id-5' => 1031,
498 'billing_postal_code-5' => 10545,
499 'billing_country_id-5' => 1228,
500 'payment_processor_id' => $paymentProcessorID,
501 'priceSetId' => $this->getPriceSetID(),
502 $this->getPriceFieldKey() => $this->getPriceFieldValueID(),
503 'amount_level' => 'Too much',
504 'fee_amount' => $this->formatMoneyInput(1550.55),
505 'total_amount' => $this->formatMoneyInput(1550.55),
506 'from_email_address' => $this->getFromEmailAddress(),
508 'receipt_text' => '',
510 return $submitParams;
515 * @throws \CRM_Core_Exception
516 * @throws \CiviCRM_API3_Exception
518 public function testSubmitWithDeferredRecognition() {
519 Civi
::settings()->set('deferred_revenue_enabled', TRUE);
520 $futureDate = date('Y') +
1 . '-09-20';
521 $form = $this->getForm(['is_monetary' => 1, 'financial_type_id' => 1, 'start_date' => $futureDate]);
522 $form->_quickConfig
= TRUE;
525 'register_date' => date('Ymd'),
528 'event_id' => $this->getEventID(),
529 'record_contribution' => TRUE,
531 'amount_level' => 'blah',
532 'financial_type_id' => 1,
534 $contribution = $this->callAPISuccessGetSingle('Contribution', []);
535 // Api doesn't retrieve it & we don't much want to change that as we want to feature freeze BAO_Query.
536 $this->assertEquals($futureDate . ' 00:00:00', CRM_Core_DAO
::singleValueQuery("SELECT revenue_recognition_date FROM civicrm_contribution WHERE id = {$contribution['id']}"));
540 * Test submitting a partially paid event registration.
542 * In this case the participant status is selected as 'partially paid' and
543 * a contribution is created for the full amount with a payment equal to the entered amount.
545 * @dataProvider getBooleanDataProvider
547 * @param bool $isQuickConfig
549 * @throws \CRM_Core_Exception
551 public function testSubmitPartialPayment($isQuickConfig) {
552 $mut = new CiviMailUtils($this, TRUE);
553 $form = $this->getForm(['is_monetary' => 1]);
554 $this->callAPISuccess('PriceSet', 'create', ['is_quick_config' => $isQuickConfig, 'id' => $this->getPriceSetID()]);
555 $paymentInstrumentID = CRM_Core_PseudoConstant
::getKey('CRM_Contribute_BAO_Contribution', 'payment_instrument_id', 'Check');
557 'hidden_feeblock' => '1',
558 'hidden_eventFullMsg' => '',
559 'priceSetId' => $this->getPriceSetID(),
560 $this->getPriceFieldKey() => $this->getPriceFieldValueID(),
561 'check_number' => '879',
562 'record_contribution' => '1',
563 'financial_type_id' => '4',
564 'receive_date' => '2020-01-31 00:51:00',
565 'payment_instrument_id' => $paymentInstrumentID,
567 'contribution_status_id' => CRM_Core_PseudoConstant
::getKey('CRM_Contribute_BAO_Contribution', 'contribution_status_id', 'Completed'),
568 'total_amount' => '20',
569 'send_receipt' => '1',
570 'from_email_address' => $this->getFromEmailAddress(),
571 'receipt_text' => 'Contact the Development Department if you need to make any changes to your registration.',
572 'hidden_custom' => '1',
573 'hidden_custom_group_count' => ['' => 1],
575 'contact_id' => $this->getContactID(),
576 'event_id' => $this->getEventID(),
578 'register_date' => '2020-01-31 00:50:00',
579 'role_id' => [0 => CRM_Core_PseudoConstant
::getKey('CRM_Event_BAO_Participant', 'role_id', 'Attendee')],
580 'status_id' => CRM_Core_PseudoConstant
::getKey('CRM_Event_BAO_Participant', 'status_id', 'Partially paid'),
581 'source' => 'I wrote this',
582 'note' => 'I wrote a note',
583 'MAX_FILE_SIZE' => '33554432',
585 $form->submit($submitParams);
586 $this->assertPartialPaymentResult($isQuickConfig, $mut);
590 * Test submitting a partially paid event registration, recording a pending contribution.
594 * @dataProvider getBooleanDataProvider
596 * @param bool $isQuickConfig
598 * @throws \CRM_Core_Exception
599 * @throws \CiviCRM_API3_Exception
601 public function testSubmitPendingPartiallyPaidAddPayment($isQuickConfig) {
602 $mut = new CiviMailUtils($this, TRUE);
603 $form = $this->getForm(['is_monetary' => 1]);
604 $this->callAPISuccess('PriceSet', 'create', ['is_quick_config' => $isQuickConfig, 'id' => $this->getPriceSetID()]);
605 $paymentInstrumentID = CRM_Core_PseudoConstant
::getKey('CRM_Contribute_BAO_Contribution', 'payment_instrument_id', 'Check');
606 $submitParams = $this->getRecordContributionParams('Partially paid', $form);
607 $form->submit($submitParams);
608 $this->callAPISuccess('Payment', 'create', [
609 'contribution_id' => $this->callAPISuccessGetValue('Contribution', ['return' => 'id']),
610 'total_amount' => 20,
611 'check_number' => 879,
612 'payment_instrument_id' => $paymentInstrumentID,
614 $this->assertPartialPaymentResult($isQuickConfig, $mut);
618 * Test submitting a partially paid event registration, recording a pending contribution.
622 * @dataProvider getBooleanDataProvider
624 * @param bool $isQuickConfig
626 * @throws \CRM_Core_Exception
628 public function testSubmitPendingAddPayment($isQuickConfig) {
629 $mut = new CiviMailUtils($this, TRUE);
630 $form = $this->getForm(['is_monetary' => 1]);
631 $this->callAPISuccess('PriceSet', 'create', ['is_quick_config' => $isQuickConfig, 'id' => $this->getPriceSetID()]);
632 $paymentInstrumentID = CRM_Core_PseudoConstant
::getKey('CRM_Contribute_BAO_Contribution', 'payment_instrument_id', 'Check');
633 $submitParams = $this->getRecordContributionParams('Pending from pay later', 'Pending');
634 // Create the pending contribution for the full amount to be paid.
635 $submitParams['total_amount'] = 1550.55;
636 $form->submit($submitParams);
637 $this->callAPISuccess('Payment', 'create', [
638 'contribution_id' => $this->callAPISuccessGetValue('Contribution', ['return' => 'id']),
639 'total_amount' => 20,
640 'check_number' => 879,
641 'payment_instrument_id' => $paymentInstrumentID,
643 $this->assertPartialPaymentResult($isQuickConfig, $mut, FALSE);
647 * @param bool $isQuickConfig
648 * @param \CiviMailUtils $mut
649 * @param bool $isAmountPaidOnForm
650 * Was the amount paid entered on the form (if so this should be on the receipt)
652 protected function assertPartialPaymentResult($isQuickConfig, CiviMailUtils
$mut, $isAmountPaidOnForm = TRUE) {
653 $paymentInstrumentID = CRM_Core_PseudoConstant
::getKey('CRM_Contribute_BAO_Contribution', 'payment_instrument_id', 'Check');
654 $contribution = $this->callAPISuccessGetSingle('Contribution', []);
656 'contact_id' => $this->getContactID(),
657 'total_amount' => '1550.55',
658 'fee_amount' => '0.00',
659 'net_amount' => '1550.55',
660 'contribution_source' => 'I wrote this',
661 'amount_level' => '',
662 'is_template' => '0',
663 'financial_type' => 'Event Fee',
664 'payment_instrument' => 'Check',
665 'contribution_status' => 'Partially paid',
666 'check_number' => '879',
668 $this->assertAttributesEquals($expected, $contribution);
670 $participant = $this->callAPISuccessGetSingle('Participant', []);
671 $this->assertAttributesEquals([
672 'contact_id' => $this->getContactID(),
673 'event_title' => 'Annual CiviCRM meet',
674 'participant_fee_level' => [0 => 'big - 1'],
675 'participant_fee_amount' => '1550.55',
676 'participant_fee_currency' => 'USD',
677 'event_type' => 'Conference',
678 'participant_status' => 'Partially paid',
679 'participant_role' => 'Attendee',
680 'participant_source' => 'I wrote this',
681 'participant_note' => 'I wrote a note',
682 'participant_is_pay_later' => '0',
684 $lineItem = $this->callAPISuccessGetSingle('LineItem', []);
685 $this->assertAttributesEquals([
686 'entity_table' => 'civicrm_participant',
687 'entity_id' => $participant['id'],
688 'contribution_id' => $contribution['id'],
689 'price_field_id' => $this->getPriceFieldID(),
692 'unit_price' => '1550.55',
693 'line_total' => '1550.55',
694 'participant_count' => '0',
695 'price_field_value_id' => $this->getPriceFieldValueID(),
696 'financial_type_id' => '4',
697 'tax_amount' => '0.00',
700 $payment = $this->callAPISuccessGetSingle('FinancialTrxn', ['is_payment' => 1]);
701 $this->assertAttributesEquals([
702 'to_financial_account_id' => 6,
703 'from_financial_account_id' => 7,
704 'total_amount' => 20,
705 'fee_amount' => '0.00',
709 'payment_instrument_id' => $paymentInstrumentID,
710 'check_number' => '879',
713 $financialItem = $this->callAPISuccessGetSingle('FinancialItem', []);
714 $this->assertAttributesEquals([
715 'description' => 'big',
716 'contact_id' => $this->getContactID(),
719 'status_id' => CRM_Core_PseudoConstant
::getKey('CRM_Financial_BAO_FinancialItem', 'status_id', 'Unpaid'),
720 'entity_table' => 'civicrm_line_item',
721 'entity_id' => $lineItem['id'],
722 'financial_account_id' => 4,
726 'From: "FIXME" <info@EXAMPLE.ORG>',
727 'To: Anthony Anderson <anthony_anderson@civicrm.org>',
728 'Subject: Event Confirmation - Annual CiviCRM meet - Mr. Anthony Anderson II',
729 'Dear Anthony,Contact the Development Department if you need to make any changes to your registration.',
730 'Event Information and Location',
731 'Annual CiviCRM meet',
733 $isQuickConfig ?
$this->formatMoneyInput(1550.55) . ' big - 1' : 'Price Field - big',
734 $isAmountPaidOnForm ?
'Total Paid: $ 20.00' : ' ',
735 'Balance: $ 1,530.55',
736 'Financial Type: Event Fee',
743 * Get the id of the configured price set.
747 protected function getPriceSetID() {
748 return (int) $this->_ids
['price_set'];
752 * Get the price field id that has been created for the test.
756 protected function getPriceFieldID() {
757 return (int) $this->_ids
['price_field'][0];
761 * Get the array key for the configured price field.
765 protected function getPriceFieldKey(): string {
766 return 'price_' . $this->getPriceFieldID();
770 * Get the price field value id that has been created for the test.
774 protected function getPriceFieldValueID(): int {
775 return (int) $this->_ids
['price_field_value'][1];
779 * Get the parameters for recording a contribution.
781 * @param string $participantStatus
782 * @param string $contributionStatus
786 protected function getRecordContributionParams($participantStatus, $contributionStatus): array {
788 'hidden_feeblock' => '1',
789 'hidden_eventFullMsg' => '',
790 'priceSetId' => $this->getPriceSetID(),
791 $this->getPriceFieldKey() => $this->getPriceFieldValueID(),
792 'check_number' => '879',
793 'record_contribution' => '1',
794 'financial_type_id' => '4',
795 'receive_date' => '2020-01-31 00:51:00',
796 'payment_instrument_id' => CRM_Core_PseudoConstant
::getKey('CRM_Contribute_BAO_Contribution', 'payment_instrument_id', 'Check'),
798 'contribution_status_id' => CRM_Core_PseudoConstant
::getKey('CRM_Contribute_BAO_Contribution', 'contribution_status_id', $contributionStatus),
799 'total_amount' => '20',
800 'send_receipt' => '1',
801 'from_email_address' => $this->getFromEmailAddress(),
802 'receipt_text' => 'Contact the Development Department if you need to make any changes to your registration.',
803 'hidden_custom' => '1',
804 'hidden_custom_group_count' => ['' => 1],
806 'contact_id' => $this->getContactID(),
807 'event_id' => $this->getEventID(),
809 'register_date' => '2020-01-31 00:50:00',
810 'role_id' => [0 => CRM_Core_PseudoConstant
::getKey('CRM_Event_BAO_Participant', 'role_id', 'Attendee')],
811 'status_id' => CRM_Core_PseudoConstant
::getKey('CRM_Event_BAO_Participant', 'status_id', $participantStatus),
812 'source' => 'I wrote this',
813 'note' => 'I wrote a note',
814 'MAX_FILE_SIZE' => '33554432',
816 return $submitParams;
820 * Check if participant is transferred correctly.
822 * @throws \CRM_Core_Exception
823 * @throws \CiviCRM_API3_Exception
825 public function testTransferParticipantRegistration() {
826 //Register a contact to a sample event.
827 $this->createParticipantRecordsFromTwoFieldPriceSet();
828 $contribution = $this->callAPISuccessGetSingle('Contribution', []);
829 //Check line item count of the contribution id before transfer.
830 $lineItems = CRM_Price_BAO_LineItem
::getLineItemsByContributionID($contribution['id']);
831 $this->assertEquals(count($lineItems), 2);
832 $participantId = CRM_Core_DAO
::getFieldValue('CRM_Event_BAO_ParticipantPayment', $contribution['id'], 'participant_id', 'contribution_id');
833 /* @var CRM_Event_Form_SelfSvcTransfer $form */
834 $form = $this->getFormObject('CRM_Event_Form_SelfSvcTransfer');
835 $toContactId = $this->individualCreate();
836 $form->transferParticipantRegistration($toContactId, $participantId);
838 //Assert participant is transferred to $toContactId.
839 $participant = $this->callAPISuccess('Participant', 'getsingle', [
840 'return' => ["transferred_to_contact_id"],
841 'id' => $participantId,
843 $this->assertEquals($participant['transferred_to_contact_id'], $toContactId);
845 //Assert $toContactId has a new registration.
846 $toParticipant = $this->callAPISuccess('Participant', 'getsingle', [
847 'contact_id' => $toContactId,
849 $this->assertEquals($toParticipant['participant_registered_by_id'], $participantId);
851 //Check line item count of the contribution id remains the same.
852 $lineItems = CRM_Price_BAO_LineItem
::getLineItemsByContributionID($contribution['id']);
853 $this->assertEquals(count($lineItems), 2);
857 * Get the id of the created event.
861 protected function getEventID(): int {
862 return $this->ids
['Event']['event'];
866 * Get created contact ID.
870 protected function getContactID(): int {
871 return $this->ids
['contact']['event'];