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