Skip to content

Commit

Permalink
updated participant count code
Browse files Browse the repository at this point in the history
fix for participant count code
  • Loading branch information
MegaphoneJon committed Feb 16, 2024
1 parent 3341be2 commit 7ca57d9
Show file tree
Hide file tree
Showing 5 changed files with 153 additions and 4 deletions.
8 changes: 8 additions & 0 deletions src/AdminHelp.php
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,14 @@ protected function participant_fee_amount() {
$this->fee();
}

protected function participant_count() {
return '<p>' .
t('Total number of participants to be registered for this event upon submission of the form.') .
'</p><p>' .
t('Note that if a value is not given, the default Participant Count will be 1.') .
'</p>';
}

protected function fee() {
return '<p>' .
t('Once added to the webform, this field can be configured in a number of ways by changing its settings.') .
Expand Down
4 changes: 4 additions & 0 deletions src/Fields.php
Original file line number Diff line number Diff line change
Expand Up @@ -858,6 +858,10 @@ protected function wf_crm_get_fields($var = 'fields') {
'name' => t('Participant Fee'),
] + $moneyDefaults;
}
$fields['participant_count'] = [
'name' => t('Participant Count'),
'type' => 'civicrm_number',
];
}
if (isset($sets['membership'])) {
$fields['membership_membership_type_id'] = [
Expand Down
62 changes: 62 additions & 0 deletions src/Utils.php
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,68 @@ function wf_crm_get_events($reg_options, $context) {
return $ret;
}

/**
* Create a hidden Price Set that contains a Price Field Value with a `count` of one so that `qty` accurately reflects
* number of seats registered on submission
*/
function wf_crm_get_participant_price_set() {
// Get the price_set_value id
$qtyPriceFieldValueId = civicrm_api4('PriceFieldValue', 'get', [
'checkPermissions' => FALSE,
'select' => ['id'],
'where' => [['name', '=', 'quantity_count_field_value']],
])[0]['id'] ?? NULL;
// If the Price Set Value exsists, return it.
if ($qtyPriceFieldValueId) {
return $qtyPriceFieldValueId;
}
else {
// If it does not exist, create the price set, price field, and price field value (with a `count` of 1).
$activeFinancialtypeId = civicrm_api4('FinancialType', 'get', [
'checkPermissions' => FALSE,
'select' => ['id'],
'where' => [['is_active', '=', TRUE]],
'limit' => 1,
])[0]['id'];
$qtyPriceSetId = civicrm_api4('PriceSet', 'create', [
'checkPermissions' => FALSE,
'values' => [
'name' => 'quantity_count',
'title' => 'Webform participant quantity count',
'extends:name' => 'CiviEvent',
'is_active' => TRUE,
'is_reserved' => TRUE,
'is_required' => FALSE,
'is_quick_config' => TRUE,
'financial_type_id' => $activeFinancialtypeId,
],
])[0]['id'];
$qtyPriceFieldId = civicrm_api4('PriceField', 'create', [
'checkPermissions' => FALSE,
'values' => [
'price_set_id' => $qtyPriceSetId,
'name' => 'quantity_count_field',
'label' => 'Webform participant quantity count field',
'html_type' => 'Select',
'is_active' => TRUE,
],
])[0]['id'];
$qtyPriceFieldValueId = civicrm_api4('PriceFieldValue', 'create', [
'checkPermissions' => FALSE,
'values' => [
'price_field_id' => $qtyPriceFieldId,
'name' => 'quantity_count_field_value',
'label' => 'Webform participant quantity count field value',
'count' => 1,
'amount' => 1,
'is_active' => TRUE,
'financial_type_id' => $activeFinancialtypeId,
],
])[0]['id'];
return $qtyPriceFieldValueId;
}
}

/**
* @param array $event
* @param string $format
Expand Down
19 changes: 15 additions & 4 deletions src/WebformCivicrmPostProcess.php
Original file line number Diff line number Diff line change
Expand Up @@ -478,15 +478,20 @@ private function validateParticipants() {
if (is_numeric($eid)) {
$this->events[$eid]['ended'] = TRUE;
$this->events[$eid]['title'] = t('this event');
$this->events[$eid]['count'] = wf_crm_aval($this->events, "$eid:count", 0) + $count;
$this->events[$eid]['count'] = wf_crm_aval($this->events, "$eid:count", 0) + ($count * ($p['count'] ?? 1));
// Get (or create if needed) a Price Set that has a value field that correctly counts the number of participants registered on submission.
$participantPriceValueID = $this->utils->wf_crm_get_participant_price_set();
$this->line_items[] = [
'qty' => $count,
'qty' => $count * ($p['count'] ?? 1),
'participant_count' => $count * ($p['count'] ?? 1),
'entity_table' => 'civicrm_participant',
'event_id' => $eid,
'contact_ids' => $contacts,
'unit_price' => $p['fee_amount'] ?? 0,
'unit_price' => ($p['fee_amount'] ?? 0) / ($p['count'] ?? 1),
'element' => "civicrm_{$c}_participant_{$n}_participant_{$id_and_type}",
'contact_label' => $participantName,
'price_field_value_id' => $participantPriceValueID,
'line_total' => $p['fee_amount'] ?? 0,
];
}
}
Expand Down Expand Up @@ -1201,7 +1206,6 @@ private function processParticipants($c, $cid) {
if (empty($item['participant_id'])) {
$item['participant_id'] = $item['entity_id'] = $result['id'];
}
$item['participant_count'] = wf_crm_aval($item, 'participant_count', 0) + 1;
break;
}
}
Expand All @@ -1216,6 +1220,13 @@ private function processParticipants($c, $cid) {
$this->utils->wf_civicrm_api('participant', 'create', ['status_id' => "Cancelled", 'id' => $existing[$eid]]);
\Drupal::messenger()->addStatus(t('Registration cancelled for @event', ['@event' => $title]));
}
// Free events need line items for correct participant count.
$contribution_enabled = wf_crm_aval($this->data, 'contribution:1:contribution:1:enable_contribution');
if (!$contribution_enabled && isset($this->line_items)) {
foreach ($this->line_items as $item) {
$this->utils->wf_civicrm_api('lineItem', 'create', $item);
}
}
}
}
}
Expand Down
64 changes: 64 additions & 0 deletions tests/src/FunctionalJavascript/EventTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,70 @@ function testParticipantContactReference() {
$this->assertEquals($contactRef['id'], $participant["{$customKey}_id"]);
}

/**
* Verify the participant count is calculated correctly (with multiple participants)
*/
function testParticipantCount() {
$this->drupalLogin($this->adminUser);
$this->drupalGet(Url::fromRoute('entity.webform.civicrm', [
'webform' => $this->webform->id(),
]));
$this->enableCivicrmOnWebform();

$event = $this->utils->wf_civicrm_api('Event', 'create', [
'event_type_id' => "Conference",
'title' => "Participant Count Test Event",
'start_date' => date('Y-m-d'),
'financial_type_id' => $this->ft['id'],
'max_participants' => 1000,
]);
$this->assertEquals(0, $event['is_error']);
$this->assertEquals(1, $event['count']);

$this->getSession()->getPage()->selectFieldOption('number_of_contacts', 3);
$this->htmlOutput();

$this->getSession()->getPage()->clickLink('Event Registration');

// Configure Event tab.
$this->getSession()->getPage()->selectFieldOption('participant_reg_type', 'all');
$this->assertSession()->assertWaitOnAjaxRequest();
$this->htmlOutput();
$this->getSession()->getPage()->selectFieldOption('participant_1_number_of_participant', 1);
$this->assertSession()->assertWaitOnAjaxRequest();
$this->htmlOutput();
$this->getSession()->getPage()->selectFieldOption('civicrm_1_participant_1_participant_event_id[]', 'Participant Count Test Event');
$this->getSession()->getPage()->checkField('Participant Fee');
$this->getSession()->getPage()->checkField('Participant Count');

$this->saveCiviCRMSettings();

$this->drupalGet($this->webform->toUrl('canonical'));
$this->assertPageNoErrorMessages();
$edit = [
'civicrm_1_contact_1_contact_first_name' => 'Frederick',
'civicrm_1_contact_1_contact_last_name' => 'Pabst',
'civicrm_2_contact_1_contact_first_name' => 'Mark',
'civicrm_2_contact_1_contact_last_name' => 'Anthony',
'civicrm_3_contact_1_contact_first_name' => 'Emma',
'civicrm_3_contact_1_contact_last_name' => 'Goldman',
'civicrm_1_participant_1_participant_fee_amount' => '120',
'civicrm_1_participant_1_participant_count' => '3',
];
$this->postSubmission($this->webform, $edit);

$eventSeatsAvailable = civicrm_api3('Event', 'get', [
'sequential' => 1,
'return' => ["is_full"],
'title' => "Participant Count Test Event",
]);

$this->assertEquals(994, $eventSeatsAvailable['values'][0]['available_places']);

// Ensure both contacts are added to the event.
$this->verifyResults();
}

/**
* Event Participant submission.
*/
Expand Down

0 comments on commit 7ca57d9

Please sign in to comment.