Skip to content

Commit

Permalink
(wip) Process price fields
Browse files Browse the repository at this point in the history
  • Loading branch information
jensschuppe committed Nov 14, 2024
1 parent ad04e69 commit fcfe502
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 31 deletions.
23 changes: 23 additions & 0 deletions CRM/Remoteevent/Registration.php
Original file line number Diff line number Diff line change
Expand Up @@ -803,6 +803,29 @@ public static function registerAdditionalParticipants(RegistrationEvent $registr
$registration->setAdditionalParticipantsData($additionalParticipantsData);
}

public static function createOrder(RegistrationEvent $registration): void {
$event = $registration->getEvent();
if (
(bool) $event['is_monetary']
&& class_exists('\Civi\Api4\Order')
) {
$order = \Civi\Api4\Order::create(FALSE)
->setContributionValues([
'contact_id' => $registration->getContactID(),
'financial_type_id' => $event['financial_type_id'],
]);
foreach ($registration->getPriceFieldValues() as $value) {
$order->addLineItem([
'entity_table' => 'civicrm_participant',
'entity_id' => $value['participant_id'],
'price_field_value_id' => $value['price_field_value_id'],
'qty' => $value['qty']
]);
}
$order->execute();
}
}

/**
* Get a (cached version) of ParticipantStatusType.get
*/
Expand Down
78 changes: 47 additions & 31 deletions CRM/Remoteevent/RegistrationProfile.php
Original file line number Diff line number Diff line change
Expand Up @@ -102,43 +102,47 @@ public function getLabel()
*/
abstract public function getFields($locale = null);

public static function getPriceFields(array $event): array {
return \Civi\Api4\Event::get(FALSE)
->addSelect('price_field.*')
->addJoin(
'PriceSetEntity AS price_set_entity',
'INNER',
['price_set_entity.entity_table', '=', '"civicrm_event"'],
['price_set_entity.entity_id', '=', 'id']
)
->addJoin(
'PriceSet AS price_set',
'INNER',
['price_set.id', '=', 'price_set_entity.price_set_id'],
['price_set.is_active', '=', 1]
)
->addJoin(
'PriceField AS price_field',
'LEFT',
['price_field.price_set_id', '=', 'price_set.id']
)
->addWhere('id', '=', $event['id'])
->execute()
->getArrayCopy();
}

