diff --git a/CRM/Event/BAO/ParticipantStatusType.php b/CRM/Event/BAO/ParticipantStatusType.php index 9db56d820b59..388e12637d83 100644 --- a/CRM/Event/BAO/ParticipantStatusType.php +++ b/CRM/Event/BAO/ParticipantStatusType.php @@ -99,6 +99,29 @@ public static function setIsActive($id, $isActive) { return CRM_Core_DAO::setFieldValue('CRM_Event_BAO_ParticipantStatusType', $id, 'is_active', $isActive); } + /** + * Checks if status_id (id or string (eg. 5 or "Pending from pay later") is allowed for class + * + * @param int|string $status_id + * @param string $class + * + * @return bool + */ + public static function getIsValidStatusForClass($status_id, $class = 'Pending') { + $classParticipantStatuses = civicrm_api3('ParticipantStatusType', 'get', [ + 'class' => $class, + 'is_active' => 1, + ])['values']; + $allowedParticipantStatuses = []; + foreach ($classParticipantStatuses as $id => $detail) { + $allowedParticipantStatuses[$id] = $detail['name']; + } + if (in_array($status_id, $allowedParticipantStatuses) || array_key_exists($status_id, $allowedParticipantStatuses)) { + return TRUE; + } + return FALSE; + } + /** * @param array $params * diff --git a/api/v3/Order.php b/api/v3/Order.php index e99b38542c40..c108b8221892 100644 --- a/api/v3/Order.php +++ b/api/v3/Order.php @@ -93,7 +93,12 @@ function civicrm_api3_order_create($params) { $supportedEntity = TRUE; switch ($entity) { case 'participant': - $entityParams['status_id'] = 'Pending from incomplete transaction'; + if (isset($entityParams['participant_status_id']) + && (!CRM_Event_BAO_ParticipantStatusType::getIsValidStatusForClass($entityParams['participant_status_id'], 'Pending'))) { + throw new CiviCRM_API3_Exception('Creating a participant via the Order API with a non "pending" status is not supported'); + } + $entityParams['participant_status_id'] = $entityParams['participant_status_id'] ?? 'Pending from incomplete transaction'; + $entityParams['status_id'] = $entityParams['participant_status_id']; break; case 'membership': diff --git a/tests/phpunit/api/v3/OrderTest.php b/tests/phpunit/api/v3/OrderTest.php index bf81f4fb6888..55856dd122c0 100644 --- a/tests/phpunit/api/v3/OrderTest.php +++ b/tests/phpunit/api/v3/OrderTest.php @@ -339,6 +339,16 @@ public function testAddOrderForParticipant() { 'id' => $order['id'], ]); + // Enable the "Pending from approval" status which is not enabled by default + $pendingFromApprovalParticipantStatus = civicrm_api3('ParticipantStatusType', 'getsingle', [ + 'name' => "Pending from approval", + ]); + civicrm_api3('ParticipantStatusType', 'create', [ + 'id' => $pendingFromApprovalParticipantStatus['id'], + 'name' => "Pending from approval", + 'is_active' => 1, + ]); + $p['line_items'][] = [ 'line_item' => $lineItems, 'params' => [ @@ -347,6 +357,7 @@ public function testAddOrderForParticipant() { 'role_id' => 1, 'register_date' => '2007-07-21 00:00:00', 'source' => 'Online Event Registration: API Testing', + 'participant_status_id' => 'Pending from approval', ], ]; @@ -358,12 +369,15 @@ public function testAddOrderForParticipant() { 'net_amount' => 600, ], ]; - $paymentParticipant = [ + $orderParams = [ 'contribution_id' => $order['id'], ]; - $order = $this->callAPISuccess('order', 'get', $paymentParticipant); + $order = $this->callAPISuccess('order', 'get', $orderParams); $this->checkPaymentResult($order, $expectedResult); - $this->callAPISuccessGetCount('ParticipantPayment', $paymentParticipant, 2); + $paymentParticipant = $this->callAPISuccess('ParticipantPayment', 'get', $orderParams)['values']; + $this->assertEquals(2, count($paymentParticipant), 'Expected two participant payments'); + $participant = $this->callAPISuccessGetSingle('Participant', ['participant_id' => end($paymentParticipant)['participant_id']]); + $this->assertEquals('Pending from approval', $participant['participant_status']); $this->callAPISuccess('Contribution', 'Delete', [ 'id' => $order['id'], ]);