Merge pull request #15670 from eileenmcnaughton/dupe_locks
[civicrm-core.git] / templates / CRM / Event / Form / Participant.tpl
1 {*
2 +--------------------------------------------------------------------+
3 | Copyright CiviCRM LLC. All rights reserved. |
4 | |
5 | This work is published under the GNU AGPLv3 license with some |
6 | permitted exceptions and without any warranty. For full license |
7 | and copyright information, see https://civicrm.org/licensing |
8 +--------------------------------------------------------------------+
9 *}
10 {* This template is used for adding/editing/deleting offline Event Registrations *}
11
12 {* Ajax callback for showing event fee snippet *}
13 {if $showFeeBlock}
14 {if $priceSet}
15 <div id='validate_pricefield' class='messages crm-error hiddenElement'></div>
16 {literal}
17 <script type="text/javascript">
18
19 var fieldOptionsFull = [];
20 {/literal}
21 {foreach from=$priceSet.fields item=fldElement key=fldId}
22 {if $fldElement.options}
23 {foreach from=$fldElement.options item=fldOptions key=opId}
24 {if $fldOptions.is_full}
25 {literal}
26 fieldOptionsFull[{/literal}{$fldId}{literal}] = [];
27 fieldOptionsFull[{/literal}{$fldId}{literal}][{/literal}{$opId}{literal}] = 1;
28 {/literal}
29 {/if}
30 {/foreach}
31 {/if}
32 {/foreach}
33 {literal}
34
35 if ( fieldOptionsFull.length > 0 ) {
36 CRM.$(function($) {
37 $("input,#priceset select,#priceset").each(function () {
38 if ( $(this).attr('price') ) {
39 switch( $(this).attr('type') ) {
40 case 'checkbox':
41 case 'radio':
42 $(this).click( function() {
43 validatePriceField(this);
44 });
45 break;
46
47 case 'select-one':
48 $(this).change( function() {
49 validatePriceField(this);
50 });
51 break;
52 case 'text':
53 $(this).bind( 'keyup', function() { validatePriceField(this) });
54 break;
55 }
56 }
57 });
58 });
59
60 function validatePriceField( obj ) {
61 var namePart = cj(obj).attr('name').split('_');
62 var fldVal = cj(obj).val();
63 if ( cj(obj).attr('type') == 'checkbox') {
64 var eleIdpart = namePart[1].split('[');
65 var eleId = eleIdpart[0];
66 }
67 else {
68 var eleId = namePart[1];
69 }
70 var showError = false;
71
72 switch( cj(obj).attr('type') ) {
73 case 'text':
74 if ( fieldOptionsFull[eleId] && fldVal ) {
75 showError = true;
76 cj(obj).parent( ).parent( ).children('.label').addClass('crm-error');
77 }
78 else {
79 cj(obj).parent( ).parent( ).children('.label').removeClass('crm-error');
80 cj('#validate_pricefield').hide( ).html('');
81 }
82 break;
83
84 case 'checkbox':
85 var checkBoxValue = eleIdpart[1].split(']');
86 if ( cj(obj).prop("checked") == true &&
87 fieldOptionsFull[eleId] &&
88 fieldOptionsFull[eleId][checkBoxValue[0]]) {
89 showError = true;
90 cj(obj).parent( ).addClass('crm-error');
91 }
92 else {
93 cj(obj).parent( ).removeClass('crm-error');
94 }
95 break;
96
97 default:
98 if ( fieldOptionsFull[eleId] &&
99 fieldOptionsFull[eleId][fldVal] ) {
100 showError = true;
101 cj(obj).parent( ).addClass('crm-error');
102 }
103 else {
104 cj(obj).parent( ).removeClass('crm-error');
105 }
106 }
107
108 if ( showError ) {
109 cj('#validate_pricefield').show().html('<i class="crm-i fa-exclamation-triangle crm-i-red"></i>{/literal} {ts escape='js'}This Option is already full for this event.{/ts}{literal}');
110 }
111 else {
112 cj('#validate_pricefield').hide( ).html('');
113 }
114 }
115 }
116
117 // change the status to default 'partially paid' for partial payments
118 var feeAmount, userModifiedAmount;
119 var partiallyPaidStatusId = {/literal}{$partiallyPaidStatusId}{literal};
120
121 cj('#total_amount')
122 .focus(
123 function() {
124 feeAmount = cj(this).val();
125 feeAmount = Number(feeAmount.replace(/[^0-9\.]+/g,""));
126 }
127 )
128 .change(
129 function() {
130 userModifiedAmount = cj(this).val();
131 userModifiedAmount = Number(userModifiedAmount.replace(/[^0-9\.]+/g,""));
132 if (userModifiedAmount < feeAmount) {
133 cj('#status_id').val(partiallyPaidStatusId).change();
134 }
135 }
136 );
137
138 cj('form[name=Participant]').on("click", '.validate',
139 function(e) {
140 if (CRM.$('#total_amount').length == 0) {
141 var $balance = CRM.$('#payment-info-balance');
142 if ($balance.length > 0 && parseFloat($balance.attr('data-balance')) == 0) {
143 return true;
144 }
145 }
146 var userSubmittedStatus = cj('#status_id').val();
147 var statusLabel = cj('#status_id option:selected').text();
148 if (userModifiedAmount < feeAmount && userSubmittedStatus != partiallyPaidStatusId) {
149 var msg = "{/literal}{ts escape="js" 1="%1"}Payment amount is less than the amount owed. Expected participant status is 'Partially paid'. Are you sure you want to set the participant status to %1? Click OK to continue, Cancel to change your entries.{/ts}{literal}";
150 var result = confirm(ts(msg, {1: statusLabel}));
151 if (result == false) {
152 return false;
153 }
154 }
155 }
156 );
157 </script>
158 {/literal}
159 {/if}
160
161 {include file="CRM/Event/Form/EventFees.tpl"}
162
163 {* Main event form template *}
164 {else}
165 {if $participantMode == 'test' }
166 {assign var=registerMode value="TEST"}
167 {elseif $participantMode == 'live'}
168 {assign var=registerMode value="LIVE"}
169 {/if}
170 <div class="crm-block crm-form-block crm-participant-form-block">
171 {if $newCredit AND $action EQ 1 AND $participantMode EQ null}
172 <div class="action-link css_right crm-link-credit-card-mode">
173 {if $contactId}
174 {capture assign=ccModeLink}{crmURL p='civicrm/contact/view/participant' q="reset=1&action=add&cid=`$contactId`&context=`$context`&mode=live"}{/capture}
175 {else}
176 {capture assign=ccModeLink}{crmURL p='civicrm/contact/view/participant' q="reset=1&action=add&context=standalone&mode=live"}{/capture}
177 {/if}
178 <a class="open-inline-noreturn action-item crm-hover-button" href="{$ccModeLink}">&raquo; {ts}submit credit card event registration{/ts}</a>
179 </div>
180 {/if}
181 <div class="view-content">
182 {if $participantMode}
183 <div class="help">
184 {ts 1=$displayName 2=$registerMode}Use this form to submit an event registration on behalf of %1. <strong>A %2 transaction will be submitted</strong> using the selected payment processor.{/ts}
185 </div>
186 {/if}
187 <div id="eventFullMsg" class="messages status no-popup" style="display:none;"></div>
188
189
190 {if $action eq 1 AND $paid}
191 <div class="help">
192 {ts}If you are accepting offline payment from this participant, check <strong>Record Payment</strong>. You will be able to fill in the payment information, and optionally send a receipt.{/ts}
193 </div>
194 {/if}
195
196 {if $action eq 8} {* If action is Delete *}
197 <div class="crm-participant-form-block-delete messages status no-popup">
198 <div class="crm-content">
199 <div class="icon inform-icon"></div> &nbsp;
200 {ts}WARNING: Deleting this registration will result in the loss of related payment records (if any).{/ts} {ts}Do you want to continue?{/ts}
201 </div>
202 {if $additionalParticipant}
203 <div class="crm-content">
204 {ts 1=$additionalParticipant} There are %1 more Participant(s) registered by this participant.{/ts}
205 </div>
206 {/if}
207 </div>
208 {if $additionalParticipant}
209 {$form.delete_participant.html}
210 {/if}
211 {else} {* If action is other than Delete *}
212 <div class="crm-submit-buttons">{include file="CRM/common/formButtons.tpl" location="top"}</div>
213 <table class="form-layout-compressed">
214 <tr class="crm-participant-form-contact-id">
215 <td class="label">{$form.contact_id.label}</td>
216 <td>{$form.contact_id.html}</td>
217 </tr>
218 {if $action EQ 2}
219 {if $additionalParticipants} {* Display others registered by this participant *}
220 <tr class="crm-participant-form-block-additionalParticipants">
221 <td class="label"><label>{ts}Also Registered by this Participant{/ts}</label></td>
222 <td>
223 {foreach from=$additionalParticipants key=apName item=apURL}
224 <a href="{$apURL}" title="{ts}view additional participant{/ts}">{$apName}</a><br />
225 {/foreach}
226 </td>
227 </tr>
228 {/if}
229 {if $registered_by_contact_id}
230 <tr class="crm-participant-form-block-registered-by">
231 <td class="label"><label>{ts}Registered By{/ts}</label></td>
232 <td class="view-value">
233 <a href="{crmURL p='civicrm/contact/view/participant' q="reset=1&id=$participant_registered_by_id&cid=$registered_by_contact_id&action=view"}"
234 title="{ts}view primary participant{/ts}">{$registered_by_display_name}</a>
235 </td>
236 </tr>
237 {/if}
238 {/if}
239 <tr class="crm-participant-form-block-event_id">
240 <td class="label">{$form.event_id.label}</td>
241 <td class="view-value">
242 {$form.event_id.html}
243 {if $is_test}
244 {ts}(test){/ts}
245 {/if}
246 </td>
247 </tr>
248
249 {* CRM-7362 --add campaign *}
250 {include file="CRM/Campaign/Form/addCampaignToComponent.tpl" campaignTrClass="crm-participant-form-block-campaign_id"}
251
252 <tr class="crm-participant-form-block-role_id">
253 <td class="label">{$form.role_id.label}</td>
254 <td>{$form.role_id.html}</td>
255 </tr>
256 <tr class="crm-participant-form-block-register_date">
257 <td class="label">{$form.register_date.label}</td>
258 <td>{$form.register_date.html}</td>
259 </tr>
260 <tr class="crm-participant-form-block-status_id">
261 <td class="label">{$form.status_id.label}</td>
262 <td>{$form.status_id.html}{if $event_is_test} {ts}(test){/ts}{/if}
263 <div id="notify">{$form.is_notify.html}{$form.is_notify.label}</div>
264 </td>
265 </tr>
266 <tr class="crm-participant-form-block-source">
267 <td class="label">{$form.source.label}</td><td>{$form.source.html|crmAddClass:huge}<br />
268 <span class="description">{ts}Source for this registration (if applicable).{/ts}</span></td>
269 </tr>
270 {if $participantMode}
271 <tr class="crm-participant-form-block-payment_processor_id">
272 <td class="label nowrap">{$form.payment_processor_id.label}</td>
273 <td>{$form.payment_processor_id.html}</td>
274 </tr>
275 {/if}
276 </table>
277 {if $participantId and $hasPayment}
278 <table class='form-layout'>
279 <tr>
280 <td class='label'>{ts}Fees{/ts}</td>
281 {* this is where the payment info is shown using CRM/Contribute/Page/PaymentInfo.tpl tpl*}
282 <td id='payment-info'></td>
283 </tr>
284 </table>
285 {/if}
286 {* Fee block (EventFees.tpl) is injected here when an event is selected. *}
287 <div class="crm-event-form-fee-block"></div>
288 <fieldset>
289 <table class="form-layout">
290 <tr class="crm-participant-form-block-note">
291 <td class="label">{$form.note.label}</td><td>{$form.note.html}</td>
292 </tr>
293 </table>
294 </fieldset>
295
296 <div class="crm-participant-form-block-customData">
297 <div id="customData" class="crm-customData-block"></div> {* Participant Custom data *}
298 <div id="customData{$eventNameCustomDataTypeID}" class="crm-customData-block"></div> {* Event Custom Data *}
299 <div id="customData{$roleCustomDataTypeID}" class="crm-customData-block"></div> {* Role Custom Data *}
300 <div id="customData{$eventTypeCustomDataTypeID}" class="crm-customData-block"></div> {* Role Custom Data *}
301 </div>
302 {/if}
303
304 {if $accessContribution and $action eq 2 and $rows.0.contribution_id}
305 {include file="CRM/Contribute/Form/Selector.tpl" context="Search"}
306 {/if}
307
308 <div class="crm-submit-buttons">{include file="CRM/common/formButtons.tpl" location="bottom"}</div>
309 </div>
310 </div>
311 {* JS block for ADD or UPDATE actions only *}
312 {if $action eq 1 or $action eq 2}
313 {if $participantId and $hasPayment}
314 {include file="CRM/Contribute/Page/PaymentInfo.tpl" show='payments'}
315 {/if}
316
317 {*include custom data js file*}
318 {include file="CRM/common/customData.tpl"}
319
320 <script type="text/javascript">
321 {literal}
322 CRM.$(function($) {
323
324 var $form = $('form.{/literal}{$form.formClass}{literal}');
325
326 // Handle event selection
327 $('#event_id', $form).change(function() {
328 var eventId = $(this).val();
329 if (!eventId) {
330 return;
331 }
332 var info = $(this).select2('data').extra;
333
334 // Set role from default
335 $('select[name^=role_id]', $form).select2('val', [info.default_role_id], true);
336
337 // Set campaign default
338 $('#campaign_id', $form).select2('val', info.campaign_id);
339
340 // Event and event-type custom data
341 CRM.buildCustomData('Participant', eventId, {/literal}{$eventNameCustomDataTypeID}{literal}, null, null, null, true);
342 CRM.buildCustomData('Participant', info.event_type_id, {/literal}{$eventTypeCustomDataTypeID}{literal}, null, null, null, true);
343
344 buildFeeBlock();
345 });
346
347 // Handle participant role selection
348 $('select[name^=role_id]', $form).change(buildRoleCustomData);
349 if ($('select[name^=role_id]', $form).val()) {
350 buildRoleCustomData();
351 }
352
353 buildFeeBlock();
354
355 //build discount block
356 if ($('#discount_id', $form).val()) {
357 buildFeeBlock($('#discount_id', $form).val());
358 }
359 $($form).on('change', '#discount_id', function() {
360 buildFeeBlock($(this).val());
361 });
362
363 function buildRoleCustomData() {
364 var roleId = $('select[name^=role_id]', $form).val() || [];
365 CRM.buildCustomData('Participant', roleId.join(), {/literal}{$roleCustomDataTypeID}{literal});
366 }
367
368 //build fee block
369 function buildFeeBlock(discountId) {
370 var dataUrl = {/literal}"{crmURL p=$urlPath h=0 q="snippet=4&qfKey=$qfKey"}";
371
372 {if $urlPathVar}
373 dataUrl += '&' + '{$urlPathVar}';
374 {/if}
375 {if $isBackOffice}
376 dataUrl += '&' + 'is_backoffice=1';
377 {/if}
378
379 {literal}
380 var eventId = $('[name=event_id], #event_id', $form).val();
381
382 if (eventId) {
383 dataUrl += '&eventId=' + eventId;
384 }
385 else {
386 $('#eventFullMsg', $form).hide( );
387 $('.crm-event-form-fee-block', $form).html('');
388 return;
389 }
390
391 var participantId = {/literal}{$participantId|@json_encode}{literal};
392
393 if (participantId) {
394 dataUrl += '&participantId=' + participantId;
395 }
396
397 if (discountId) {
398 dataUrl += '&discountId=' + discountId;
399 }
400
401 $.ajax({
402 url: dataUrl,
403 success: function ( html ) {
404 $(".crm-event-form-fee-block", $form).html( html ).trigger('crmLoad');
405 //show event real full as well as waiting list message.
406 if ( $("#hidden_eventFullMsg", $form).val( ) ) {
407 $( "#eventFullMsg", $form).show( ).html( $("#hidden_eventFullMsg", $form).val( ) );
408 }
409 else {
410 $( "#eventFullMsg", $form ).hide( );
411 }
412 }
413 });
414 }
415
416 {/literal}
417 CRM.buildCustomData( '{$customDataType}', null, null );
418 {if $eventID}
419 CRM.buildCustomData( '{$customDataType}', {$eventID}, {$eventNameCustomDataTypeID} );
420 {/if}
421 {if $eventTypeID}
422 CRM.buildCustomData( '{$customDataType}', {$eventTypeID}, {$eventTypeCustomDataTypeID} );
423 {/if}
424 {literal}
425
426 });
427 </script>
428 {/literal}
429
430 {/if}
431
432
433 <script type="text/javascript">
434 {literal}
435
436 sendNotification();
437 function sendNotification() {
438 var notificationStatusIds = {/literal}"{$notificationStatusIds}"{literal};
439 notificationStatusIds = notificationStatusIds.split(',');
440 if (cj.inArray(cj('select#status_id option:selected').val(), notificationStatusIds) > -1) {
441 cj("#notify").show();
442 cj("#is_notify").prop('checked', true);
443 }
444 else {
445 cj("#notify").hide();
446 cj("#is_notify").prop('checked', false);
447 }
448 }
449
450 {/literal}
451 </script>
452
453 {/if} {* end of main event block*}