/**
* @param array $event
* @param string|null $locale
*
* @return array<string,array<string,mixed>>
* @throws \CRM_Core_Exception
*/
public function getPriceFields(array $event, ?string $locale = NULL): array
public function getProfilePriceFields(array $event, ?string $locale = NULL): array
{
$fields = [];

if (!(bool) $event['is_monetary']) {
return $fields;
}

$priceFields = \Civi\Api4\Event::get(FALSE)
->addSelect('price_field.*')
->addJoin(
'PriceSetEntity AS price_set_entity',
'INNER',
['price_set_entity.entity_table', '=', '"civicrm_event"'],
['price_set_entity.entity_id', '=', 'id']
)
->addJoin(
'PriceSet AS price_set',
'INNER',
['price_set.id', '=', 'price_set_entity.price_set_id'],
['price_set.is_active', '=', 1]
)
->addJoin(
'PriceField AS price_field',
'LEFT',
['price_field.price_set_id', '=', 'price_set.id']
)
->addWhere('id', '=', $event['id'])
->execute();

$priceFields = self::getPriceFields($event);
if (count($priceFields) === 0) {
return $fields;
}
Expand All @@ -159,17 +163,29 @@ public function getPriceFields(array $event, ?string $locale = NULL): array
$field = [
// TODO: Validate types.
'type' => $priceField['price_field.html_type'],
'name' => $priceField['price_field.name'],
'name' => 'price_' . $priceField['price_field.name'],
// TODO: Localize label with given $locale.
'label' => $priceField['price_field.label'],
'weight' => $priceField['price_field.weight'],
'required' => (bool) $priceField['price_field.is_required'],
'parent' => 'price',
'options' => $priceFieldValues->column('label'),
];
if ($priceField['price_field.is_enter_qty']) {
// Append price per unit.
$field['label'] .= sprintf(
' (%s)',
CRM_Utils_Money::format(
$priceFieldValues->first()['amount'],
$event['currency']
)
);
}
else {
$field['options'] = $priceFieldValues->column('label');
}

// Append price field value amounts in option labels.
if ($priceField['price_field.is_display_amounts']) {
if (isset($field['options']) && $priceField['price_field.is_display_amounts']) {
array_walk($field['options'], function(&$label, $id, $context) {
$label .= sprintf(
' (%s)',
Expand All @@ -195,7 +211,7 @@ public function getPriceFields(array $event, ?string $locale = NULL): array
$field['suffix_display'] = 'inline';
}

// TODO: Ids the price field name unique across all price fields for
// TODO: Is the price field name unique across all price fields for
// this event?
$fields['price_' . $priceField['price_field.name']] = $field;
}
Expand All @@ -215,7 +231,7 @@ public function getAdditionalParticipantsFields(array $event, ?int $maxParticipa
$event['event_remote_registration.remote_registration_additional_participants_profile']
);
$additional_fields = $additional_participants_profile->getFields($locale);
$additional_fields += $additional_participants_profile->getPriceFields($event, $locale);
$additional_fields += $additional_participants_profile->getProfilePriceFields($event, $locale);
$fields['additional_participants'] = [
'type' => 'fieldset',
'name' => 'additional_participants',
Expand Down Expand Up @@ -374,7 +390,7 @@ function(int $carry, string $item) {

// Validate price fields.
if ((bool) $event['is_monetary']) {
foreach ($this->validatePriceFields($event, $data) as $field_name => $error) {
foreach ($this->validatePriceFields($event, $data, $l10n) as $field_name => $error) {
$validationEvent->addValidationError($field_name, $error);
}
}
Expand All @@ -393,7 +409,7 @@ function(int $carry, string $item) {
protected function validatePriceFields(array $event, array $submission, CRM_Remoteevent_Localisation $l10n): array
{
$errors = [];
foreach ($this->getPriceFields($event) as $priceField) {
foreach ($this->getProfilePriceFields($event) as $priceField) {
// TODO: Validate price field values.
}
return $errors;
Expand Down Expand Up @@ -524,7 +540,7 @@ public static function addProfileData($get_form_results)
$locale = $get_form_results->getLocale();
$fields = $profile->getFields($locale);
if ('create' === $get_form_results->getContext()) {
$fields += $profile->getPriceFields($event, $locale);
$fields += $profile->getProfilePriceFields($event, $locale);
$fields += $profile->getAdditionalParticipantsFields($event, NULL, $locale);
}
$get_form_results->addFields($fields);
Expand Down
43 changes: 43 additions & 0 deletions Civi/RemoteParticipant/Event/RegistrationEvent.php
Original file line number Diff line number Diff line change
Expand Up @@ -247,4 +247,47 @@ public function getQueryParameters()
{
return $this->submission;
}

/**
* @return array<string, mixed>
* @throws \CRM_Core_Exception
*/
public function getPriceFieldValues(): array
{
$values = [];

$event = $this->getEvent();
if (!(bool) $event['is_monetary']) {
return $values;
}

foreach (\CRM_Remoteevent_RegistrationProfile::getPriceFields($event) as $priceField) {
$value = $this->submission['price_' . $priceField['price_field.name']] ?? NULL;
if (is_numeric($value)) {
$values[] = [
'participant_id' => $this->getParticipantID(),
'price_field_name' => $priceField['price_field.name'],
'price_field_value_id' => !(bool) $priceField['price_field.is_enter_qty'] ? $value : NULL,
'qty' => (bool) $priceField['price_field.is_enter_qty'] ? $value : 1,
];
}
}

$additionalParticipantsPriceFields = \CRM_Remoteevent_RegistrationProfile::getPriceFields($event);
foreach ($this->getAdditionalParticipantsData() as $additionalParticipantNo => $additionalParticipant) {
foreach ($additionalParticipantsPriceFields as $priceField) {
$value = $this->submission['additional_' . $additionalParticipantNo . '_price_' . $priceField['price_field.name']] ?? NULL;
if (is_numeric($value)) {
$values[] = [
'participant_id' => $additionalParticipant['id'],
'price_field_name' => $priceField['price_field.name'],
'price_field_value_id' => !(bool) $priceField['price_field.is_enter_qty'] ? $value : NULL,
'qty' => (bool) $priceField['price_field.is_enter_qty'] ? $value : 1,
];
}
}
}

return $values;
}
}
3 changes: 3 additions & 0 deletions remoteevent.php
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,9 @@ function remoteevent_civicrm_config(&$config)
['CRM_Remoteevent_Registration', 'registerAdditionalParticipants'], CRM_Remoteevent_Registration::STAGE2_PARTICIPANT_CREATION);

// TODO: Process price fields.
$dispatcher->addUniqueListener(
RegistrationEvent::NAME,
['CRM_Remoteevent_Registration', 'createOrder'], CRM_Remoteevent_Registration::AFTER_PARTICIPANT_CREATION);

$dispatcher->addUniqueListener(
RegistrationEvent::NAME,
Expand Down

0 comments on commit fcfe502

Please sign in to comment.