Merge pull request #9789 from fliespl/patch-2
[civicrm-core.git] / templates / CRM / Batch / Form / Entry.tpl
CommitLineData
6a488035
TO
1{*
2 +--------------------------------------------------------------------+
2c4c49ca 3 | CiviCRM version 4.7 |
6a488035 4 +--------------------------------------------------------------------+
2a73d3b0 5 | Copyright CiviCRM LLC (c) 2004-2017 |
6a488035
TO
6 +--------------------------------------------------------------------+
7 | This file is a part of CiviCRM. |
8 | |
9 | CiviCRM is free software; you can copy, modify, and distribute it |
10 | under the terms of the GNU Affero General Public License |
11 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
12 | |
13 | CiviCRM is distributed in the hope that it will be useful, but |
14 | WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
16 | See the GNU Affero General Public License for more details. |
17 | |
18 | You should have received a copy of the GNU Affero General Public |
19 | License and the CiviCRM Licensing Exception along |
20 | with this program; if not, contact CiviCRM LLC |
21 | at info[AT]civicrm[DOT]org. If you have questions about the |
22 | GNU Affero General Public License or the licensing of CiviCRM, |
23 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
24 +--------------------------------------------------------------------+
25*}
26<div class="batch-entry form-item">
f6eedce7 27 <div class="help">
edb21379
DG
28 {ts}Click Validate & Process below when you've entered all items for the batch. You can also Save & Continue Later at any time.{/ts}
29 {if call_user_func(array('CRM_Core_Permission','check'), 'administer CiviCRM')}
30 {capture assign=batchEntryProfileURL}{crmURL p="civicrm/admin/uf/group" q="reset=1&selectedChild=reserved-profiles"}{/capture}
0e9f6ad1
DG
31 {ts 1=$batchEntryProfileURL}Add, remove or change the order of columns by editing the corresponding <a href="%1" target="_blank">Bulk Entry profile</a>.{/ts}
32 {if $batchType EQ 1}
33 {ts}Custom fields and a Personal Campaign Page field can be added if needed.{/ts}
34 {/if}
edb21379 35 {/if}
6a488035 36 </div>
261371e1 37 {if $batchAmountMismatch}
38 <div class="status message status-warning">
bc8360e1 39 <i class="crm-i fa-exclamation-triangle"></i> {ts}Total for amounts entered below does not match the expected batch total.{/ts}
261371e1 40 </div>
41 <div class="crm-button crm-button_qf_Entry_upload_force-save">
42 {$form._qf_Entry_upload_force.html}
43 </div>
44 <div class="clear"></div>
45 {/if}
46 <table class="form-layout-compressed batch-totals">
47 <tr>
48 <td class="label">{ts}Total amount expected{/ts}</td>
49 <td class="right"><span class="batch-expected-total">{$batchTotal|crmMoney}</span></td>
50 </tr>
51 <tr>
52 <td class="label">{ts}Total amount entered{/ts}</td>
53 <td class="right">{$config->defaultCurrencySymbol} <span class="batch-actual-total"></span></td>
54 </tr>
55 </table>
56
57 <div class="crm-copy-fields crm-grid-table" id="crm-batch-entry-table">
58 <div class="crm-grid-header">
59 <div class="crm-grid-cell">&nbsp;</div>
60 <div class="crm-grid-cell">{ts}Contact{/ts}</div>
9fa00ed1 61 {if $batchType eq 2}
6a488035 62 <div class="crm-grid-cell">&nbsp;</div>
261371e1 63 {/if}
9fa00ed1 64 {if $batchType eq 3}
b8e805eb 65 <div class="crm-grid-cell">{ts}Open Pledges (Due Date - Amount){/ts}</div>
04e6444d 66 {/if}
261371e1 67 {foreach from=$fields item=field key=fieldName}
68 <div class="crm-grid-cell">
47087bdc 69 {if $field.name|substr:0:11 ne 'soft_credit' and $field.name ne 'trxn_id'}
261371e1 70 <img src="{$config->resourceBase}i/copy.png"
71 alt="{ts 1=$field.title}Click to copy %1 from row one to all rows.{/ts}"
72 fname="{$field.name}" class="action-icon"
694ca46e 73 title="{ts}Click here to copy the value in row one to ALL rows.{/ts}"/>
74 {/if}{$field.title}
261371e1 75 </div>
76 {/foreach}
77 </div>
cdeb4bdf 78
6a488035 79 {section name='i' start=1 loop=$rowCount}
261371e1 80 {assign var='rowNumber' value=$smarty.section.i.index}
81 <div class="{cycle values="odd-row,even-row"} selector-rows crm-grid-row" entity_id="{$rowNumber}">
6a488035
TO
82 <div class="compressed crm-grid-cell"><span class="batch-edit"></span></div>
83 {* contact select/create option*}
84 <div class="compressed crm-grid-cell">
ccec9d6b 85 {$form.primary_contact_id.$rowNumber.html|crmAddClass:big}
6a488035
TO
86 </div>
87
9fa00ed1 88 {if $batchType eq 2}
6a488035
TO
89 {$form.member_option.$rowNumber.html}
90 {/if}
9fa00ed1 91 {if $batchType eq 3}
04e6444d 92 {$form.open_pledges.$rowNumber.html}
93 {/if}
6a488035 94 {foreach from=$fields item=field key=fieldName}
261371e1 95 {assign var=n value=$field.name}
217c192b 96 {if in_array( $n, array( 'thankyou_date', 'cancel_date', 'receipt_date', 'receive_date', 'join_date', 'membership_start_date', 'membership_end_date' ) ) }
261371e1 97 <div class="compressed crm-grid-cell">
98 <span class="crm-batch-{$n}-{$rowNumber}">
99 {include file="CRM/common/jcalendar.tpl" elementName=$n elementIndex=$rowNumber batchUpdate=1}
100 </span>
101 </div>
102 {elseif $n eq 'soft_credit'}
103 <div class="compressed crm-grid-cell">
ccec9d6b 104 {$form.soft_credit_contact_id.$rowNumber.html|crmAddClass:big}
3e77035d 105 {$form.soft_credit_amount.$rowNumber.label}&nbsp;{$form.soft_credit_amount.$rowNumber.html|crmAddClass:eight}
261371e1 106 </div>
03ad81ae 107 {elseif $n eq 'soft_credit_type'}
bd48fd3f 108 <div class="compressed crm-grid-cell">{$form.soft_credit_type.$rowNumber.html}</div>
a4a361c9 109 {elseif $n eq 'contribution_soft_credit_pcp_id'}
b7714c80
AH
110 <div class="compressed crm-grid-cell">
111 <div>{$form.pcp_made_through_id.$rowNumber.html}{$form.pcp_made_through.$rowNumber.html}</div>
112 <div>{$form.pcp_display_in_roll.$rowNumber.label}&nbsp;{$form.pcp_display_in_roll.$rowNumber.html}</div>
113 <div class="pcp_roll_display">{$form.pcp_roll_nickname.$rowNumber.label}&nbsp;{$form.pcp_roll_nickname.$rowNumber.html}</div>
114 <div class="pcp_roll_display">{$form.pcp_personal_note.$rowNumber.label}&nbsp;{$form.pcp_personal_note.$rowNumber.html}</div>
115 </div>
261371e1 116 {elseif in_array( $fields.$n.html_type, array('Radio', 'CheckBox'))}
6a488035 117 <div class="compressed crm-grid-cell">&nbsp;{$form.field.$rowNumber.$n.html}</div>
04e6444d 118 {elseif $n eq 'total_amount'}
5542b7c2 119 <div class="compressed crm-grid-cell">
120 {$form.field.$rowNumber.$n.html}
121 {if $batchType eq 3 }
122 {ts}<span id={$rowNumber} class="pledge-adjust-option"><a href='#'>adjust payment amount</a></span>{/ts}
123 <span id="adjust-select-{$rowNumber}" class="adjust-selectbox">{$form.option_type.$rowNumber.html}</span>
124 {/if}
125 </div>
261371e1 126 {else}
6a488035 127 <div class="compressed crm-grid-cell">{$form.field.$rowNumber.$n.html}</div>
261371e1 128 {/if}
6a488035 129 {/foreach}
261371e1 130 </div>
6a488035 131 {/section}
261371e1 132 </div>
133 <div class="crm-submit-buttons">{if $fields}{$form._qf_Batch_refresh.html}{/if} &nbsp; {$form.buttons.html}</div>
6a488035
TO
134</div>
135{literal}
136<script type="text/javascript">
3cc60a06 137CRM.$(function($) {
b50fdacc 138 var $form = $('form.{/literal}{$form.formClass}{literal}');
ae8f569f 139 $('.selector-rows').change(function () {
261371e1 140 var options = {
141 'url': {/literal}"{crmURL p='civicrm/ajax/batch' h=0}"{literal}
8777ffd1 142 };
b50fdacc 143 $($form).ajaxSubmit(options);
d5cf4608 144 });
8777ffd1 145
714bbd34 146 $('input[id*="primary_contact_"]').change(function() {
9fa00ed1 147 var temp = this.id.split('_');
148 var ROWID = temp[3];
714bbd34 149 if ($(this).val()) {
9fa00ed1 150 updateContactInfo(ROWID,'primary_');
151 }
152 });
6a488035 153
714bbd34
CW
154 $('select[id^="option_type_"]').each(function () {
155 if ($(this).val() == 1) {
156 $(this).attr('disabled', true);
157 $(this).hide();
04e6444d 158 }
159 });
160
ae8f569f 161 $('#crm-container').on('keyup change', '*.selector-rows', function () {
261371e1 162 // validate rows
ae8f569f 163 checkColumns($(this));
261371e1 164 });
6a488035 165
261371e1 166 // validate rows
167 validateRow();
6a488035 168
261371e1 169 //calculate the actual total for the batch
170 calculateActualTotal();
6a488035 171
ae8f569f 172 $('input[id*="_total_amount"]').bind('keyup change', function () {
261371e1 173 calculateActualTotal();
174 });
6a488035 175
261371e1 176 {/literal}{if $batchType eq 1 }{literal}
177 // hide all dates if send receipt is checked
178 hideSendReceipt();
6a488035 179
261371e1 180 // hide the receipt date if send receipt is checked
ae8f569f
CW
181 $('input[id*="][send_receipt]"]').change(function () {
182 showHideReceipt($(this));
261371e1 183 });
6a488035 184
9fa00ed1 185 {/literal}{elseif $batchType eq 2}{literal}
ae8f569f
CW
186 $('select[id^="member_option_"]').each(function () {
187 if ($(this).val() == 1) {
188 $(this).prop('disabled', true);
261371e1 189 }
190 });
6a488035 191
261371e1 192 // set payment info accord to membership type
ae8f569f
CW
193 $('select[id*="_membership_type_0"]').change(function () {
194 setPaymentBlock($(this), null);
261371e1 195 });
6a488035 196
ae8f569f
CW
197 $('select[id*="_membership_type_1"]').change(function () {
198 setPaymentBlock($(this), $(this).val());
261371e1 199 });
6a488035 200
261371e1 201 {/literal}{/if}{literal}
6a488035 202
261371e1 203 // line breaks between radio buttons and checkboxes
ae8f569f
CW
204 $('input.form-radio').next().after('<br />');
205 $('input.form-checkbox').next().after('<br />');
6a488035 206
261371e1 207 //set the focus on first element
ae8f569f 208 $('#primary_contact_1').focus();
6a488035 209
261371e1 210});
6a488035 211
261371e1 212function setPaymentBlock(form, memType) {
213 var rowID = form.closest('div.crm-grid-row').attr('entity_id');
214 var dataUrl = {/literal}"{crmURL p='civicrm/ajax/memType' h=0}"{literal};
6a488035 215
261371e1 216 if (!memType) {
217 memType = cj('select[id="field_' + rowID + '_membership_type_1"]').val();
6a488035
TO
218 }
219
261371e1 220 cj.post(dataUrl, {mtype: memType}, function (data) {
221 cj('#field_' + rowID + '_financial_type').val(data.financial_type_id);
222 cj('#field_' + rowID + '_total_amount').val(data.total_amount).change();
223 }, 'json');
224}
225
226function hideSendReceipt() {
227 cj('input[id*="][send_receipt]"]').each(function () {
228 showHideReceipt(cj(this));
229 });
230}
6a488035 231
261371e1 232function showHideReceipt(elem) {
233 var rowID = elem.closest('div.crm-grid-row').attr('entity_id');
234 if (elem.prop('checked')) {
235 cj('.crm-batch-receipt_date-' + rowID).hide();
236 }
237 else {
238 cj('.crm-batch-receipt_date-' + rowID).show();
239 }
240}
241
242function validateRow() {
243 cj('.selector-rows').each(function () {
244 checkColumns(cj(this));
245 });
246}
247
248function checkColumns(parentRow) {
249 // show valid row icon if all required data is field
250 var validRow = 0;
251 var inValidRow = 0;
252 var errorExists = false;
253 var rowID = parentRow.closest('div.crm-grid-row').attr('entity_id');
254
255 parentRow.find('div .required').each(function () {
256 //special case to handle contact autocomplete select
257 var fieldId = cj(this).attr('id');
258 if (fieldId.substring(0, 16) == 'primary_contact_') {
259 // if display value is set then make sure we also check if contact id is set
260 if (!cj(this).val()) {
261 inValidRow++;
262 }
263 else {
eac283fc 264 var contactIdElement = cj('input[name="primary_contact_select_id[' + rowID + ']"]');
265 if (cj(this).val() && !contactIdElement.val()) {
261371e1 266 inValidRow++;
267 errorExists = true;
268 }
eac283fc 269 else if (cj(this).val() && contactIdElement.val()) {
270 // this is hack to remove error span because we are skipping this for autocomplete fields
271 cj(this).next('span.crm-error').remove();
272 }
261371e1 273 }
274 }
275 else {
276 if (!cj(this).val()) {
277 inValidRow++;
278 }
279 else {
eac283fc 280 if (cj(this).hasClass('error') && (cj(this).hasClass('valid') || cj(this).hasClass('required'))) {
261371e1 281 errorExists = true;
282 }
283 else {
284 validRow++;
285 }
286 }
287 }
288 });
289
290 // this means user has entered some data
291 if (errorExists) {
292 parentRow.find("div:first span").prop('class', 'batch-invalid');
293 }
294 else {
295 if (inValidRow == 0 && validRow > 0) {
296 parentRow.find("div:first span").prop('class', 'batch-valid');
297 }
298 else {
299 parentRow.find("div:first span").prop('class', 'batch-edit');
300 }
301 }
302}
303
304function calculateActualTotal() {
305 var total = 0;
306 cj('input[id*="_total_amount"]').each(function () {
307 if (cj(this).val()) {
308 total += parseFloat(cj(this).val());
309 }
310 });
311
312 cj('.batch-actual-total').html(formatMoney(total));
313}
314
315//money formatting/localization
316function formatMoney(amount) {
317 var c = 2;
318 var t = '{/literal}{$config->monetaryThousandSeparator}{literal}';
319 var d = '{/literal}{$config->monetaryDecimalPoint}{literal}';
320
321 var n = amount,
322 c = isNaN(c = Math.abs(c)) ? 2 : c,
323 d = d == undefined ? "," : d,
324 t = t == undefined ? "." : t, s = n < 0 ? "-" : "",
325 i = parseInt(n = Math.abs(+n || 0).toFixed(c)) + "",
326 j = (j = i.length) > 3 ? j % 3 : 0;
327
328 return s + (j ? i.substr(0, j) + t : "") + i.substr(j).replace(/(\d{3})(?=\d)/g, "$1" + t) + (c ? d + Math.abs(n - i).toFixed(c).slice(2) : "");
329}
330
331function updateContactInfo(blockNo, prefix) {
9fa00ed1 332 var contactHiddenElement = 'input[id="' + prefix + 'contact_id_' + blockNo + '"]';
261371e1 333 var contactId = cj(contactHiddenElement).val();
334
335 var returnProperties = '';
ae8f569f 336 var profileFields = [];
261371e1 337 {/literal}
338 {if $contactFields}
339 {foreach from=$contactFields item=val key=fldName}
340 var fldName = "{$fldName}";
341 {literal}
342 if (returnProperties) {
343 returnProperties = returnProperties + ',';
344 }
345 var fld = fldName.split('-');
346 returnProperties = returnProperties + fld[0];
347 profileFields[fld[0]] = fldName;
348 {/literal}
349 {/foreach}
350 {/if}
351 {literal}
352
353 CRM.api('Contact', 'get', {
354 'sequential': '1',
6a488035
TO
355 'contact_id': contactId,
356 'return': returnProperties },
261371e1 357 { success: function (data) {
358 cj.each(data.values[0], function (key, value) {
359 // set the values
360 var actualFldName = profileFields[key];
361 if (key == 'country' || key == 'state_province') {
362 idFldName = key + '_id';
363 value = data.values[0][idFldName];
364 }
365 setFieldValue(actualFldName, value, blockNo)
366 });
6a488035 367
261371e1 368 // for membership batch entry based on contact we need to enable / disable
369 // add membership select
370 {/literal}{if $batchType eq 2}{literal}
371 CRM.api('Membership', 'get', {
372 'sequential': '1',
373 'contact_id': contactId,
374 },
375 { success: function (data) {
376 if (data.count > 0) {
377 //get the information on membership type
378 var membershipTypeId = data.values[0].membership_type_id;
379 var membershipJoinDate = data.values[0].join_date;
380 CRM.api('MembershipType', 'get', {
381 'sequential': '1',
382 'id': membershipTypeId
383 },
384 { success: function (data) {
385 var memTypeContactId = data.values[0].member_of_contact_id;
6f9cd76f 386 cj('select[id="member_option_' + blockNo + '"]').prop('disabled', false).val(2);
261371e1 387 cj('select[id="field_' + blockNo + '_membership_type_0"]').val(memTypeContactId).change();
388 cj('select[id="field_' + blockNo + '_membership_type_1"]').val(membershipTypeId).change();
389 setDateFieldValue('join_date', membershipJoinDate, blockNo)
390 }
6a488035 391 });
6a488035 392 }
261371e1 393 }
6a488035 394 });
9fa00ed1 395 {/literal}{elseif $batchType eq 3}{literal}
396 cj('#open_pledges_'+blockNo).empty();
397 cj('#open_pledges_'+blockNo).append(cj('<option>', {
398 value: '',
399 text: '-select-'
400 }));
401 CRM.api('Pledge', 'get', {
402 'sequential': 1,
403 'contact_id': contactId || 0
404 },
405 {success: function(data) {
406 cj.each(data['values'], function(key, value) {
407 if (value['pledge_status'] != 'Completed') {
5056dc8e 408 var date = cj.datepicker.parseDate('yy-mm-dd', value['pledge_next_pay_date']);
409 var dateformat = "{/literal}{$config->dateInputFormat}{literal}";
9fa00ed1 410 cj('#open_pledges_'+ blockNo).append(cj('<option>', {
411 value: value['pledge_id'],
5056dc8e 412 text: cj.datepicker.formatDate(dateformat, date) + ", " + value['pledge_next_pay_amount'] + ' ' + value['pledge_currency']
9fa00ed1 413 }));
414 }
415 });
416 }
417 });
261371e1 418 {/literal}{/if}{literal}
419 }
6a488035 420 });
261371e1 421}
6a488035
TO
422
423/**
424 * This function is use to setdefault elements via ajax
425 *
426 * @param fname string field name
427 * @return void
428 */
261371e1 429function setFieldValue(fname, fieldValue, blockNo) {
430 var elementId = cj('[name="field[' + blockNo + '][' + fname + ']"]');
6a488035 431
261371e1 432 if (elementId.length == 0) {
433 elementId = cj('input[type=checkbox][name^="field[' + blockNo + '][' + fname + ']"][type!=hidden]');
434 }
6a488035 435
261371e1 436 // if element not found than return
437 if (elementId.length == 0) {
438 return;
439 }
6a488035 440
261371e1 441 //check if it is date element
442 var isDateElement = elementId.attr('format');
6a488035 443
261371e1 444 //get the element type
445 var elementType = elementId.attr('type');
6a488035 446
261371e1 447 // set the value for all the elements, elements needs to be handled are
448 // select, checkbox, radio, date fields, text, textarea, multi-select
449 // wysiwyg editor, advanced multi-select ( to do )
450 if (elementType == 'radio') {
451 if (fieldValue) {
452 elementId.filter("[value=" + fieldValue + "]").prop("checked", true);
453 }
454 else {
455 elementId.removeProp('checked');
456 }
457 }
458 else {
459 if (elementType == 'checkbox') {
6a488035
TO
460 // handle checkbox
461 elementId.removeProp('checked');
261371e1 462 if (fieldValue) {
463 cj.each(fieldValue, function (key, value) {
464 cj('input[name="field[' + blockNo + '][' + fname + '][' + value + ']"]').prop('checked', true);
6a488035
TO
465 });
466 }
261371e1 467 }
468 else {
13d9bc82
CW
469 if (elementId.is('textarea')) {
470 CRM.wysiwyg.setVal(elementId, fieldValue);
261371e1 471 }
472 else {
473 elementId.val(fieldValue);
6a488035 474 }
6a488035 475 }
261371e1 476 }
6a488035 477
261371e1 478 // since we use different display field for date we also need to set it.
479 // also check for date time field and set the value correctly
480 if (isDateElement && fieldValue) {
481 setDateFieldValue(fname, fieldValue, blockNo)
482 }
6a488035
TO
483}
484
261371e1 485function setDateFieldValue(fname, fieldValue, blockNo) {
486 var dateValues = fieldValue.split(' ');
6a488035 487
261371e1 488 var actualDateElement = cj('#field_' + blockNo + '_' + fname);
489 var date_format = actualDateElement.attr('format');
490 var altDateFormat = 'yy-mm-dd';
6a488035 491
261371e1 492 var actualDateValue = cj.datepicker.parseDate(altDateFormat, dateValues[0]);
6a488035 493
261371e1 494 // format date according to display field
495 var hiddenDateValue = cj.datepicker.formatDate('mm/dd/yy', actualDateValue);
6a488035 496
261371e1 497 actualDateElement.val(hiddenDateValue);
6a488035 498
261371e1 499 var displayDateValue = actualDateElement.val();
500 if (date_format != 'mm/dd/yy') {
501 displayDateValue = cj.datepicker.formatDate(date_format, actualDateValue);
502 }
b09ba3a4 503 cj('[id^=field_' + blockNo + '_' + fname + '_display]').val(displayDateValue);
6a488035 504
261371e1 505 // need to fix time formatting
506 if (dateValues[1]) {
507 cj('#field_' + blockNo + '_' + fname + '_time').val(dateValues[1].substr(0, 5));
508 }
6a488035 509}
9fa00ed1 510
511if (CRM.batch.type_id == 3){
512 cj('select[id*="open_pledges_"]').change(function () {
513 setPledgeAmount(cj(this), cj(this).val());
514 });
515 cj('.pledge-adjust-option').click(function(){
516 var blockNo = cj(this).attr('id');
517 cj('select[id="option_type_' + blockNo + '"]').show();
518 cj('select[id="option_type_' + blockNo + '"]').removeAttr('disabled');
519 cj('#field_' + blockNo + '_total_amount').removeAttr('readonly');
520 });
521}
522
523function setPledgeAmount(form, pledgeID) {
04e6444d 524 var rowID = form.closest('div.crm-grid-row').attr('entity_id');
525 var dataUrl = CRM.url('civicrm/ajax/pledgeAmount');
8777ffd1 526 if (pledgeID) {
9fa00ed1 527 cj.post(dataUrl, {pid: pledgeID}, function (data) {
5542b7c2 528 cj('#field_' + rowID + '_financial_type').val(data.financial_type_id).change();
9fa00ed1 529 cj('#field_' + rowID + '_total_amount').val(data.amount).change();
04e6444d 530 cj('#field_' + rowID + '_total_amount').attr('readonly', true);
9fa00ed1 531 }, 'json');
532 }
533 else {
534 cj('#field_' + rowID + '_total_amount').val('').change();
8777ffd1 535 cj('#field_' + rowID + '_financial_type').val('').change();
9fa00ed1 536 cj('#field_' + rowID + '_total_amount').removeAttr('readonly');
537 }
04e6444d 538}
6a488035 539
04e6444d 540//end for pledge amount
6a488035
TO
541</script>
542{/literal}
6a488035
TO
543{*include batch copy js js file*}
544{include file="CRM/common/batchCopy.tpl"}