event-tickets-with-ticket-scanner
Last commit date
3rd
9 months ago
css
9 months ago
img
9 months ago
languages
9 months ago
ticket
9 months ago
vendors
9 months ago
SASO_EVENTTICKETS.php
9 months ago
backend.js
9 months ago
changelog.txt
9 months ago
db.php
9 months ago
index.php
9 months ago
init_file.php
9 months ago
js_seatingplan.js
9 months ago
order_details.js
9 months ago
readme.txt
9 months ago
saso-eventtickets-validator.js
9 months ago
sasoEventtickets_AdminSettings.php
9 months ago
sasoEventtickets_Authtoken.php
9 months ago
sasoEventtickets_Base.php
9 months ago
sasoEventtickets_Core.php
9 months ago
sasoEventtickets_Frontend.php
9 months ago
sasoEventtickets_Messenger.php
9 months ago
sasoEventtickets_Options.php
9 months ago
sasoEventtickets_PDF.php
9 months ago
sasoEventtickets_Ticket.php
9 months ago
sasoEventtickets_TicketBadge.php
9 months ago
sasoEventtickets_TicketDesigner.php
9 months ago
sasoEventtickets_TicketQR.php
9 months ago
ticket_events.js
9 months ago
ticket_scanner.js
9 months ago
validator.js
9 months ago
wc_backend.js
9 months ago
wc_frontend.js
9 months ago
woocommerce-hooks.php
9 months ago
backend.js
3706 lines
| 1 | function sasoEventtickets(_myAjaxVar, doNotInit) { |
| 2 | const { __, _x, _n, sprintf } = wp.i18n; |
| 3 | let myAjax = _myAjaxVar; |
| 4 | let self = this; |
| 5 | let PREMIUM = null; |
| 6 | var $ = jQuery; |
| 7 | var PARAS = basics_ermittelURLParameter(); |
| 8 | var DATA = { |
| 9 | /*action: '',*/ |
| 10 | nonce: myAjax.nonce, |
| 11 | last_nonce_check: 0 |
| 12 | }; |
| 13 | |
| 14 | var system = {is_debug:false, DYNJS:{}, DYNJS_CACHE:{}}; |
| 15 | var FATAL_ERROR = false; |
| 16 | var DIV = null; |
| 17 | var LAYOUT = null; |
| 18 | var DATA_LISTS = null; |
| 19 | var DATA_AUTHTOKENS = null; |
| 20 | var OPTIONS = { |
| 21 | list:[], mapKeys:{}, |
| 22 | versions:{mapKeys:{}}, |
| 23 | meta_tags_keys:{list:[], mapKeys:{}}, |
| 24 | infos:{}, |
| 25 | tickets_for_testing:[], |
| 26 | options_special:{} |
| 27 | }; |
| 28 | |
| 29 | var STATE = null; |
| 30 | |
| 31 | if (_myAjaxVar._doNotInit) doNotInit = true; |
| 32 | |
| 33 | function time() { |
| 34 | return new Date().getTime(); |
| 35 | } |
| 36 | |
| 37 | function destroy_tags(t) { |
| 38 | if (t != null) { |
| 39 | t = t.replace("<", "").replace(">",""); |
| 40 | } |
| 41 | return t; |
| 42 | } |
| 43 | |
| 44 | function _requestURL(action, myData) { |
| 45 | let paras = '?action='+myAjax._action+'&a_sngmbh='+action+'&nonce='+ DATA.nonce+'&t='+time(); |
| 46 | if (myData) { |
| 47 | for(let key in myData) paras += '&data['+key+']='+encodeURIComponent(myData[key]); |
| 48 | } |
| 49 | for(let key in DATA) paras += '&'+key+'='+encodeURIComponent(DATA[key]); |
| 50 | return myAjax.url + paras; |
| 51 | } |
| 52 | |
| 53 | function _makePost(action, myData, cbf, ecbf, pcbf) { |
| 54 | if (FATAL_ERROR) return; |
| 55 | let _data = Object.assign({}, DATA); |
| 56 | _data.action = myAjax._action; |
| 57 | _data.a_sngmbh = action; |
| 58 | _data.t = new Date().getTime(); |
| 59 | _data.nonce = DATA.nonce; |
| 60 | pcbf && pcbf(); |
| 61 | for(var key in myData) _data['data['+key+']'] = myData[key]; |
| 62 | $.post( myAjax.url, _data, function( response ) { |
| 63 | if (response && response.data && response.data.nonce) { |
| 64 | DATA.last_nonce_check = new Date().getTime(); |
| 65 | DATA.nonce = response.data.nonce; |
| 66 | } |
| 67 | if (!response.success) { |
| 68 | if (ecbf) ecbf(response); |
| 69 | else LAYOUT.renderFatalError(response.data); |
| 70 | } else { |
| 71 | cbf && cbf(response.data); |
| 72 | } |
| 73 | }); |
| 74 | } |
| 75 | |
| 76 | function _makeGet(action, myData, cbf, ecbf, pcbf) { |
| 77 | if (FATAL_ERROR) return; |
| 78 | let _data = Object.assign({}, DATA); |
| 79 | _data.action = myAjax._action; |
| 80 | _data.a_sngmbh = action; |
| 81 | _data.t = new Date().getTime(); |
| 82 | _data.nonce = DATA.nonce; |
| 83 | pcbf && pcbf(); |
| 84 | for(var key in myData) _data['data['+key+']'] = myData[key]; |
| 85 | $.get( myAjax.url, _data, function( response ) { |
| 86 | if (response && response.data && response.data.nonce) { |
| 87 | DATA.last_nonce_check = new Date().getTime(); |
| 88 | DATA.nonce = response.data.nonce; |
| 89 | } |
| 90 | if (!response.success) { |
| 91 | if (ecbf) ecbf(response); |
| 92 | else LAYOUT.renderFatalError(response.data); |
| 93 | } else { |
| 94 | cbf && cbf(response.data); |
| 95 | } |
| 96 | }); |
| 97 | } |
| 98 | |
| 99 | function getOptionsFromServer(cbf, ecbf, pcbf) { |
| 100 | _makeGet('getOptions', {}, options=>{ |
| 101 | _setOptions(options); |
| 102 | cbf && cbf(options); |
| 103 | }, ecbf, pcbf); |
| 104 | } |
| 105 | |
| 106 | function _downloadFile(action, myData, filenameToStore, cbf, ecbf, pcbf) { |
| 107 | let _data = Object.assign({}, DATA); |
| 108 | _data.action = myAjax._action; |
| 109 | _data.a_sngmbh = action; |
| 110 | _data.t = new Date().getTime(); |
| 111 | _data.nonce = DATA.nonce; |
| 112 | pcbf && pcbf(); |
| 113 | for(var key in myData) _data['data['+key+']'] = myData[key]; |
| 114 | let params = ""; |
| 115 | for(var key in _data) params += key+"="+_data[key]+"&"; |
| 116 | let url = myAjax.url+'?'+params; |
| 117 | let window_name = myData.code ? myData.code : '_blank'; |
| 118 | let new_window = window.open(url, window_name); |
| 119 | //window.location.href = url; |
| 120 | //ajax_downloadFile(url, filenameToStore, cbf); |
| 121 | } |
| 122 | function ajax_downloadFile(urlToSend, fileName, cbf) { |
| 123 | var req = new XMLHttpRequest(); |
| 124 | req.open("GET", urlToSend, true); |
| 125 | req.responseType = "blob"; |
| 126 | req.onload = function (event) { |
| 127 | var blob = req.response; |
| 128 | //var fileName = req.getResponseHeader("X-fileName") //if you have the fileName header available |
| 129 | var link=document.createElement('a'); |
| 130 | link.href=window.URL.createObjectURL(blob); |
| 131 | link.download=fileName; |
| 132 | link.click(); |
| 133 | cbf && cbf(); |
| 134 | }; |
| 135 | |
| 136 | req.send(); |
| 137 | } |
| 138 | |
| 139 | function speakOutLoud(v, display) { |
| 140 | if ('speechSynthesis' in window) { |
| 141 | var t = typeof v === 'object' ? 'Value is an object.' : v; |
| 142 | if (t.trim() == "") t = 'Value is empty'; |
| 143 | var msg = new SpeechSynthesisUtterance(t); |
| 144 | msg.lang = "en-US"; |
| 145 | window.speechSynthesis.speak(msg); |
| 146 | if (display) console.log("Speak:", v); |
| 147 | } else { |
| 148 | console.log(v); |
| 149 | } |
| 150 | } |
| 151 | function _setOptions(optionData) { |
| 152 | OPTIONS.list = optionData.options; |
| 153 | for (let a=0;a<OPTIONS.list.length;a++) { |
| 154 | let item = OPTIONS.list[a]; |
| 155 | OPTIONS.mapKeys[item.key] = item; |
| 156 | OPTIONS.mapKeys[item.key].getValue = function(key) { |
| 157 | return function() {return _getOptions_getValByKey(key);}; |
| 158 | }(item.key); |
| 159 | } |
| 160 | if (optionData.versions) { |
| 161 | if (!optionData.versions.IS_PRETTY_PERMALINK_ACTIVATED) { |
| 162 | LAYOUT.renderInfoBox(__("Warning", 'event-tickets-with-ticket-scanner'), __("In order to make the ticket detail view and the ticket scanner work, you need to set a permalink structure within the settings.<br>Please go to the settings->permalinks and choose a permalink structure, that is not 'plain'.", 'event-tickets-with-ticket-scanner')); |
| 163 | } |
| 164 | OPTIONS.versions.mapKeys = optionData.versions; |
| 165 | } |
| 166 | if (optionData.meta_tags_keys) { |
| 167 | OPTIONS.meta_tags_keys.list = optionData.meta_tags_keys; |
| 168 | OPTIONS.meta_tags_keys.mapKeys = {}; |
| 169 | for (let a=0;a<OPTIONS.meta_tags_keys.list.length;a++) { |
| 170 | let item = OPTIONS.meta_tags_keys.list[a]; |
| 171 | OPTIONS.meta_tags_keys.mapKeys[item.key] = item; |
| 172 | OPTIONS.meta_tags_keys.mapKeys[item.key].getValue = function(key) { |
| 173 | return function() {return _getOptions_Meta_getValByKey(key);}; |
| 174 | }(item.key); |
| 175 | } |
| 176 | } |
| 177 | if (optionData.infos) { |
| 178 | OPTIONS.infos = optionData.infos; |
| 179 | } |
| 180 | if (optionData.tickets_for_testing) { |
| 181 | OPTIONS.tickets_for_testing = optionData.tickets_for_testing; |
| 182 | } |
| 183 | if (optionData.options_special) { |
| 184 | OPTIONS.options_special = optionData.options_special; |
| 185 | } |
| 186 | |
| 187 | if (isPremium()) { |
| 188 | let serial = _getOptions_getValByKey('serial'); |
| 189 | if (serial == '') { |
| 190 | if (STATE != "options") { |
| 191 | let errortext = __("You are using the premium version. Many thanks, please enter your serial key within the options", 'event-tickets-with-ticket-scanner'); |
| 192 | let i = confirm(errortext); |
| 193 | if (i) { |
| 194 | _displayOptionsArea(); |
| 195 | } |
| 196 | } |
| 197 | } |
| 198 | if (serial != "" && typeof OPTIONS.infos.premium_expiration !== "undefined") { |
| 199 | let expiration = OPTIONS.infos.premium_expiration; |
| 200 | if (expiration.last_run != 0 && expiration.timestamp > 0) { |
| 201 | let expirationDate = new Date(expiration.timestamp * 1000); |
| 202 | let toCheck = new Date(); |
| 203 | toCheck.setDate(toCheck.getDate() + 21); |
| 204 | let today = new Date(); |
| 205 | if (expirationDate <= today || toCheck >= expirationDate) { |
| 206 | let msg = typeof expiration.message !== "undefined" && expiration.message != "" ? '<br>'+expiration.message : ''; |
| 207 | let info_box = $('<div style="background-color:red;color:white;padding:10px;">').html("Your premium license expires soon, at the "+expiration.expiration_date+ ' '+expiration.timezone+'<br>It will work, but no updates are possible for the premium plugin after the expiration date.<br>'+msg+'You can <a target="_blank" style="color:white;font-weight:bold;" href="https://vollstart.com/event-tickets-with-ticket-scanner/">renew your premium license here</a>.'); |
| 208 | $('body').find('div[data-id="plugin_info_area"').html(info_box); |
| 209 | } |
| 210 | } |
| 211 | } |
| 212 | } |
| 213 | } |
| 214 | |
| 215 | function _getOptions_getByKey(key) { |
| 216 | if (OPTIONS.mapKeys[key]) return OPTIONS.mapKeys[key]; |
| 217 | return null; |
| 218 | } |
| 219 | function _getOptions_Meta_getByKey(key) { |
| 220 | if (OPTIONS.meta_tags_keys.mapKeys[key]) return OPTIONS.meta_tags_keys.mapKeys[key]; |
| 221 | return null; |
| 222 | } |
| 223 | function _getOptions_Versions_getByKey(key) { |
| 224 | if (OPTIONS.versions.mapKeys[key]) return OPTIONS.versions.mapKeys[key]; |
| 225 | return null; |
| 226 | } |
| 227 | function _getOptions_Infos_getByKey(key) { |
| 228 | if (OPTIONS.infos[key]) return OPTIONS.infos[key]; |
| 229 | return null; |
| 230 | } |
| 231 | function _getOptions_isActivatedByKey(key) { |
| 232 | let po = _getOptions_getByKey(key); |
| 233 | if (po == null) return false; |
| 234 | return po.value == 1; |
| 235 | } |
| 236 | function _getOptions_Versions_isActivatedByKey(key) { |
| 237 | let po = _getOptions_Versions_getByKey(key); |
| 238 | if (po == null) return false; |
| 239 | return po == 1; |
| 240 | } |
| 241 | function _getOptions_getLabelByKey(key) { |
| 242 | let po = _getOptions_getByKey(key); |
| 243 | if (po == null) return ""; |
| 244 | return po.label; |
| 245 | } |
| 246 | function _getOptions_Meta_getLabelByKey(key) { |
| 247 | let po = _getOptions_Meta_getByKey(key); |
| 248 | if (po == null) return ""; |
| 249 | return po.label; |
| 250 | } |
| 251 | function _getOptions_getValByKey(key) { |
| 252 | let po = _getOptions_getByKey(key); |
| 253 | if (po == null) return ""; |
| 254 | return po.value == "" ? po['default'] : po.value; |
| 255 | } |
| 256 | function _getOptions_Versions_getValByKey(key) { |
| 257 | let po = _getOptions_Versions_getByKey(key); |
| 258 | if (po == null) return ""; |
| 259 | return po; |
| 260 | } |
| 261 | |
| 262 | function basics_ermittelURLParameter() { |
| 263 | var parawerte = {}; |
| 264 | var teile; |
| 265 | if (window.location.search !== "") { |
| 266 | teile = window.location.search.substring(1).split("&"); |
| 267 | for (var a=0;a<teile.length;a++) |
| 268 | { |
| 269 | var pos = teile[a].indexOf("="); |
| 270 | if (pos < 0) { |
| 271 | parawerte[teile[a]] = true; |
| 272 | } else { |
| 273 | var key = teile[a].substring(0,pos); |
| 274 | parawerte[key] = decodeURIComponent(teile[a].substring(pos+1)); |
| 275 | } |
| 276 | } |
| 277 | } |
| 278 | return parawerte; |
| 279 | } |
| 280 | |
| 281 | function intval(v) { |
| 282 | let retv = parseInt(v,10); |
| 283 | if (isNaN(retv)) retv = 0; |
| 284 | return retv; |
| 285 | } |
| 286 | |
| 287 | function DateTime2Text(millisek) { |
| 288 | return Date2Text(millisek, OPTIONS.options_special.format_datetime ? OPTIONS.options_special.format_datetime : "d.m.Y H:i"); |
| 289 | } |
| 290 | function Date2Text(millisek, format, timezone_id) { |
| 291 | if (!millisek) |
| 292 | millisek = time(timezone_id); |
| 293 | var d = new Date(millisek); |
| 294 | if (!format) |
| 295 | //format = system.format_date ? system.format_date : "%d.%m.%Y"; |
| 296 | format = OPTIONS.options_special.format_date ? OPTIONS.options_special.format_date : "d.m.Y"; |
| 297 | //format = "%d.%m.%Y %H:%i"; |
| 298 | var tage = [ |
| 299 | _x('Sun', 'cal', 'event-tickets-with-ticket-scanner'), |
| 300 | _x('Mon', 'cal', 'event-tickets-with-ticket-scanner'), |
| 301 | _x('Tue', 'cal', 'event-tickets-with-ticket-scanner'), |
| 302 | _x('Wed', 'cal', 'event-tickets-with-ticket-scanner'), |
| 303 | _x('Thu', 'cal', 'event-tickets-with-ticket-scanner'), |
| 304 | _x('Fri', 'cal', 'event-tickets-with-ticket-scanner'), |
| 305 | _x('Sat', 'cal', 'event-tickets-with-ticket-scanner') |
| 306 | ]; |
| 307 | var monate = [ |
| 308 | _x('Jan', 'cal', 'event-tickets-with-ticket-scanner'), |
| 309 | _x('Feb', 'cal', 'event-tickets-with-ticket-scanner'), |
| 310 | _x('Mar', 'cal', 'event-tickets-with-ticket-scanner'), |
| 311 | _x('Apr', 'cal', 'event-tickets-with-ticket-scanner'), |
| 312 | _x('May', 'cal', 'event-tickets-with-ticket-scanner'), |
| 313 | _x('Jun', 'cal', 'event-tickets-with-ticket-scanner'), |
| 314 | _x('Jul', 'cal', 'event-tickets-with-ticket-scanner'), |
| 315 | _x('Aug', 'cal', 'event-tickets-with-ticket-scanner'), |
| 316 | _x('Sep', 'cal', 'event-tickets-with-ticket-scanner'), |
| 317 | _x('Oct', 'cal', 'event-tickets-with-ticket-scanner'), |
| 318 | _x('Nov', 'cal', 'event-tickets-with-ticket-scanner'), |
| 319 | _x('Dec', 'cal', 'event-tickets-with-ticket-scanner') |
| 320 | ]; |
| 321 | var formate = {'d':d.getDate()<10?'0'+d.getDate():d.getDate(), |
| 322 | 'j':d.getDate(),'D':tage[d.getDay()],'w':d.getDate(),'m':d.getMonth()+1<10?'0'+(d.getMonth()+1):d.getMonth()+1,'M':monate[d.getMonth()], |
| 323 | 'n':d.getMonth()+1,'Y':d.getFullYear(),'y':d.getYear()>100?d.getYear().toString().substring(d.getYear().toString().length-2):d.getYear(), |
| 324 | 'H':d.getHours()<10?'0'+d.getHours():d.getHours(),'h':d.getHours()>12?d.getHours()-12:d.getHours(), |
| 325 | 'i':d.getMinutes()<10?'0'+d.getMinutes():d.getMinutes(),'s':d.getSeconds()<10?'0'+d.getSeconds():d.getSeconds() |
| 326 | }; |
| 327 | for (var akey in formate) { |
| 328 | //var rg = new RegExp('%'+akey, "g"); |
| 329 | var rg = new RegExp(akey, "g"); |
| 330 | format = format.replace(rg, formate[akey]); |
| 331 | } |
| 332 | return format; |
| 333 | } |
| 334 | |
| 335 | function _getMediaData(mediaid, cbf) { |
| 336 | _makeGet('getMediaData', {'mediaid':mediaid}, (ret)=>{ |
| 337 | cbf && cbf(ret); |
| 338 | }); |
| 339 | } |
| 340 | |
| 341 | function getDataLists(cbf) { |
| 342 | if (DATA_LISTS !== null) cbf && cbf(); |
| 343 | _makeGet('getLists', {}, data=>{ |
| 344 | DATA_LISTS = data; |
| 345 | cbf && cbf(DATA_LISTS); |
| 346 | }); |
| 347 | } |
| 348 | |
| 349 | function getCodeObjectMeta(codeObj) { |
| 350 | if (codeObj.metaObj) return codeObj.metaObj; |
| 351 | try { |
| 352 | if (typeof codeObj.meta == "undefined" || codeObj.meta == "") { |
| 353 | codeObj.metaObj = null; |
| 354 | } else { |
| 355 | codeObj.metaObj = JSON.parse(codeObj.meta); |
| 356 | } |
| 357 | } catch(e) { |
| 358 | // new empty tickets have no meta |
| 359 | //console.log("Error should not happen. Meta is broken. ", codeObj); |
| 360 | codeObj.metaObj = null; |
| 361 | } |
| 362 | return codeObj.metaObj; |
| 363 | } |
| 364 | |
| 365 | function updateCodeObject(codeObj, newCodeObj) { |
| 366 | for(var prop in newCodeObj) { |
| 367 | codeObj[prop] = newCodeObj[prop]; |
| 368 | } |
| 369 | codeObj.metaObj = null; |
| 370 | } |
| 371 | |
| 372 | function closeDialog(dlg) { |
| 373 | $(dlg).dialog( "close" ); |
| 374 | $(dlg).html(''); |
| 375 | $(dlg).dialog("destroy").remove(); |
| 376 | $(dlg).empty(); |
| 377 | $(dlg).remove(); |
| 378 | $('.ui-dialog-content').dialog('destroy'); |
| 379 | } |
| 380 | |
| 381 | function getUseFulVideosHTML() { |
| 382 | return '<h3>Useful videos</h3><ul><li><span class="dashicons dashicons-external"></span><a href="https://youtu.be/yJcHMV7oAFc" target="_blank">Setup for use case Event Organizer (Youtube)</a></li><li><span class="dashicons dashicons-external"></span><a href="https://www.youtube.com/watch?v=TDMWI0R_HXQ" target="_blank">Setup for use case Club, Spa and Fitness clubs (Youtube)</a></li></ul>'; |
| 383 | } |
| 384 | |
| 385 | function getAuthtokens(cbf) { |
| 386 | if (DATA_AUTHTOKENS !== null) cbf && cbf(); |
| 387 | _makeGet('getAuthtokens', {}, data=>{ |
| 388 | DATA_AUTHTOKENS = data; |
| 389 | cbf && cbf(DATA_AUTHTOKENS); |
| 390 | }); |
| 391 | } |
| 392 | |
| 393 | function _displayAuthTokensArea() { |
| 394 | STATE = 'authtokens'; |
| 395 | DIV.html(''); |
| 396 | DIV.append(getBackButtonDiv()); |
| 397 | |
| 398 | DIV.append('<h3>'+_x('Auth Token', 'label', 'event-tickets-with-ticket-scanner')+'</h3>'); |
| 399 | $('<p>').html(__('You can add auth tokens, that can be used to access your ticket scanner. Create an auth token and pass the QR code to the user or let the user scan it from your admin area. The used auth token will bypass any access restricton settings for the ticket scanner that are set in the options.', 'event-tickets-with-ticket-scanner')).appendTo(DIV); |
| 400 | $('<p>').html(__('The user scan the QR code for the auth token with the ticket scanner. Just like a normal ticket. The system will store the auth token to the browser.', 'event-tickets-with-ticket-scanner')).appendTo(DIV); |
| 401 | let loading = $('<div/>').html(_getSpinnerHTML()).appendTo(DIV); |
| 402 | let div2 = $('<div style="background:white;padding:15px;border-radius:15px;">').appendTo(DIV); |
| 403 | let tplace = $('<div style="background:white;padding:15px;border-radius:15px;"/>'); |
| 404 | |
| 405 | getOptionsFromServer(reply=>{ |
| 406 | let tabelle_authtokens_datatable; |
| 407 | let btn_new = $('<button/>').addClass("button-primary").html(_x('Add', 'label', 'event-tickets-with-ticket-scanner')).on("click", ()=>{ |
| 408 | __showMaskAuthtoken(null); |
| 409 | }); |
| 410 | $('<div/>').css('text-align', 'right').css('margin-bottom','10px').append(btn_new).appendTo(div2); |
| 411 | let div_tabelle = $('<div>'); |
| 412 | loading.html(""); |
| 413 | tplace.html("").append(div_tabelle).appendTo(div2); |
| 414 | |
| 415 | function __showMaskAuthtoken(editValues) { |
| 416 | let _options = { |
| 417 | title: editValues !== null ? _x('Edit Auth Token', 'title', 'event-tickets-with-ticket-scanner') : _x('Add Auth Token', 'title', 'event-tickets-with-ticket-scanner'), |
| 418 | modal: true, |
| 419 | minWidth: 600, |
| 420 | minHeight: 400, |
| 421 | buttons: [ |
| 422 | { |
| 423 | text: _x('Ok', 'label', 'event-tickets-with-ticket-scanner'), |
| 424 | click: function() { |
| 425 | ___submitForm(); |
| 426 | } |
| 427 | }, |
| 428 | { |
| 429 | text: _x('Cancel', 'label', 'event-tickets-with-ticket-scanner'), |
| 430 | click: function() { |
| 431 | closeDialog(this); |
| 432 | } |
| 433 | } |
| 434 | ] |
| 435 | }; |
| 436 | let dlg = $('<div/>').html('<form>'+_x('Name', 'label', 'event-tickets-with-ticket-scanner')+'<br><input name="inputName" type="text" style="width:100%;" required></form>'); |
| 437 | dlg.dialog(_options); |
| 438 | |
| 439 | dlg.find("form").append('<p>'+_x('Bound to product(s)', 'label', 'event-tickets-with-ticket-scanner')+'<br><input name="inputBoundToProducts" type="text" placeholder="'+_x('all products allowed to be redeemed', 'label', 'event-tickets-with-ticket-scanner')+'" style="width:100%;"><br>'+__('You can add comma seperated "," product ids. This will limit the user to redeem tickets only of products listed here. If left empty, all are allowed.', 'event-tickets-with-ticket-scanner')+'</p>'); |
| 440 | dlg.dialog(_options); |
| 441 | |
| 442 | dlg.find("form").append($('<p>'+_x('Description', 'label', 'event-tickets-with-ticket-scanner')+'<br><textarea name="desc" style="width:100%;"></textarea></p>')); |
| 443 | if (isPremium() && typeof PREMIUM.addAuthtokenMaskEditFields != "undefined") PREMIUM.addAuthtokenMaskEditFields(dlg, editValues); |
| 444 | dlg.find("form").append($('<p><input type="checkbox" name="aktiv">'+_x('is active', 'label', 'event-tickets-with-ticket-scanner')+'</p>')); |
| 445 | |
| 446 | let form = dlg.find("form").on("submit", event=>{ |
| 447 | event.preventDefault(); |
| 448 | ___submitForm(); |
| 449 | }); |
| 450 | |
| 451 | let metaObj = []; |
| 452 | if (editValues && typeof editValues.meta !== "undefined" && editValues.meta != "") { |
| 453 | try { |
| 454 | metaObj = JSON.parse(editValues.meta); |
| 455 | } catch(e) {} |
| 456 | } |
| 457 | |
| 458 | if (editValues) { |
| 459 | form[0].elements['inputName'].value = editValues.name; |
| 460 | form[0].elements['inputName'].select(); |
| 461 | form[0].elements['inputBoundToProducts'].value = editValues.metaObj.ticketscanner.bound_to_products; |
| 462 | form[0].elements['aktiv'].checked = editValues.aktiv == 1 ? true : false; |
| 463 | if (typeof metaObj.desc !== "undefined") { |
| 464 | form[0].elements['desc'].value = metaObj.desc; |
| 465 | } |
| 466 | } |
| 467 | |
| 468 | function ___submitForm() { |
| 469 | let inputName = form[0].elements['inputName'].value.trim(); |
| 470 | if (inputName === "") return; |
| 471 | |
| 472 | dlg.html(_getSpinnerHTML()); |
| 473 | let _data = {"name":inputName}; |
| 474 | _data['aktiv'] = form[0].elements['aktiv'].checked ? 1 : 0; |
| 475 | _data['meta'] = {"desc":"", "ticketscanner":{"bound_to_products":""}}; |
| 476 | _data['meta']['desc'] = form[0].elements['desc'].value.trim(); |
| 477 | _data['meta']['ticketscanner']['bound_to_products'] = form[0].elements['inputBoundToProducts'].value.trim(); |
| 478 | if (isPremium() && typeof PREMIUM.addAuthtokenMaskEditFieldsData != "undefined") PREMIUM.addAuthtokenMaskEditFieldsData(_data, form[0], editValues); |
| 479 | |
| 480 | form[0].reset(); |
| 481 | if (editValues) { |
| 482 | _data.id = editValues.id; |
| 483 | _makePost('editAuthtoken', _data, result=>{ |
| 484 | DATA_AUTHTOKENS = null; |
| 485 | __renderTabelleAuthtokens(); |
| 486 | //tabelle_authtokens_datatable.ajax.reload(); |
| 487 | setTimeout(function(){closeDialog(dlg);},250); |
| 488 | }, ()=>{ |
| 489 | closeDialog(dlg); |
| 490 | }); |
| 491 | } else { |
| 492 | _makePost('addAuthtoken', _data, result=>{ |
| 493 | DATA_AUTHTOKENS = null; |
| 494 | __renderTabelleAuthtokens(); |
| 495 | closeDialog(dlg); |
| 496 | }, response=>{ |
| 497 | closeDialog(dlg); |
| 498 | if (response.data.slice(0,1) === "#") { |
| 499 | FATAL_ERROR === false && LAYOUT.renderFatalError(response.data); |
| 500 | //FATAL_ERROR = true; |
| 501 | } |
| 502 | }); |
| 503 | } |
| 504 | } |
| 505 | } // end __showMaskAuthtoken |
| 506 | |
| 507 | function __renderTabelleAuthtokens() { |
| 508 | div_tabelle.html(_getSpinnerHTML()); |
| 509 | getAuthtokens(()=>{ |
| 510 | let table_id = myAjax.divPrefix+'_tabelle_authtokens'; |
| 511 | let tabelle = $('<table/>').attr("id", table_id); |
| 512 | tabelle.html('<thead><tr><th></th><th align="left">'+_x('Name', 'label', 'event-tickets-with-ticket-scanner')+'</th><th align="left">'+_x('Created', 'label', 'event-tickets-with-ticket-scanner')+'</th><th>'+_x('Area', 'label', 'event-tickets-with-ticket-scanner')+'</th><th>'+_x('Status', 'label', 'event-tickets-with-ticket-scanner')+'</th><th></th></tr></thead>'); |
| 513 | div_tabelle.html(tabelle); |
| 514 | |
| 515 | let table = $('#'+table_id); |
| 516 | $(table).DataTable().clear().destroy(); |
| 517 | tabelle_authtokens_datatable = $(table).DataTable({ |
| 518 | "responsive": true, |
| 519 | "visible": true, |
| 520 | "searching": true, |
| 521 | "ordering": true, |
| 522 | "processing": true, |
| 523 | "serverSide": false, |
| 524 | "stateSave": true, |
| 525 | "data": DATA_AUTHTOKENS, |
| 526 | "order": [[ 1, "asc" ]], |
| 527 | "columns":[ |
| 528 | {"data":null,"className":'details-control',"orderable":false,"defaultContent":'', "width":10}, |
| 529 | {"data":"name", "orderable":true, |
| 530 | "render": ( data, type, row )=>{ |
| 531 | return encodeURIComponent(data); |
| 532 | } |
| 533 | }, |
| 534 | {"data":"time", "orderable":true, "width":80, |
| 535 | "render":function (data, type, row) { |
| 536 | return '<span style="display:none;">'+data+'</span>'+DateTime2Text(data); |
| 537 | } |
| 538 | }, |
| 539 | {"data":"areacode", "orderable":true, "className":"dt-center", "width":80}, |
| 540 | {"data":"aktiv", "orderable":true, "width":50, "className":"dt-center", "render":(data, type, row)=>{ |
| 541 | return data == 1 ? 'active' : 'inactive'; |
| 542 | }}, |
| 543 | {"data":null,"orderable":false,"defaultContent":'',"className":"buttons dt-right","width":100, |
| 544 | "render": ( data, type, row )=>{ |
| 545 | return '<button class="button-secondary" data-type="edit">'+_x('Edit', 'label', 'event-tickets-with-ticket-scanner')+'</button> <button class="button-secondary" data-type="delete">'+_x('Delete', 'label', 'event-tickets-with-ticket-scanner')+'</button>'; |
| 546 | } |
| 547 | } |
| 548 | ] |
| 549 | }); |
| 550 | tabelle.css("width", "100%"); |
| 551 | table.on('click', 'button[data-type="edit"]', e=>{ |
| 552 | let data = tabelle_authtokens_datatable.row( $(e.target).parents('tr') ).data(); |
| 553 | __showMaskAuthtoken(data); |
| 554 | }); |
| 555 | table.on('click', 'button[data-type="delete"]', e=>{ |
| 556 | let data = tabelle_authtokens_datatable.row( $(e.target).parents('tr') ).data(); |
| 557 | LAYOUT.renderYesNo(_x('Do you want to delete?', 'title', 'event-tickets-with-ticket-scanner'), __('Are you sure, you want to delete this auth token?', 'event-tickets-with-ticket-scanner')+'<br><p><b>'+data.name+'</b></p>'+__('The user with this auth token will not be able to use the server anymore. The user will need to add a new auth token from you.<p>The effect will be immediately.</p>', 'event-tickets-with-ticket-scanner'), ()=>{ |
| 558 | let _data = {'id':data.id}; |
| 559 | div_tabelle.html(_getSpinnerHTML()); |
| 560 | _makePost('removeAuthtoken', _data, result=>{ |
| 561 | DATA_AUTHTOKENS = null; |
| 562 | __renderTabelleAuthtokens(); |
| 563 | //tabelle_authtokens_datatable.ajax.reload(); |
| 564 | }); |
| 565 | }); |
| 566 | }); |
| 567 | $('#'+table_id+' tbody').on('click', 'td.details-control', e=>{ |
| 568 | function ___format(d) { |
| 569 | let metaObj = {}; |
| 570 | if (d.metaObj) metaObj = d.metaObj; |
| 571 | if (d.meta && !d.metaObj) { |
| 572 | metaObj = JSON.parse(d.meta); |
| 573 | } |
| 574 | let id = 'qrcode_'+d.id+'_'+time(); |
| 575 | let content = JSON.stringify({"type":"auth", "time":d.time, "name":d.name, "code":d.code, "areacode":d.areacode, "url":OPTIONS.infos.site.site_url}); |
| 576 | let content2 = _getTicketScannerURL()+'&auth='+encodeURIComponent(content); |
| 577 | |
| 578 | let div = $('<div/>'); |
| 579 | $('<div>').html("<b>Authcode: </b>"+d.code).appendTo(div); |
| 580 | let div_wrapper = $('<div style="padding-top:10px;">').appendTo(div); |
| 581 | |
| 582 | $('<div style="width:256px;float:left;text-align:center">').html('<b>Only Auth Token</b><div id="'+id+'" style="text-align:center;"></div><script>jQuery("#'+id+'").qrcode(\''+content+'\');</script>').appendTo(div_wrapper); |
| 583 | $('<div style="margin-left:20px;width:256px;float:left;text-align:center">').html('<b>With Ticket Scanner URL</b><div id="'+id+'2" style="text-align:center;"></div><script>jQuery("#'+id+'2").qrcode(\''+content2+'\');</script>').appendTo(div_wrapper); |
| 584 | |
| 585 | let div_inner = $('<div style="float:left;padding-left:10px;">').appendTo(div_wrapper); |
| 586 | let _desc = metaObj.desc == "" ? "-" : metaObj.desc; |
| 587 | $('<div>').html('<b><a href="'+content2+'" target="_blank">Open Ticket Scanner with Auth Token</a></b>').appendTo(div_inner); |
| 588 | $('<div>').html('<b>Desc:</b> ').append($('<span>').text(_desc)).appendTo(div_inner); |
| 589 | |
| 590 | let bound_to_products = metaObj.ticketscanner.bound_to_products == "" ? [] : metaObj.ticketscanner.bound_to_products.toString().split(","); |
| 591 | $("<div>").html("<b>Bound to product:</b> "+(bound_to_products.length == 0 ? "all products": bound_to_products.join(", "))).appendTo(div_inner); |
| 592 | |
| 593 | return div; |
| 594 | } |
| 595 | |
| 596 | var tr = $(e.target).parents('tr'); |
| 597 | var row = tabelle_authtokens_datatable.row( tr ); |
| 598 | if ( row.child.isShown() ) { |
| 599 | // This row is already open - close it |
| 600 | row.child.hide(); |
| 601 | tr.removeClass('shown'); |
| 602 | } else { |
| 603 | // Open this row |
| 604 | row.child( ___format(row.data()) ).show(); |
| 605 | tr.addClass('shown'); |
| 606 | } |
| 607 | |
| 608 | }); |
| 609 | }); |
| 610 | } |
| 611 | __renderTabelleAuthtokens(); |
| 612 | }); |
| 613 | } |
| 614 | |
| 615 | function _displayFAQArea() { |
| 616 | STATE = 'faq'; |
| 617 | DIV.html(_getSpinnerHTML()); |
| 618 | |
| 619 | let questions = [ |
| 620 | { |
| 621 | "q":'PDF is not rendering - critical error', |
| 622 | "t":'<p>The used PDF library cannot handle all the fancy HTML and CSS. Using these in the product description can lead to an error. If the ticket detail page is working, but the PDF not then you can try to remove the HTML tags or use the option to not print the product description to the ticket.<br>Please set the option <b>wcTicketPDFStripHTML</b> to remove the HTML and retry the PDF by reloading the browser or click again.</p><p>If your system is not live yet, you can use the debug mode first to see which HTML tags are used. The basics HTML tags are working well.</p><p>Try the option to remove the not supported HTML tags - this is not always great, because it removes the HTML tags that Wordpress is not supporting and could still lead to PDF issues, but a great start.<br>If this was not helping, then remove please the HTML tags in your product description for a test. You can also just deactivate the option <b>wcTicketDisplayShortDesc</b> to not use the short description of the product for a test.</p>' |
| 623 | }, |
| 624 | { |
| 625 | "q":'Receiving 404 error page if calling the ticket view and/or PDF', |
| 626 | "t":'<p>Some installations have issues to open the ticket details view and/or the ticket scanner.<br>This could be because of your theme, other plugins or more stricter security settings.</p><p>If you experience to see the "file not found" page (404), then it could help if your activate the compatibility mode in the options.</p><p>For this configure the option <b>wcTicketCompatibilityModeURLPath</b> and/or <b>wcTicketCompatibilityMode</b>.</p><p>If this do not help, then the plugin will not work with your installation for now.</p>' |
| 627 | }, |
| 628 | { |
| 629 | "q":'How to ask for a value of your ticket?', |
| 630 | "t":'<p>You can setup your product to ask your customer for up to 2 values. Free text and a value chosen from a dropdown.<br>You can checkout how it is done with <a href="https://youtu.be/2vTV39wgWNE" target="_blank">this video</a>.</p>' |
| 631 | }, |
| 632 | { |
| 633 | "q":'(Pre)Create order with tickets in the backend', |
| 634 | "t":'<p>You can also checkout <a href="https://youtu.be/VxUV-s-SIpA" target="_blank">this video here</a>.<br>This video shows how to create an order from the backend and generate the tickets.<br>This approach is also good for free tickets. So you can create the order and have valid tickets. Do not forget to set the order to a redeemable status. The default is "completed".</p>' |
| 635 | }, |
| 636 | { |
| 637 | "q":'How to display meta information of the purchased item?', |
| 638 | "t":'You can display the meta information of the item with TWIG.<br>Try TWIG code in the ticket template test designer, to see if this helps. First it is a good idea to check the whole meta values. You can achieve this, by displaying the values as JSON with this code.<p><b>{% for item_id, item in ORDER.get_items %}<br>{{ item.get_meta_data|json_encode() }}<br>{% endfor %}</b></p><p>You will see the key value pairs. Then grab your values. E.g.</p><p><b>{%- for item_id, item in ORDER.get_items -%}<br>{%- if item_id == METAOBJ.woocommerce.item_id -%}<br><br>Date: {{ item.get_meta("Booked From", true) }} - {{ item.get_meta("Booked To", true) }}<br>{%- endif -%}<br>{%- endfor -%}</b></p>' |
| 639 | }, |
| 640 | { |
| 641 | "q":"How to set the order immediately to 'completed' if the order is paid?", |
| 642 | "t":"You can activate the option wcTicketSetOrderToCompleteIfAllOrderItemsAreTickets to change the order status to completed if all purchased items in the order are tickets and the order status is processing. With this the order is fine and not paid orders are not automatically set to completed. This prevents frauds." |
| 643 | }, |
| 644 | { |
| 645 | "q":"How to use own page with ticket scanner and have the QR code redirect to it?", |
| 646 | "t":"<p>You set up a page with the ticket scanner shortcode 'sasoEventTicketsValidator_ticket_scanner'.<br>Then adjust the URL for your tickets (scanner is included). The only option for now is the wcTicketCompatibilityModeURLPath. But this also changes the detail page of the ticket. Basically the system is adding to this URL just the '/scanner/?code='.</p><p>If you do not want this, you can adjust the QR content with the option qrOwnQRContent.</p><p>Set it to have the content:<br>https://domain-and-path/scanner/?code={WC_TICKET__PUBLIC_TICKET_ID}</p>" |
| 647 | } |
| 648 | ]; |
| 649 | |
| 650 | let div = $('<div>'); |
| 651 | div.append("<h2>FAQ</h2>"); |
| 652 | let div2 = $('<div style="background:white;padding:15px;border-radius:15px;">').appendTo(div); |
| 653 | div2.append(getUseFulVideosHTML()+'<br><br>'); |
| 654 | |
| 655 | questions.forEach(v=>{ |
| 656 | let clicked = false; |
| 657 | div2.append($('<h3 style="cursor:pointer;">').html("+ "+v.q).on("click",e=>{ |
| 658 | f1.css("display", clicked ? "none" : "block"); |
| 659 | clicked = !clicked; |
| 660 | })); |
| 661 | let f1 = $('<div style="display:none;padding-bottom:15px;">').html(v.t).appendTo(div2); |
| 662 | }); |
| 663 | |
| 664 | DIV.html(getBackButtonDiv()); |
| 665 | DIV.append(div); |
| 666 | } |
| 667 | |
| 668 | function _load_seatingplanJS(paras, cbj) { |
| 669 | let filename = 'js_seatingplan'; |
| 670 | if (typeof system.DYNJS === "undefined") system.DYNJS = {}; |
| 671 | if (false && system.DYNJS[filename]) { |
| 672 | //eval(system.DYNJS[filename]); |
| 673 | sasoEventtickets_js_seatingplan(paras); |
| 674 | cbj && cbj(); |
| 675 | } else { |
| 676 | $.getScript( myAjax._plugin_home_url+'/'+filename+".js", ( data, textStatus, jqxhr ) =>{ |
| 677 | system.DYNJS[filename] = data; |
| 678 | |
| 679 | eval(data); // inject code into the global scope |
| 680 | //addScriptCode(data, filename); // function is unaware of the global scope |
| 681 | |
| 682 | sasoEventtickets_js_seatingplan(paras); |
| 683 | cbj && cbj(); |
| 684 | }); |
| 685 | } |
| 686 | } |
| 687 | |
| 688 | function _displaySeatingplanArea() { |
| 689 | STATE = 'seatingplan'; |
| 690 | DIV.html(getBackButtonDiv()); |
| 691 | |
| 692 | let div = $('<div>').html(_getSpinnerHTML()); |
| 693 | |
| 694 | _load_seatingplanJS({div:div}, ()=>{ |
| 695 | //console.log("seatingplan loaded"); |
| 696 | }); |
| 697 | |
| 698 | DIV.append(div); |
| 699 | } |
| 700 | function _displaySupportInfoArea() { |
| 701 | STATE = 'support'; |
| 702 | DIV.html(_getSpinnerHTML()); |
| 703 | getOptionsFromServer(reply=>{ |
| 704 | let newline = '<br>'; |
| 705 | let div_stats = $('<div/>').html(_getSpinnerHTML()); |
| 706 | |
| 707 | _makeGet('getSupportInfos', {}, infos=>{ |
| 708 | div_stats.html(""); |
| 709 | div_stats.append('<b>Codes:</b>: '+infos.amount.codes+newline); |
| 710 | div_stats.append('<b>Lists:</b>: '+infos.amount.lists+newline); |
| 711 | div_stats.append('<b>IPs:</b>: '+infos.amount.ips+newline); |
| 712 | }); |
| 713 | |
| 714 | let data = reply.options; // options values |
| 715 | let versions = reply.versions; |
| 716 | |
| 717 | DIV.html(getBackButtonDiv()); |
| 718 | |
| 719 | // zeige support email |
| 720 | DIV.append(getUseFulVideosHTML); |
| 721 | DIV.append('<h3>Support Email</h3><b>support@vollstart.com</b>'); |
| 722 | DIV.append('<h3>Support Context Information</h3><p>'+__('Please copy the following information, so that we can support you better and faster. Remove any critical information if needed.', 'event-tickets-with-ticket-scanner')+'</p>'); |
| 723 | DIV.append('<b>Ticket Counter: </b> '+reply.infos.ticket.counter+newline); |
| 724 | DIV.append('<b>Wordpress Version:</b> '+versions.wp+newline); |
| 725 | DIV.append('<b>MySQL/Mariadb Version:</b> '+versions.mysql+newline); |
| 726 | DIV.append('<b>PHP Version:</b> '+versions.php+newline); |
| 727 | DIV.append('<b>Product:</b> Event Tickets with WooCommerce'+newline); |
| 728 | DIV.append('<b>Basic Plugin Version:</b> '+versions.basic+newline); |
| 729 | DIV.append('<b>Basic DB Version:</b> '+versions.db+newline); |
| 730 | if (versions.premium != "") { |
| 731 | DIV.append('<b>Premium Serial:</b> '+versions.premium_serial+newline); |
| 732 | DIV.append('<b>Premium Plugin Version:</b> '+versions.premium+newline); |
| 733 | DIV.append('<b>Premium DB Version:</b> '+versions.premium_db+newline); |
| 734 | } |
| 735 | DIV.append('<h4 style="margin-bottom:0;">Date</h4>'); |
| 736 | DIV.append('<b>Your default timezone: </b> '+versions.date_default_timezone+newline); |
| 737 | DIV.append('<b>Your WP timezone: </b> '+versions.date_WP_timezone+newline); |
| 738 | DIV.append('<b>Your WP timezone full: </b> '+versions.date_WP_timezone_time+newline); |
| 739 | DIV.append('<b>Your date: </b> '+versions.date_default_timezone_time+newline); |
| 740 | DIV.append('<b>UTC date: </b> '+versions.date_UTC_timezone_time+newline); |
| 741 | |
| 742 | DIV.append('<h4 style="margin-bottom:0;">Stats</h4>'); |
| 743 | DIV.append(div_stats); |
| 744 | DIV.append('<h4 style="margin-bottom:0;">URLs</h4>'); |
| 745 | DIV.append('<b>Mulitsite: </b> '+reply.infos.site.is_multisite+newline); |
| 746 | DIV.append('<b>Home: </b> '+reply.infos.site.home+newline); |
| 747 | DIV.append('<b>Network home: </b> '+reply.infos.site.network_home+newline); |
| 748 | DIV.append('<b>Site URL: </b> '+reply.infos.site.site_url+newline); |
| 749 | |
| 750 | DIV.append('<h4 style="margin-bottom:0;">Ticket URLs</h4>'); |
| 751 | //$wcTicketCompatibilityModeURLPath = trim(trim($wcTicketCompatibilityModeURLPath, "/")); |
| 752 | DIV.append('<b>Ticket Detail Own URL Path: </b> '+reply.infos.site.home+"/"+_getOptions_getValByKey("wcTicketCompatibilityModeURLPath")+newline); |
| 753 | DIV.append('<b>Ticket Scanner Own URL Path: </b> '+reply.infos.site.home+"/"+_getOptions_getValByKey("wcTicketCompatibilityModeURLPath")+'/scanner/'+newline); |
| 754 | DIV.append('<b>Ticket Default Plugin Detail URL: </b> '+reply.infos.ticket.ticket_base_url+newline); |
| 755 | DIV.append('<b>Ticket Default Plugin Scanner Path: </b> '+reply.infos.ticket.ticket_scanner_path+newline); |
| 756 | DIV.append('<b>Ticket Detail Default Plugin Path: </b> '+reply.infos.ticket.ticket_detail_path+newline); |
| 757 | DIV.append('<b>Ticket Scanner Default Plugin Path: </b> '+reply.infos.ticket.ticket_detail_path+'scanner/'+newline); |
| 758 | |
| 759 | let tabelle_errorlogs_datatable; |
| 760 | DIV.append('<h3 style="margin-bottom:10px;">Error Logs</h3>'); |
| 761 | $('<div style="text-align:right;margin-bottom:10px;">') |
| 762 | .append($('<button>').html(__('Refresh table', 'event-tickets-with-ticket-scanner')).addClass("button-secondary").on("click", ()=>{ |
| 763 | tabelle_errorlogs_datatable.ajax.reload(); |
| 764 | })) |
| 765 | .append($('<button>').html(__('Empty table', 'event-tickets-with-ticket-scanner')).addClass("sngmbh_btn-delete").on("click", ()=>{ |
| 766 | LAYOUT.renderYesNo(__('Empty table', 'event-tickets-with-ticket-scanner'), sprintf(/* translators: %s: name of ticket table */__('Do you want to empty the "%s" table? All data will be lost.', 'event-tickets-with-ticket-scanner'), _x("Error Logs", 'title', 'event-tickets-with-ticket-scanner')), ()=>{ |
| 767 | LAYOUT.renderYesNo(__('Empty table - last chance', 'event-tickets-with-ticket-scanner'), sprintf(/* translators: %s: name of ticket table */__('Are you sure? You will not be able to restore the data, except you have a backup of your database. All data will be lost.', 'event-tickets-with-ticket-scanner'), _x("Error Logs", 'title', 'event-tickets-with-ticket-scanner')), ()=>{ |
| 768 | _makeGet('emptyTableErrorLogs', null, ()=>{ |
| 769 | tabelle_errorlogs_datatable.ajax.reload(); |
| 770 | }); |
| 771 | }); |
| 772 | }); |
| 773 | })) |
| 774 | .appendTo(DIV); |
| 775 | |
| 776 | let div_tabelle = $('<div style="margin-bottom:20px;">').appendTo(DIV); |
| 777 | |
| 778 | let label_version = _x('Version', 'label', 'event-tickets-with-ticket-scanner'); |
| 779 | DIV.append('<h3 style="margin-bottom:10px;">Used Libraries</h3>'); |
| 780 | DIV.append('<p>'+__('The following libraries are used in the plugin.', 'event-tickets-with-ticket-scanner')+'</p>'); |
| 781 | DIV.append('<p>'+__('The libraries are used in the frontend and backend.', 'event-tickets-with-ticket-scanner')+'</p>'); |
| 782 | DIV.append('<ul>'); |
| 783 | DIV.append('<li><b>jQuery</b> - '+label_version+': '+jQuery.fn.jquery+'</li>'); |
| 784 | DIV.append('<li><b>jQuery UI</b> - '+label_version+': '+jQuery.ui.version+'</li>'); |
| 785 | DIV.append('<li><b>jQuery UI CSS</b> - '+label_version+': '+jQuery.ui.version+'</li>'); |
| 786 | DIV.append('<li><b>PHP TWIG template engine</b> https://twig.symfony.com/ - '+label_version+': 3.x</li>'); |
| 787 | DIV.append('<li><b>PHP QR Code</b> http://sourceforge.net/projects/phpqrcode/ - '+label_version+': 1.1.4</li>'); |
| 788 | DIV.append('<li><b>FPDI</b> '+label_version+': 2.3.7</li>'); |
| 789 | DIV.append('<li><b>FPDF</b> '+label_version+': 1.8.5</li>'); |
| 790 | DIV.append('<li><b>TCPDF</b> http://www.tcpdf.org - '+label_version+': 6.4.4</li>'); |
| 791 | DIV.append('<li><b>Javascript QR code scanner:</b> https://github.com/nimiq/qr-scanner - '+label_version+': 1.4.2</li>'); |
| 792 | DIV.append('<li><b>Javascript Datatable:</b> https://datatables.net/ - '+label_version+': 1.10.21</li>'); |
| 793 | DIV.append('<li><b>Javascript Raphael:</b> http://raphaeljs.com/ - '+label_version+': 2.3.0</li>'); |
| 794 | DIV.append('<li><b>Javascript Ace Editor</b></li>'); |
| 795 | DIV.append('<li><b>html5-qrcode:</b> https://github.com/mebjas/html5-qrcode/ - '+label_version+': 2.3.8</li>'); |
| 796 | |
| 797 | DIV.append('<h3 style="margin-bottom:10px;">Options</h3>'); |
| 798 | // liste alle optionen mit wert auf |
| 799 | data.forEach(v=>{ |
| 800 | if (v.type != 'heading' && v.key != "serial") { |
| 801 | if (v.additional && v.additional.doNotRender && v.additional.doNotRender === 1) {} |
| 802 | else { |
| 803 | let value = v.value; |
| 804 | let def = ''; |
| 805 | if (value == '') { |
| 806 | def = ' (DEFAULT used)'; |
| 807 | value = v.default; |
| 808 | } |
| 809 | text = document.createTextNode(value); |
| 810 | DIV.append(`<b>${v.key}${def}:</b> `).append(text).append(`${newline}`); |
| 811 | } |
| 812 | } |
| 813 | }); |
| 814 | |
| 815 | /* |
| 816 | DIV.append('<h3 style="margin-bottom:0;">All available Options</h3>'); |
| 817 | let list_elem = $('<div>').appendTo(DIV); |
| 818 | data.forEach(v=>{ |
| 819 | if (v.type != 'heading' && v.key != "serial" && v.type != "desc") { |
| 820 | if (v.additional && v.additional.doNotRender && v.additional.doNotRender === 1) {} |
| 821 | else { |
| 822 | list_elem.append(v.key); |
| 823 | list_elem.append(' - '); |
| 824 | list_elem.append(v.label); |
| 825 | if (v.desc != "") { |
| 826 | list_elem.append(`${newline}`).append(v.desc); |
| 827 | } |
| 828 | list_elem.append(`${newline}`); |
| 829 | list_elem.append(`${newline}`); |
| 830 | } |
| 831 | } else { |
| 832 | if (v.type == 'heading') { |
| 833 | list_elem.append(`${newline}`); |
| 834 | list_elem.append('== '+v.label+' =='); |
| 835 | if (v.desc != "") { |
| 836 | //list_elem.append(`${newline}`).append(v.desc); |
| 837 | } |
| 838 | list_elem.append(`${newline}`); |
| 839 | } |
| 840 | } |
| 841 | }); |
| 842 | */ |
| 843 | |
| 844 | // helper buttons |
| 845 | $('<button/>').css("margin-top", "30px").addClass("sngmbh_btn-delete").html(_x("Repair tables", 'label', 'event-tickets-with-ticket-scanner')).appendTo(DIV).on("click", ()=>{ |
| 846 | LAYOUT.renderYesNo(__('Repair database tables?', 'event-tickets-with-ticket-scanner'), __('Do you realy want to try to repair your database table definitions for the plugin? It should be safe, but only needed in very rare cases. You might see errors messages during the page reload - that is normal. Why not asking support, if you should do it? ;)', 'event-tickets-with-ticket-scanner'), dlg=>{ |
| 847 | dlg.html(_getSpinnerHTML()); |
| 848 | dlg.dialog({ |
| 849 | title:_x('Repaired', 'title', 'event-tickets-with-ticket-scanner'), modal:true, dialogClass: "no-close", |
| 850 | close: function(event, ui){ abort=true; }, |
| 851 | buttons: [ |
| 852 | { |
| 853 | text: _x('Ok', 'label', 'event-tickets-with-ticket-scanner'), |
| 854 | click: function() { |
| 855 | $( this ).dialog( _x('Close', 'label', 'event-tickets-with-ticket-scanner') ); |
| 856 | $( this ).html(''); |
| 857 | } |
| 858 | } |
| 859 | ] |
| 860 | }); |
| 861 | _makePost('repairTables', {}, result=>{ |
| 862 | speakOutLoud(result, true); |
| 863 | dlg.html(result); |
| 864 | }); |
| 865 | }); |
| 866 | }); |
| 867 | |
| 868 | function __renderTabelleErrorLogs() { |
| 869 | div_tabelle.html(_getSpinnerHTML()); |
| 870 | let table_id = myAjax.divPrefix+'_tabelle_errorlogs'; |
| 871 | let tabelle = $('<table/>').attr("id", table_id); |
| 872 | tabelle.html('<thead><tr><th></th><th align="left">'+_x('Created', 'label', 'event-tickets-with-ticket-scanner')+'</th><th align="left">'+_x('Exception', 'label', 'event-tickets-with-ticket-scanner')+'</th><th>'+_x('Function', 'label', 'event-tickets-with-ticket-scanner')+'</th></tr></thead>'); |
| 873 | div_tabelle.html(tabelle); |
| 874 | |
| 875 | let table = $('#'+table_id); |
| 876 | $(table).DataTable().clear().destroy(); |
| 877 | tabelle_errorlogs_datatable = $(table).DataTable({ |
| 878 | "responsive": true, |
| 879 | "searching": true, |
| 880 | "ordering": true, |
| 881 | "processing": true, |
| 882 | "serverSide": true, |
| 883 | "stateSave": false, |
| 884 | "pageLength":50, |
| 885 | "ajax": { |
| 886 | url: _requestURL('getErrorLogs'), |
| 887 | type: 'POST', |
| 888 | }, |
| 889 | "order": [[ 1, "desc" ]], |
| 890 | "columns":[ |
| 891 | {"data":null,"className":'details-control',"orderable":false,"defaultContent":'', "width":10}, |
| 892 | {"data":"time", "orderable":true, "width":80}, |
| 893 | {"data":"exception_msg", "orderable":true}, |
| 894 | {"data":"caller_name", "orderable":true}, |
| 895 | ] |
| 896 | }); |
| 897 | tabelle.css("width", "100%"); |
| 898 | $('#'+table_id+' tbody').on('click', 'td.details-control', e=>{ |
| 899 | var tr = $(e.target).parents('tr'); |
| 900 | var row = tabelle_errorlogs_datatable.row( tr ); |
| 901 | if ( row.child.isShown() ) { |
| 902 | // This row is already open - close it |
| 903 | row.child.hide(); |
| 904 | tr.removeClass('shown'); |
| 905 | } else { |
| 906 | // Open this row |
| 907 | let d = row.data(); |
| 908 | row.child( "#"+d.id+'<br><pre>'+destroy_tags(d.msg)+'</pre>' ).show(); |
| 909 | tr.addClass('shown'); |
| 910 | } |
| 911 | |
| 912 | }); |
| 913 | } |
| 914 | __renderTabelleErrorLogs(); |
| 915 | |
| 916 | }); |
| 917 | } |
| 918 | |
| 919 | /** |
| 920 | * returns 0 if the versions are the same, 1 if version1 is greater, -1 if version2 is greater |
| 921 | */ |
| 922 | function compareVersions(version1, version2) { |
| 923 | const v1 = version1.split('.').map(Number); |
| 924 | const v2 = version2.split('.').map(Number); |
| 925 | |
| 926 | for (let i = 0; i < Math.max(v1.length, v2.length); i++) { |
| 927 | const num1 = v1[i] || 0; |
| 928 | const num2 = v2[i] || 0; |
| 929 | |
| 930 | if (num1 > num2) return 1; |
| 931 | if (num1 < num2) return -1; |
| 932 | } |
| 933 | |
| 934 | /* |
| 935 | // Example usage: |
| 936 | const result = compareVersions('5.8.1', '5.8.2'); |
| 937 | if (result > 0) { |
| 938 | console.log('Version 5.8.1 is greater than 5.8.2'); |
| 939 | } else if (result < 0) { |
| 940 | console.log('Version 5.8.1 is less than 5.8.2'); |
| 941 | } else { |
| 942 | console.log('Both versions are equal'); |
| 943 | } |
| 944 | */ |
| 945 | |
| 946 | return 0; |
| 947 | } |
| 948 | |
| 949 | function _displayOptionsArea() { |
| 950 | STATE = 'options'; |
| 951 | DIV.html(_getSpinnerHTML()); |
| 952 | getOptionsFromServer(reply=>{ |
| 953 | let data = reply.options; // options values |
| 954 | let meta_tags_keys = reply.meta_tags_keys; |
| 955 | |
| 956 | DIV.html(getBackButtonDiv()); |
| 957 | |
| 958 | // Create tabs |
| 959 | let tabs = $('<div class="tabs"/>'); |
| 960 | let tabOptions = $('<div id="tab-options" class="tab-content"/>'); |
| 961 | |
| 962 | // Create tab navigation |
| 963 | let tabNav = $('<ul class="tab-nav"/>'); |
| 964 | tabNav.append('<li><a href="#tab-options">Options</a></li>'); |
| 965 | if (isPremium() && typeof PREMIUM.displayOptionsArea_Templates !== "undefined") { |
| 966 | tabNav.append(PREMIUM.displayOptionsArea_Tab); |
| 967 | } |
| 968 | |
| 969 | tabs.append(tabNav); |
| 970 | tabs.append(tabOptions); |
| 971 | if (isPremium() && typeof PREMIUM.displayOptionsArea_Templates !== "undefined") { |
| 972 | //if (BASIC._compareVersions(prem_version, '1.5.0') < 0) { // check the version |
| 973 | // div_template.append("This is a premium feature is available with Premium Version 1.5.0. You need to update your premium plugin."); |
| 974 | //} |
| 975 | tabs.append(PREMIUM.displayOptionsArea_Templates(_getOptions_Versions_getByKey('premium'))); |
| 976 | } |
| 977 | DIV.append(tabs); |
| 978 | |
| 979 | // Populate Options tab |
| 980 | let div_options = $('<div/>'); |
| 981 | let div_infos = $('<div style="padding-top: 50px;"/>'); |
| 982 | let resetOption_div = $('<div class="reset_option_wrap" style="padding-top: 20px;"/>'); |
| 983 | tabOptions.append(div_options); |
| 984 | tabOptions.append('<hr>'); |
| 985 | tabOptions.append(resetOption_div); |
| 986 | $('<button class="button reset_btn_actn">').html(_x('Reset All Options', 'label', 'event-tickets-with-ticket-scanner')) |
| 987 | .on('click', ()=>{ |
| 988 | LAYOUT.renderYesNo(_x('Reset All Options', 'title', 'event-tickets-with-ticket-scanner'), __('Do you really want to reset all the option?', 'event-tickets-with-ticket-scanner'), ()=>{ |
| 989 | _makePost('resetOptions','', function(result) { |
| 990 | if(result){ |
| 991 | _displayOptionsArea(); |
| 992 | } |
| 993 | }); |
| 994 | }); |
| 995 | }).appendTo(resetOption_div); |
| 996 | tabOptions.append(div_infos); |
| 997 | div_infos.append('<a name="replacementtags"></a><h3>'+_x('Replacement Tags', 'title', 'event-tickets-with-ticket-scanner')+'</h3>').append('<p>'+__('You can use these replacement tags in your text messages and URLs for the meta ticket values', 'event-tickets-with-ticket-scanner')+'</p>'); |
| 998 | meta_tags_keys.forEach(v=>{ |
| 999 | let t = '<p><b>{'+v.key+'}</b>: '+v.label+'</p>'; |
| 1000 | div_infos.append(t); |
| 1001 | }); |
| 1002 | |
| 1003 | //div_options.append('<h3>'+_x('Options', 'title', 'event-tickets-with-ticket-scanner')+'</h3>'); |
| 1004 | div_options.append('<p><span class="dashicons dashicons-external"></span><a href="https://vollstart.com/event-tickets-with-ticket-scanner/docs/" target="_blank">Click here, to visit the documentation.</a></p>'); |
| 1005 | div_options.append(getUseFulVideosHTML()); |
| 1006 | |
| 1007 | let menu_band = $('<div style="padding-top:10px;padding-bottom:15px;">').appendTo(div_options); |
| 1008 | let menu_values = []; |
| 1009 | data.forEach(v=>{ |
| 1010 | if (v.type === "heading") { |
| 1011 | menu_values.push(v); |
| 1012 | } |
| 1013 | }); |
| 1014 | menu_values.sort((a,b)=>{ |
| 1015 | if(a.label < b.label) { return -1; } |
| 1016 | if(a.label > b.label) { return 1; } |
| 1017 | return 0; |
| 1018 | }); |
| 1019 | menu_values.forEach(v=>{ |
| 1020 | $('<a href="#'+v.key+'" style="padding:5px;padding-left:0;margin-right:10px;">').html(v.label).appendTo(menu_band); |
| 1021 | }); |
| 1022 | $('<a href="#topMenu" style="text-decoration:none;position:fixed;bottom:50px;right:10px;background-color:#b225cb;color:white;border-radius:15px;border:1 px solid blue;display:inline-block;padding:10px;">').html('<i class="dashicons dashicons-arrow-up"></i> Top').appendTo(div_options); |
| 1023 | |
| 1024 | // Add jQuery for tab functionality |
| 1025 | $('.tab-nav a').on('click', function(e) { |
| 1026 | e.preventDefault(); |
| 1027 | $('.tab-content').hide(); |
| 1028 | $($(this).attr('href')).show(); |
| 1029 | $('.tab-nav a').removeClass('active'); |
| 1030 | $(this).addClass('active'); |
| 1031 | }); |
| 1032 | |
| 1033 | // Show the first tab by default |
| 1034 | if (typeof PARAS.subdisplay !== "undefined" && PARAS.subdisplay == 'templates') { |
| 1035 | $('.tab-nav a').eq(1).click(); |
| 1036 | } else { |
| 1037 | $('.tab-nav a:first').click(); |
| 1038 | } |
| 1039 | |
| 1040 | function __createTicketTemplateChooserBox(ticket_template, editor) { |
| 1041 | return $('<div style="width:250px;display:inline-block;margin-right:5px;text-align:center;">') |
| 1042 | .append('<img style="width:250px;" src="'+myAjax._plugin_home_url+'/img/ticket_templates/'+ticket_template.image_url+'">') |
| 1043 | .append("<br>Zero-Padding: "+(ticket_template.wcTicketPDFZeroMarginTest ? "Yes" : "No")) |
| 1044 | .append(", Size: ("+ticket_template.wcTicketSizeWidthTest+'x'+ticket_template.wcTicketSizeHeightTest+")") |
| 1045 | .append("<br>") |
| 1046 | .append($('<button class="button button-primary">').text(__('Load template','event-tickets-with-ticket-scanner')).on("click", ()=>{ |
| 1047 | LAYOUT.renderYesNo(_x('Load Template Ticket Code', 'title', 'event-tickets-with-ticket-scanner'), |
| 1048 | __('Do you want to replace the test ticket template code with this template?', 'event-tickets-with-ticket-scanner')+'<br><p><img style="width:250px;" src="'+myAjax._plugin_home_url+'/img/ticket_templates/'+ticket_template.image_url+'"></p><p>Following values will be changed:' |
| 1049 | +'<br><b>wcTicketPDFZeroMarginTest</b>: '+(ticket_template.wcTicketPDFZeroMarginTest ? "Yes" : "No") |
| 1050 | +'<br><b>wcTicketPDFisRTLTest</b>: '+(ticket_template.wcTicketPDFisRTLTest ? "Yes" : "No") |
| 1051 | +'<br><b>wcTicketSizeWidthTest</b>: '+ticket_template.wcTicketSizeWidthTest |
| 1052 | +'<br><b>wcTicketSizeHeightTest</b>: '+ticket_template.wcTicketSizeHeightTest |
| 1053 | +'<br><b>wcTicketQRSizeTest</b>: '+ticket_template.wcTicketQRSizeTest |
| 1054 | +'</p>' |
| 1055 | , ()=>{ |
| 1056 | editor.wcTicketDesignerTemplateTest_editor.setValue(ticket_template.wcTicketDesignerTemplateTest); |
| 1057 | $('input[data-key="wcTicketPDFZeroMarginTest"').prop("checked",ticket_template.wcTicketPDFZeroMarginTest).trigger("change"); |
| 1058 | $('input[data-key="wcTicketPDFisRTLTest"').prop("checked",ticket_template.wcTicketPDFisRTLTest).trigger("change"); |
| 1059 | $('input[data-key="wcTicketSizeWidthTest"').val(ticket_template.wcTicketSizeWidthTest).trigger("change"); |
| 1060 | $('input[data-key="wcTicketSizeHeightTest"').val(ticket_template.wcTicketSizeHeightTest).trigger("change"); |
| 1061 | $('input[data-key="wcTicketQRSizeTest"').val(ticket_template.wcTicketQRSizeTest).trigger("change"); |
| 1062 | let value = editor.wcTicketDesignerTemplateTest_editor.getValue().trim(); |
| 1063 | __saveOptionValue("wcTicketDesignerTemplateTest", value); |
| 1064 | editor.wcTicketDesignerTemplateTest_btn.prop("disabled", true); |
| 1065 | |
| 1066 | }); |
| 1067 | })); |
| 1068 | } |
| 1069 | |
| 1070 | // render die input felder |
| 1071 | function __getOptionByKey(key) { |
| 1072 | for(let a=0;a<data.length;a++) { |
| 1073 | if (key == data[a].key) return data[a]; |
| 1074 | } |
| 1075 | return null; |
| 1076 | } |
| 1077 | function __saveOptionValue(key, value, cbf, pcbf) { |
| 1078 | _makePost('changeOption', {'key':key, 'value':value}, |
| 1079 | ()=>{ |
| 1080 | cbf && cbf(); |
| 1081 | if (key == "wcTicketDesignerTemplateTest") { |
| 1082 | $("#wcTicketDesignerTemplateTest_button_PDF").prop("disabled", false).text(__('Preview Test Template Code as PDF', 'event-tickets-with-ticket-scanner')); |
| 1083 | } |
| 1084 | }, null, |
| 1085 | ()=>{ |
| 1086 | pcbf && pcbf(); |
| 1087 | if (key == "wcTicketDesignerTemplateTest") { |
| 1088 | $("#wcTicketDesignerTemplateTest_button_PDF").prop("disabled", true).text(__('saving...', 'event-tickets-with-ticket-scanner')); |
| 1089 | } |
| 1090 | }); |
| 1091 | |
| 1092 | } |
| 1093 | |
| 1094 | let editor = {}; // for ace editor |
| 1095 | data.forEach(v=>{ |
| 1096 | if (typeof v.additional !== "undefined" && v.additional.doNotRender) return; |
| 1097 | if (v.type == "heading") { |
| 1098 | let desc = v.desc; |
| 1099 | if (typeof v._doc_video !== "undefined" && v._doc_video != "") { |
| 1100 | desc += ' <span class="dashicons dashicons-external"></span> <a href="'+v._doc_video+'" target="_blank">Video Help</a>'; |
| 1101 | } |
| 1102 | div_options.append('<hr>').append('<h3 id="'+v.key+'" '+(desc !== "" ? ' style="margin-bottom:0;"' : '')+'>'+v.label+'</h3>').append(desc !== "" ? '<div style="margin-bottom:15px;"><i>'+desc+'</i></div>':''); |
| 1103 | } else if (v.type =="desc") { |
| 1104 | let desc = v.desc+" "; |
| 1105 | if (typeof v._do_not_trim !== "undefined" && v._do_not_trim) { |
| 1106 | desc += 'To leave this value blank, enter a space. '; |
| 1107 | } |
| 1108 | if (typeof v._doc_video !== "undefined" && v._doc_video != "") { |
| 1109 | desc += '<span class="dashicons dashicons-external"></span> <a href="'+v._doc_video+'" target="_blank">Video Help</a>'; |
| 1110 | } |
| 1111 | div_options.append('<div/>').css({"margin-bottom": "15px","margin-right": "15px"}).append('<b>'+v.label+'</b><br>'+desc+"<br>"); |
| 1112 | } else { |
| 1113 | let elem_div = $('<div/>').css({"margin-bottom": "15px","margin-right": "15px"}); |
| 1114 | let elem_input = $('<input type="'+v.type+'">'); |
| 1115 | elem_input.attr("placeholder", v.default); |
| 1116 | if (typeof v.additional !== "undefined" && typeof v.additional.disabled !== "undefined") { |
| 1117 | elem_input.attr("disabled", true); |
| 1118 | } |
| 1119 | |
| 1120 | let cbf = null; |
| 1121 | let pcbf = null; |
| 1122 | let value = v.value; |
| 1123 | if (typeof v._do_not_trim !== "undefined" && v._do_not_trim) { |
| 1124 | } else { |
| 1125 | value = (""+v.value) !== "" ? (""+v.value).trim() : ""+v.default; |
| 1126 | } |
| 1127 | |
| 1128 | v.label = v.label + ' <span style="color:grey;">{'+v.key+'}</span>'; |
| 1129 | if (typeof v._doc_video !== "undefined" && v._doc_video != "") { |
| 1130 | v.label += ' <span class="dashicons dashicons-external"></span> <a href="'+v._doc_video+'" target="_blank">Video Help</a>'; |
| 1131 | } |
| 1132 | |
| 1133 | switch (v.type) { |
| 1134 | case "editor": |
| 1135 | elem_input = $('<div id="'+v.key+'_editor" style="height:'+(typeof v.additional !== "undefined" && typeof v.additional.height !== "undefined" ? v.additional.height : '500px')+';">').text(value.trim()); |
| 1136 | break; |
| 1137 | case "textarea": |
| 1138 | elem_input = $('<textarea>'); |
| 1139 | elem_input.attr("placeholder", v.default); |
| 1140 | //elem_input.val(value); |
| 1141 | elem_input.val(value); |
| 1142 | if (typeof v.additional !== "undefined" && typeof v.additional.rows !== "undefined") { |
| 1143 | elem_input.attr("rows", v.additional.rows); |
| 1144 | } |
| 1145 | break; |
| 1146 | case "checkbox": |
| 1147 | v.value = intval(v.value); |
| 1148 | elem_input.prop("checked",v.value === 1 ? true : false); |
| 1149 | elem_input.on("change", function(){ |
| 1150 | _makePost('changeOption', {'key':v.key, 'value':elem_input[0].checked ? 1:0}); |
| 1151 | }); |
| 1152 | elem_div.html(elem_input).append(v.label).append(v.desc !== "" ? '<br><i>'+v.desc+'</i>':''); |
| 1153 | break; |
| 1154 | case "number": |
| 1155 | if (typeof v.additional.min !== "undefined") elem_input.attr("min", v.additional.min); |
| 1156 | break; |
| 1157 | case "dropdown": |
| 1158 | elem_input = $('<select>'); |
| 1159 | if (v.additional.multiple) { |
| 1160 | elem_input.prop("multiple", true); |
| 1161 | } |
| 1162 | v.additional.values.forEach(_v=>{ |
| 1163 | $('<option>').attr("value", _v.value).html(_v.label).appendTo(elem_input); |
| 1164 | }); |
| 1165 | if (v.additional.multiple) { |
| 1166 | if (v.value.length == 0) { |
| 1167 | value = v.default; |
| 1168 | } else { |
| 1169 | value = v.value; |
| 1170 | } |
| 1171 | } else { |
| 1172 | if (value == "") value = 1; |
| 1173 | } |
| 1174 | elem_input.val(value); |
| 1175 | break; |
| 1176 | case "media": |
| 1177 | let image_info = $('<div>'); |
| 1178 | let image = $('<image style="display:none;">'); |
| 1179 | let image_btn_del = $('<button class="sngmbh_btn sngmbh_btn-delete" style="display:none;">').html(_x('Remove file', 'label', 'event-tickets-with-ticket-scanner')); |
| 1180 | image_btn_del.on('click', ()=>{ |
| 1181 | LAYOUT.renderYesNo(_x('Remove file', 'title', 'event-tickets-with-ticket-scanner'), __('Do you really want to remove the file information from this option?', 'event-tickets-with-ticket-scanner'), ()=>{ |
| 1182 | elem_input.val(""); |
| 1183 | elem_input.trigger("change"); |
| 1184 | _renderMedia(0, v, image_info, image, image_btn_del); |
| 1185 | }); |
| 1186 | }); |
| 1187 | if (typeof v.additional == "undefined") v.additional = {}; |
| 1188 | if (v.additional.max) { |
| 1189 | if (v.additional.max.width) { |
| 1190 | image.css("max-width", v.additional.max.width+'px'); |
| 1191 | } |
| 1192 | if (v.additional.max.height) { |
| 1193 | image.css("max-height", v.additional.max.height+'px'); |
| 1194 | } |
| 1195 | } |
| 1196 | elem_input.attr("type", "hidden"); |
| 1197 | let image_btn_add = $('<button style="display:block;" />').addClass("button-primary") |
| 1198 | .html(v.additional.button) |
| 1199 | .on("click", ()=>{ |
| 1200 | let is_multiple = typeof v.additional.is_multiple != "undefined" ? v.additional.is_multiple : false; |
| 1201 | let imgContainer = null; |
| 1202 | let type_filter = typeof v.additional.type_filter != "undefined" ? v.additional.type_filter : null; |
| 1203 | _openMediaChooser(elem_input, is_multiple, imgContainer, type_filter); |
| 1204 | }); |
| 1205 | $('<div/>').css({"margin-bottom": "15px","margin-right": "15px"}) |
| 1206 | .html(v.label+'<br>') |
| 1207 | .append(image_btn_add) |
| 1208 | .append(v.desc !== "" ? '<i>'+v.desc+'</i>':'') |
| 1209 | .append(elem_input) |
| 1210 | .append(image_info) |
| 1211 | .append(image) |
| 1212 | .append(image_btn_del) |
| 1213 | .appendTo(elem_div); |
| 1214 | _renderMedia(value, v, image_info, image, image_btn_del); |
| 1215 | pcbf = function() { |
| 1216 | image_info.html(_getSpinnerHTML()); |
| 1217 | image.css('display', 'none'); |
| 1218 | } |
| 1219 | cbf = function () { |
| 1220 | let value = elem_input.val(); |
| 1221 | _renderMedia(value, v, image_info, image, image_btn_del); |
| 1222 | } |
| 1223 | break; |
| 1224 | } |
| 1225 | |
| 1226 | if (v.type != "checkbox") { |
| 1227 | if (v.type != "media") { |
| 1228 | elem_div.html(v.label+'<br>').append(elem_input); |
| 1229 | let desc = v.desc+" "; |
| 1230 | if (typeof v._do_not_trim !== "undefined" && v._do_not_trim) { |
| 1231 | desc += 'To leave this value blank, enter a space. '; |
| 1232 | } |
| 1233 | desc = desc.trim(); |
| 1234 | elem_div.append(desc !== "" ? '<br><i>'+desc+'</i>':''); |
| 1235 | } |
| 1236 | if (v.type != "number") { |
| 1237 | elem_input.css({"width":"90%"}); |
| 1238 | } |
| 1239 | if (v.type != "dropdown" && v.type != "editor") { |
| 1240 | elem_input.attr("value",value); |
| 1241 | } |
| 1242 | if (v.type != "editor") { |
| 1243 | elem_input.on("change", ()=>{ |
| 1244 | let value = elem_input.val(); |
| 1245 | __saveOptionValue(v.key, value, cbf, pcbf); |
| 1246 | }); |
| 1247 | } |
| 1248 | } |
| 1249 | |
| 1250 | elem_input.attr("data-key", v.key); |
| 1251 | |
| 1252 | if (v.key == "wcassignmentUseGlobalSerialFormatter") { |
| 1253 | let option = __getOptionByKey('wcassignmentUseGlobalSerialFormatter_values'); |
| 1254 | let formatterValues = null; |
| 1255 | if (option.value != "") { |
| 1256 | try { |
| 1257 | formatterValues = JSON.parse(option.value); |
| 1258 | } catch (e) { |
| 1259 | //console.log(e); |
| 1260 | } |
| 1261 | } |
| 1262 | let extra_div = $('<div>').appendTo(elem_div).css("margin-top", "10px").css("margin-left", "50px").css("padding", "10px").css("border", "1px solid black"); |
| 1263 | // render here den formatter |
| 1264 | let serialCodeFormatter = _form_fields_serial_format(extra_div); |
| 1265 | serialCodeFormatter.setNoNumberOptions(); |
| 1266 | serialCodeFormatter.setFormatterValues(formatterValues); |
| 1267 | serialCodeFormatter.setCallbackHandle(_formatterValues=>{ |
| 1268 | // speicher formatterValues |
| 1269 | _makePost('changeOption', {'key':'wcassignmentUseGlobalSerialFormatter_values', 'value':JSON.stringify(_formatterValues)}); |
| 1270 | }); |
| 1271 | serialCodeFormatter.render(); |
| 1272 | } |
| 1273 | |
| 1274 | if (v.key == "wcTicketDesignerTemplate") { |
| 1275 | $('<button class="button button-primary">').html("Show Default Template").on("click", e=>{ |
| 1276 | LAYOUT.renderInfoBox(_x('Ticket Default Template', 'title', 'event-tickets-with-ticket-scanner'), $('<textarea style="width:100%;height:400px">').val(v.default)); |
| 1277 | }).appendTo(div_options); |
| 1278 | } |
| 1279 | |
| 1280 | if (v.type == "editor") { |
| 1281 | //https://ace.c9.io/#nav=howto |
| 1282 | let btn_group = $('<div>').prependTo(elem_div); |
| 1283 | editor[v.key+"_editor"] = null; // will be filled later |
| 1284 | editor[v.key+"_btn"] = $('<button class="button button-primary">').prop("disabled", true).html(_x('Save Template Code', 'title', 'event-tickets-with-ticket-scanner')).on("click", evt=>{ |
| 1285 | let value = editor[v.key+"_editor"].getValue().trim(); |
| 1286 | __saveOptionValue(v.key, value, cbf, pcbf); |
| 1287 | editor[v.key+"_btn"].prop("disabled", true); |
| 1288 | }).appendTo(btn_group); |
| 1289 | $('<button class="button button-danger">').html(_x('Copy Template Code To Live Code', 'title', 'event-tickets-with-ticket-scanner')).on("click", evt=>{ |
| 1290 | LAYOUT.renderYesNo(_x('Replace Live Template Code', 'title', 'event-tickets-with-ticket-scanner'), __('Do you want to replace the live template code with the template code from the test?', 'event-tickets-with-ticket-scanner'), ()=>{ |
| 1291 | let value = editor[v.key+"_editor"].getValue().trim(); |
| 1292 | $('input[data-key="'+v.key.replace("Test", "")+'"').val(value).trigger("change"); |
| 1293 | if (v.key == "wcTicketDesignerTemplateTest") { |
| 1294 | $('input[data-key="wcTicketPDFZeroMargin"').prop("checked",$('input[data-key="wcTicketPDFZeroMarginTest"').is(':checked')).trigger("change"); |
| 1295 | $('input[data-key="wcTicketPDFisRTL"').prop("checked",$('input[data-key="wcTicketPDFisRTLTest"').is(':checked')).trigger("change"); |
| 1296 | $('input[data-key="wcTicketSizeWidth"').val($('input[data-key="wcTicketSizeWidthTest"').val()).trigger("change"); |
| 1297 | $('input[data-key="wcTicketSizeHeight"').val($('input[data-key="wcTicketSizeHeightTest"').val()).trigger("change"); |
| 1298 | $('input[data-key="wcTicketQRSize"').val($('input[data-key="wcTicketQRSizeTest"').val()).trigger("change"); |
| 1299 | } |
| 1300 | }); |
| 1301 | }).appendTo(btn_group); |
| 1302 | |
| 1303 | if (v.key == "wcTicketDesignerTemplateTest") { |
| 1304 | let ticket_test_chooser = $('<div>'); |
| 1305 | let ticket_template_chooser = $('<div style="padding-top:5px;padding-bottom:20px;">').html('<b>Templates</b><br>You can choose from the templates below to have a starting point.<br>').appendTo(ticket_test_chooser); |
| 1306 | let ticket_test_select = $('<select>').appendTo(ticket_test_chooser); |
| 1307 | let ticket_test_direct_input = $('<input type="text" style="width:180px;" placeholder="or enter a public ticket number">'); |
| 1308 | // display the template thumbnails |
| 1309 | for(let a=0;a<reply.ticket_templates.length;a++) { |
| 1310 | let ticket_template = reply.ticket_templates[a]; |
| 1311 | __createTicketTemplateChooserBox(ticket_template, editor).appendTo(ticket_template_chooser); |
| 1312 | } |
| 1313 | |
| 1314 | if (OPTIONS.tickets_for_testing.length > 0) { |
| 1315 | let option_values = []; |
| 1316 | for(let a=0;a<OPTIONS.tickets_for_testing.length;a++) { |
| 1317 | let ticket = OPTIONS.tickets_for_testing[a]; |
| 1318 | let metaObj = null; |
| 1319 | try { |
| 1320 | metaObj = JSON.parse(ticket.meta); |
| 1321 | } catch(e) {} |
| 1322 | if (metaObj != null) { |
| 1323 | option_values.push({t:ticket, m:metaObj}); |
| 1324 | } |
| 1325 | } |
| 1326 | if (option_values.length > 0) { |
| 1327 | for(let a=0;a<option_values.length;a++) { |
| 1328 | let item = option_values[a]; |
| 1329 | $('<option value="'+item.m.wc_ticket._public_ticket_id+'">') |
| 1330 | .text("Order Id: "+item.t.order_id+" - "+item.m.wc_ticket._public_ticket_id+" - "+item.t._PRODUCT_NAME+" (#"+item.m.woocommerce.product_id+")") |
| 1331 | .attr("data-url-pdf", item.m.wc_ticket._url) |
| 1332 | .appendTo(ticket_test_select); |
| 1333 | } |
| 1334 | ticket_test_direct_input.appendTo(ticket_test_chooser); |
| 1335 | $('<button class="button button-primary" id="wcTicketDesignerTemplateTest_button_PDF">') |
| 1336 | .html(__('Preview Test Template Code as PDF', 'event-tickets-with-ticket-scanner')). |
| 1337 | appendTo(ticket_test_chooser).on("click", ()=>{ |
| 1338 | let ticket_url = ticket_test_select.find(":selected").attr("data-url-pdf"); |
| 1339 | let v = ticket_test_direct_input.val().trim(); |
| 1340 | if (v != "") { |
| 1341 | ticket_url = reply.infos.ticket.ticket_base_url + v; // myAjax.ticket_base_url |
| 1342 | } |
| 1343 | iframe.attr("src", ticket_url+'?pdf&testDesigner=1&t='+time()+'&nonce='+DATA.nonce); |
| 1344 | iframe |
| 1345 | .css("width", "80%") |
| 1346 | .css("height", "500px") |
| 1347 | .css("margin-top", "10px") |
| 1348 | .css("display", "block"); |
| 1349 | }); |
| 1350 | let iframe = $('<iframe style="display:none;">').appendTo(ticket_test_chooser); |
| 1351 | } else { |
| 1352 | $('<option value="">').text(__("ticket cannot be used. Public Ticket Id missing.",'event-tickets-with-ticket-scanner')).appendTo(ticket_test_select); |
| 1353 | } |
| 1354 | } else { |
| 1355 | $('<option value="">').text(__("no ticket for preview available", 'event-tickets-with-ticket-scanner')).appendTo(ticket_test_select); |
| 1356 | } |
| 1357 | ticket_test_chooser.appendTo(elem_div); |
| 1358 | } |
| 1359 | } |
| 1360 | |
| 1361 | elem_div.appendTo(div_options); |
| 1362 | } |
| 1363 | }); |
| 1364 | if (window.location.hash != "") { |
| 1365 | window.setTimeout(()=>{ |
| 1366 | let h = window.location.hash; |
| 1367 | window.location.hash = ""; |
| 1368 | window.location.hash = h; |
| 1369 | }, 250); |
| 1370 | } |
| 1371 | window.setTimeout(()=>{ |
| 1372 | for(var k in editor) { |
| 1373 | if (k.substring(k.length -7) == "_editor") { |
| 1374 | editor[k] = ace.edit(k); |
| 1375 | //editor.wcTicketDesignerTemplateTest_editor.setTheme("ace/theme/monokai"); |
| 1376 | editor[k].session.setMode("ace/mode/twig"); |
| 1377 | editor[k].setShowPrintMargin(false); |
| 1378 | editor[k].commands.addCommand({name:'save', bindKey:{win:'Ctrl-S', mac:'Command-S'}, readOnly:false, exec:myEditor=>{ |
| 1379 | myEditor.trigger("change"); |
| 1380 | }}); |
| 1381 | editor[k].session.on("change", delta=>{ |
| 1382 | editor[k.replace("_editor", "_btn")].prop("disabled", false); |
| 1383 | }); |
| 1384 | } |
| 1385 | } |
| 1386 | }, 250) |
| 1387 | |
| 1388 | }); |
| 1389 | } |
| 1390 | |
| 1391 | function getSuffixFromFilename(filename) { |
| 1392 | let extension = filename.slice(filename.lastIndexOf('.') + 1); |
| 1393 | return extension; |
| 1394 | } |
| 1395 | function _renderMedia(mediaId, v, image_info, image, image_btn_del) { |
| 1396 | if (mediaId != "" && parseInt(mediaId) != 0) { |
| 1397 | _getMediaData(mediaId, data=>{ |
| 1398 | let suffix = getSuffixFromFilename(data.url.replace(/^.*[\\\/]/,'')).toLowerCase(); |
| 1399 | let info = suffix != "pdf" ? '('+data.meta.width+'x'+data.meta.height+')' : ''; |
| 1400 | image_info.html('<b>'+_x('Title', 'title', 'event-tickets-with-ticket-scanner')+':</b> '+data.title+' '+info); |
| 1401 | if (v.additional.max && v.additional.msg_error_max) { |
| 1402 | if (v.additional.max.width && v.additional.msg_error_max.width && data.meta.width > v.additional.max.width) image_info.append('<div style="color:red;">'+v.additional.msg_error_max.width+'</div>'); |
| 1403 | if (v.additional.max.height && v.additional.msg_error_max.height && data.meta.height > v.additional.max.height) image_info.append('<div style="color:red;">'+v.additional.msg_error_max.height+'</div>'); |
| 1404 | } |
| 1405 | if (suffix != "pdf") { |
| 1406 | image.attr("src", data.url).css("display","block"); |
| 1407 | } |
| 1408 | image_btn_del.css("display", "block"); |
| 1409 | }); |
| 1410 | } else { |
| 1411 | image_info.html(""); |
| 1412 | image.css("display", "none"); |
| 1413 | image_btn_del.css("display", "none"); |
| 1414 | } |
| 1415 | } |
| 1416 | function _openMediaChooser(input_elem, multiple, imgContainer, typeFilter) { |
| 1417 | var image_frame; |
| 1418 | if(image_frame){ |
| 1419 | image_frame.open(); |
| 1420 | } |
| 1421 | if (!typeFilter) typeFilter = 'image'; |
| 1422 | multiple ? multiple = true : multiple = false; |
| 1423 | // Define image_frame as wp.media object |
| 1424 | image_frame = wp.media({ |
| 1425 | title: _x('Select Media', 'title', 'event-tickets-with-ticket-scanner'), |
| 1426 | multiple : multiple, |
| 1427 | library : { |
| 1428 | type : typeFilter, |
| 1429 | } |
| 1430 | }); |
| 1431 | |
| 1432 | image_frame.on('close',function() { |
| 1433 | // On close, get selections and save to the hidden input |
| 1434 | // plus other AJAX stuff to refresh the image preview |
| 1435 | var selection = image_frame.state().get('selection'); |
| 1436 | |
| 1437 | if (imgContainer) { // zeige erstes bild an |
| 1438 | var attachment = selection.first().toJSON(); |
| 1439 | imgContainer.html( '<img src="'+attachment.url+'" style="max-width:100%;"/>' ); |
| 1440 | } |
| 1441 | |
| 1442 | var gallery_ids = new Array(); |
| 1443 | var my_index = 0; |
| 1444 | selection.each(function(attachment) { |
| 1445 | gallery_ids[my_index] = attachment['id']; |
| 1446 | my_index++; |
| 1447 | }); |
| 1448 | var ids = gallery_ids.join(","); |
| 1449 | input_elem.val(ids); |
| 1450 | input_elem.trigger("change"); |
| 1451 | }); |
| 1452 | |
| 1453 | image_frame.on('open',function() { |
| 1454 | // On open, get the id from the hidden input |
| 1455 | // and select the appropiate images in the media manager |
| 1456 | var selection = image_frame.state().get('selection'); |
| 1457 | var ids = input_elem.val().split(','); |
| 1458 | ids.forEach(function(id) { |
| 1459 | var attachment = wp.media.attachment(id); |
| 1460 | attachment.fetch(); |
| 1461 | selection.add( attachment ? [ attachment ] : [] ); |
| 1462 | }); |
| 1463 | }); |
| 1464 | image_frame.open(); |
| 1465 | } // ende openmediachooser |
| 1466 | |
| 1467 | function getBackButtonDiv() { |
| 1468 | let div_buttons = $('<div style="display:flex;justify-content:space-between;">'); |
| 1469 | let div = $('<div/>').append($('<button/>').addClass("button-primary").html(_x('Back', 'label', 'event-tickets-with-ticket-scanner')).css("margin-bottom", "10px").on("click", function(){ |
| 1470 | LAYOUT.renderAdminPageLayout(); |
| 1471 | })); |
| 1472 | div_buttons.append(div); |
| 1473 | div_buttons.append(_displaySettingAreaButton()); |
| 1474 | return div_buttons; |
| 1475 | } |
| 1476 | |
| 1477 | function _getTicketScannerURL() { |
| 1478 | let url = _getOptions_Infos_getByKey('ticket').ticket_scanner_path; |
| 1479 | let _urlpath = _getOptions_getValByKey("wcTicketCompatibilityModeURLPath"); |
| 1480 | if (_urlpath != "") { |
| 1481 | url = OPTIONS.infos.site.home+"/"+_urlpath+'/scanner/'; |
| 1482 | } else { |
| 1483 | url = OPTIONS.infos.ticket.ticket_scanner_url; |
| 1484 | } |
| 1485 | return url; |
| 1486 | } |
| 1487 | function _displaySettingAreaButton() { |
| 1488 | let btn_grp = $('<div id="topMenu"/>').addClass("btn-group"); |
| 1489 | $('<button/>').addClass("button-primary").html(_x("Support Info", 'label', 'event-tickets-with-ticket-scanner')) |
| 1490 | .on("click", ()=>{ |
| 1491 | _displaySupportInfoArea(); |
| 1492 | }) |
| 1493 | .appendTo(btn_grp); |
| 1494 | $('<button/>').addClass("button-primary").html(_x("FAQ", 'label', 'event-tickets-with-ticket-scanner')) |
| 1495 | .on("click", ()=>{ |
| 1496 | _displayFAQArea(); |
| 1497 | }) |
| 1498 | .appendTo(btn_grp); |
| 1499 | if (typeof PARAS.seatingplan !== "undefined" && PARAS.seatingplan) { |
| 1500 | $('<button/>').addClass("button-primary").html(_x("Seating Plans", 'label', 'event-tickets-with-ticket-scanner')) |
| 1501 | .on("click", ()=>{ |
| 1502 | _displaySeatingplanArea(); |
| 1503 | }) |
| 1504 | .appendTo(btn_grp); |
| 1505 | } |
| 1506 | //if (_getOptions_Versions_isActivatedByKey('is_wc_available')) { |
| 1507 | $('<button/>').addClass("button-primary").html(_x("Ticket Scanner", 'label', 'event-tickets-with-ticket-scanner')) |
| 1508 | .on("click", ()=>{ |
| 1509 | let url = _getTicketScannerURL(); |
| 1510 | window.open(url, 'ticketscanner'); |
| 1511 | }) |
| 1512 | .appendTo(btn_grp); |
| 1513 | //} |
| 1514 | $('<button/>').addClass("button-primary").html(_x('Auth Token', 'label', 'event-tickets-with-ticket-scanner')) |
| 1515 | .on("click", ()=>{ |
| 1516 | _displayAuthTokensArea(); |
| 1517 | }) |
| 1518 | .appendTo(btn_grp); |
| 1519 | $('<button/>').addClass("button-primary").html(_x('Options', 'label', 'event-tickets-with-ticket-scanner')) |
| 1520 | .on("click", ()=>{ |
| 1521 | _displayOptionsArea(); |
| 1522 | }) |
| 1523 | .appendTo(btn_grp); |
| 1524 | if (isPremium()) { |
| 1525 | btn_grp = PREMIUM.displaySettingAreaButton(btn_grp); |
| 1526 | } |
| 1527 | return btn_grp; |
| 1528 | } |
| 1529 | |
| 1530 | function _form_fields_serial_format(appendToDiv) { |
| 1531 | let input_prefix_codes; |
| 1532 | let input_type_codes; |
| 1533 | let input_amount_letters; |
| 1534 | let input_letter_excl; |
| 1535 | let input_letter_style; |
| 1536 | let input_include_numbers; |
| 1537 | let input_serial_delimiter; |
| 1538 | let input_serial_delimiter_space; |
| 1539 | let input_number_start; |
| 1540 | let input_number_offset; |
| 1541 | |
| 1542 | let noNumbersOptions = false; |
| 1543 | let cbk = null; |
| 1544 | let formatterValues; |
| 1545 | |
| 1546 | function _setNoNumberOptions() { |
| 1547 | noNumbersOptions = true; |
| 1548 | } |
| 1549 | function _setCallbackHandle(_cbk) { |
| 1550 | cbk = _cbk; |
| 1551 | } |
| 1552 | function _callCallbackHandle() { |
| 1553 | cbk && cbk(_getFormatterValues()); |
| 1554 | } |
| 1555 | function _setFormatterValues(values) { |
| 1556 | formatterValues = values; |
| 1557 | } |
| 1558 | |
| 1559 | function __render() { |
| 1560 | $('<br>').appendTo(appendToDiv); |
| 1561 | // prefix |
| 1562 | let div_prefix_codes = _createDivInput(_x("Enter a prefix (optional)", 'label', 'event-tickets-with-ticket-scanner')).appendTo(appendToDiv); |
| 1563 | input_prefix_codes = $('<input type="text">').appendTo(div_prefix_codes); |
| 1564 | $('<div>').html(__('You can use date placeholder to have the prefix filled with the date of the confirmed purchase.', 'event-tickets-with-ticket-scanner')+'<br>'+__('You can use: {Y} = year, {m} = month, {d} = day, {H} = hour, {i} = minutes, {s} = seconds, {TIMESTAMP} = unix timestamp.', 'event-tickets-with-ticket-scanner')).appendTo(div_prefix_codes); |
| 1565 | if (formatterValues && formatterValues['input_prefix_codes'] != null) input_prefix_codes.val(formatterValues['input_prefix_codes']); |
| 1566 | input_prefix_codes.on("change", ()=>{ |
| 1567 | _callCallbackHandle(); |
| 1568 | }); |
| 1569 | // type numbers/serials |
| 1570 | let div_type_codes = _createDivInput(_x("Choose type of ticket numbers", 'label', 'event-tickets-with-ticket-scanner')).appendTo(appendToDiv); |
| 1571 | input_type_codes = $('<select><option value="1" selected>'+_x('Serials', 'option value', 'event-tickets-with-ticket-scanner')+'</option><option value="2">'+_x('Numbers', 'option value', 'event-tickets-with-ticket-scanner')+'</option></select>').appendTo(div_type_codes); |
| 1572 | if (formatterValues && formatterValues['input_type_codes'] != null) input_type_codes.val(formatterValues['input_type_codes']); |
| 1573 | |
| 1574 | if (noNumbersOptions) { |
| 1575 | input_type_codes.prop("disabled", true); |
| 1576 | } |
| 1577 | input_type_codes.on("change", function() { |
| 1578 | if (input_type_codes.val() === "2") { |
| 1579 | div_serials && div_serials.find("input").prop("disabled", true); |
| 1580 | div_serials && div_serials.find("select").prop("disabled", true); |
| 1581 | div_numbers && div_numbers.find("input").prop("disabled", false); |
| 1582 | div_numbers && div_numbers.find("select").prop("disabled", false); |
| 1583 | } else { |
| 1584 | div_serials && div_serials.find("input").prop("disabled", false); |
| 1585 | div_serials && div_serials.find("select").prop("disabled", false); |
| 1586 | div_numbers && div_numbers.find("input").prop("disabled", true); |
| 1587 | div_numbers && div_numbers.find("select").prop("disabled", true); |
| 1588 | } |
| 1589 | _callCallbackHandle(); |
| 1590 | }); |
| 1591 | // serials options |
| 1592 | let div_serials = $('<div>').html('<h4>'+_x('Serials options', 'title', 'event-tickets-with-ticket-scanner')+'</h4>').appendTo(appendToDiv); |
| 1593 | // anzahl letters |
| 1594 | let div_amount_letters = _createDivInput(_x('Amount of letter needed', 'label', 'event-tickets-with-ticket-scanner')).appendTo(div_serials); |
| 1595 | input_amount_letters = $('<input type="number" required value="21" min="1" max="30">').appendTo(div_amount_letters); |
| 1596 | if (formatterValues && formatterValues['input_amount_letters'] != null) input_amount_letters.val(formatterValues['input_amount_letters']); |
| 1597 | input_amount_letters.on("change", function(){ |
| 1598 | input_serial_delimiter.trigger("change"); |
| 1599 | _callCallbackHandle(); |
| 1600 | }); |
| 1601 | // select letter exclusion |
| 1602 | let div_letter_excl = _createDivInput(_x('Letter exclusion', 'label', 'event-tickets-with-ticket-scanner')).appendTo(div_serials); |
| 1603 | input_letter_excl = $('<select><option value="1">'+_x('None', 'option value', 'event-tickets-with-ticket-scanner')+'</option><option value="2" selected>i,l,o,p,q</option></select>').appendTo(div_letter_excl); |
| 1604 | if (formatterValues && formatterValues['input_letter_excl'] != null) input_letter_excl.val(formatterValues['input_letter_excl']); |
| 1605 | input_letter_excl.on("change", ()=>{ |
| 1606 | _callCallbackHandle(); |
| 1607 | }); |
| 1608 | // radio button text gross/klein/both/none |
| 1609 | let div_letter_style = _createDivInput(_x('Letter style', 'label', 'event-tickets-with-ticket-scanner')).appendTo(div_serials); |
| 1610 | input_letter_style = $('<select><option value="1" selected>'+_x('Uppercase', 'option value', 'event-tickets-with-ticket-scanner')+'</option><option value="2">'+_x('Lowercase', 'option value', 'event-tickets-with-ticket-scanner')+'</option><option value="3">'+_x('Both', 'option value', 'event-tickets-with-ticket-scanner')+'</option></select>').appendTo(div_letter_style); |
| 1611 | if (formatterValues && formatterValues['input_letter_style'] != null) input_letter_style.val(formatterValues['input_letter_style']); |
| 1612 | input_letter_style.on("change", ()=>{ |
| 1613 | _callCallbackHandle(); |
| 1614 | }); |
| 1615 | // radio button numbers/none |
| 1616 | let div_include_numbers = _createDivInput(_x('Numbers needed?', 'label', 'event-tickets-with-ticket-scanner')).appendTo(div_serials); |
| 1617 | input_include_numbers = $('<select><option value="1">'+_x('No', 'label', 'event-tickets-with-ticket-scanner')+'</option><option value="2" selected>'+_x('Yes', 'label', 'event-tickets-with-ticket-scanner')+'</option><option value="3">'+_x('Only numbers', 'option value', 'event-tickets-with-ticket-scanner')+'</option></select>').appendTo(div_include_numbers); |
| 1618 | if (formatterValues && formatterValues['input_include_numbers'] != null) input_include_numbers.val(formatterValues['input_include_numbers']); |
| 1619 | input_include_numbers.on("change", ()=>{ |
| 1620 | _callCallbackHandle(); |
| 1621 | }); |
| 1622 | // select delimiter none/-/./space |
| 1623 | let div_serial_delimiter = _createDivInput(_x('Delimiter?', 'label', 'event-tickets-with-ticket-scanner')).appendTo(div_serials); |
| 1624 | input_serial_delimiter = $('<select><option value="1">'+_x('None', 'option value', 'event-tickets-with-ticket-scanner')+'</option><option value="2" selected>-</option><option value="4">:</option><option value="3">'+_x('Space', 'option value', 'event-tickets-with-ticket-scanner')+'</option></select>').appendTo(div_serial_delimiter); |
| 1625 | if (formatterValues && formatterValues['input_serial_delimiter'] != null) input_serial_delimiter.val(formatterValues['input_serial_delimiter']); |
| 1626 | function __refreshDelimiterSpace() { |
| 1627 | input_serial_delimiter_space.html(""); |
| 1628 | if (input_serial_delimiter.val() !== "1") { |
| 1629 | let anzahl = parseInt(input_amount_letters.val(),10); |
| 1630 | if (anzahl > 0) { |
| 1631 | for(let a=1;a<anzahl;a++) input_serial_delimiter_space.append($('<option'+(anzahl > 2 && a === 7 ? " selected": "")+'>').attr("value",a).html(a)); |
| 1632 | } |
| 1633 | } |
| 1634 | } |
| 1635 | input_serial_delimiter.on("change", function(){ |
| 1636 | __refreshDelimiterSpace(); |
| 1637 | _callCallbackHandle(); |
| 1638 | }); |
| 1639 | // choose delimiter space |
| 1640 | let div_serial_delimiter_space = _createDivInput(_x('After how many letters?', 'label', 'event-tickets-with-ticket-scanner')).appendTo(div_serials); |
| 1641 | input_serial_delimiter_space = $('<select></select>').appendTo(div_serial_delimiter_space); |
| 1642 | if (formatterValues && formatterValues['input_serial_delimiter'] != null) { |
| 1643 | // setze Werte erstmal ein |
| 1644 | __refreshDelimiterSpace(); |
| 1645 | } |
| 1646 | if (formatterValues && formatterValues['input_serial_delimiter_space'] != null) input_serial_delimiter_space.val(formatterValues['input_serial_delimiter_space']); |
| 1647 | input_serial_delimiter_space.on("change", ()=>{ |
| 1648 | _callCallbackHandle(); |
| 1649 | }); |
| 1650 | // numbers options |
| 1651 | let div_numbers = $('<div>').html('<h4>'+_x('Numbers options', 'title', 'event-tickets-with-ticket-scanner')+'</h4>').appendTo(appendToDiv); |
| 1652 | if (noNumbersOptions) div_numbers.css("display","none"); |
| 1653 | // number start |
| 1654 | let div_number_start = _createDivInput(_x('Start number', 'label', 'event-tickets-with-ticket-scanner')).appendTo(div_numbers); |
| 1655 | input_number_start = $('<input type="number" disabled required value="10000" min="1">').appendTo(div_number_start); |
| 1656 | if (formatterValues && formatterValues['input_number_start'] != null) input_number_start.val(formatterValues['input_number_start']); |
| 1657 | input_number_start.on("change", ()=>{ |
| 1658 | _callCallbackHandle(); |
| 1659 | }); |
| 1660 | // number offset |
| 1661 | let div_number_offset = _createDivInput(_x('Offset for each number', 'label', 'event-tickets-with-ticket-scanner')).appendTo(div_numbers); |
| 1662 | input_number_offset = $('<input type="number" disabled required value="1" min="1">').appendTo(div_number_offset); |
| 1663 | if (formatterValues && formatterValues['input_number_offset'] != null) input_number_offset.val(formatterValues['input_number_offset']); |
| 1664 | input_number_offset.on("change", ()=>{ |
| 1665 | _callCallbackHandle(); |
| 1666 | }); |
| 1667 | } |
| 1668 | |
| 1669 | function __generateCode(length, cases, withnumbers, exclusion) { |
| 1670 | let charset = 'abcdefghijklmnopqrstuvwxyz'; |
| 1671 | if (cases === 1) charset = charset.toUpperCase(); |
| 1672 | if (cases === 3) charset += charset.toUpperCase(); |
| 1673 | if (withnumbers === 2) charset += '0123456789'; |
| 1674 | if (withnumbers === 3) charset = '0123456789'; |
| 1675 | if (typeof exclusion !== "undefined") { |
| 1676 | exclusion.forEach(function(v){ |
| 1677 | let regex = new RegExp(v, 'gi'); |
| 1678 | charset = charset.replace(regex, ""); |
| 1679 | }); |
| 1680 | } |
| 1681 | let retVal = ""; |
| 1682 | for (var i = 0, n = charset.length; i < length; ++i) { |
| 1683 | retVal += charset.charAt(Math.floor(Math.random() * n)); |
| 1684 | } |
| 1685 | return retVal; |
| 1686 | } |
| 1687 | function __insertSeperator(str, serial_delimiter, serial_delimiter_space) { |
| 1688 | if (str !== "" && serial_delimiter !== "" && serial_delimiter_space > 0) { |
| 1689 | let result = [str[0]]; |
| 1690 | for(let x=1; x<str.length; x++) { |
| 1691 | if (x%serial_delimiter_space === 0) { |
| 1692 | result.push(serial_delimiter, str[x]); |
| 1693 | } else { |
| 1694 | result.push(str[x]); |
| 1695 | } |
| 1696 | } |
| 1697 | return result.join(''); |
| 1698 | } |
| 1699 | return str; |
| 1700 | } |
| 1701 | |
| 1702 | function _isTypeNumbers() { |
| 1703 | return input_type_codes.val() === "2"; |
| 1704 | } |
| 1705 | function _getPrefix() { |
| 1706 | return input_prefix_codes.val().trim(); |
| 1707 | } |
| 1708 | function _getAmountLetters() { |
| 1709 | let amount_letters = parseInt(input_amount_letters.val().trim(),10); |
| 1710 | if (isNaN(amount_letters) || amount_letters < 1) { |
| 1711 | input_amount_letters.select(); |
| 1712 | return alert(__("Amount of letters has to be higher", 'event-tickets-with-ticket-scanner')); |
| 1713 | } |
| 1714 | return amount_letters; |
| 1715 | } |
| 1716 | function _getLetterExclusion() { |
| 1717 | return input_letter_excl.val() === "2" ? ['i','l','o','p','q'] : []; |
| 1718 | } |
| 1719 | function _getLetterStyle() { |
| 1720 | return parseInt(input_letter_style.val(),10); |
| 1721 | } |
| 1722 | function _getIncludeNumbers() { |
| 1723 | return parseInt(input_include_numbers.val(),10); |
| 1724 | } |
| 1725 | function _getSerialDelimiter() { |
| 1726 | return ['','-',' ',':'][parseInt(input_serial_delimiter.val(),10)-1]; |
| 1727 | } |
| 1728 | function _getSerialDelimiterSpace() { |
| 1729 | let serial_delimiter_space = 0; |
| 1730 | try { |
| 1731 | serial_delimiter_space = _getSerialDelimiter() !== "" ? parseInt(input_serial_delimiter_space.val(),10) : 0; |
| 1732 | } catch (e) {} |
| 1733 | return serial_delimiter_space; |
| 1734 | } |
| 1735 | function _getNumberStart() { |
| 1736 | let start_number = parseInt(input_number_start.val().trim(),10); |
| 1737 | if (isNaN(start_number) || start_number < 1) { |
| 1738 | input_number_start.select(); |
| 1739 | return alert(__("Your start number is not correct. It has to be an integer bigger than 0", 'event-tickets-with-ticket-scanner')); |
| 1740 | } |
| 1741 | return start_number; |
| 1742 | } |
| 1743 | function _getNumberOffset() { |
| 1744 | let number_offset = parseInt(input_number_offset.val().trim(),10); |
| 1745 | if (isNaN(number_offset) || number_offset < 1) number_offset = 1; |
| 1746 | return number_offset; |
| 1747 | } |
| 1748 | function _generateSerialCode(offsetCounter) { |
| 1749 | let code; |
| 1750 | let prefix = _getPrefix(); |
| 1751 | if (_isTypeNumbers()) { // numbers |
| 1752 | if (!offsetCounter) offsetCounter = 0; |
| 1753 | let number_offset = offsetCounter * _getNumberOffset(); |
| 1754 | code = _getNumberStart() + number_offset; |
| 1755 | if (prefix !== '') code = prefix + code; |
| 1756 | } else { |
| 1757 | code = __generateCode(_getAmountLetters(), _getLetterStyle(), _getIncludeNumbers(), _getLetterExclusion()); |
| 1758 | code = __insertSeperator(code, _getSerialDelimiter(), _getSerialDelimiterSpace()); |
| 1759 | if (prefix !== '') code = prefix + code; |
| 1760 | } |
| 1761 | return code; |
| 1762 | } |
| 1763 | function _getFormatterValues() { |
| 1764 | return { |
| 1765 | input_prefix_codes:_getPrefix().replace('/', '-'), |
| 1766 | input_type_codes:input_type_codes.val(), |
| 1767 | input_amount_letters:_getAmountLetters(), |
| 1768 | input_letter_excl:input_letter_excl.val(), |
| 1769 | input_letter_style:_getLetterStyle(), |
| 1770 | input_include_numbers:input_include_numbers.val(), |
| 1771 | input_serial_delimiter:input_serial_delimiter.val(), |
| 1772 | input_serial_delimiter_space:input_serial_delimiter_space.val(), |
| 1773 | input_number_start:_getNumberStart(), |
| 1774 | input_number_offset:_getNumberOffset() |
| 1775 | }; |
| 1776 | } |
| 1777 | |
| 1778 | return { |
| 1779 | render:__render, |
| 1780 | getAmountLetters:_getAmountLetters, |
| 1781 | getLetterExclusion:_getLetterExclusion, |
| 1782 | getLetterStyle:_getLetterStyle, |
| 1783 | getIncludeNumbers:_getIncludeNumbers, |
| 1784 | getSerialDelimiter:_getSerialDelimiter, |
| 1785 | getSerialDelimiterSpace:_getSerialDelimiterSpace, |
| 1786 | getNumberStart:_getNumberStart, |
| 1787 | getNumberOffset:_getNumberOffset, |
| 1788 | isTypeNumbers:_isTypeNumbers, |
| 1789 | getPrefix:_getPrefix, |
| 1790 | generateSerialCode:_generateSerialCode, |
| 1791 | setNoNumberOptions:_setNoNumberOptions, |
| 1792 | getFormatterValues:_getFormatterValues, |
| 1793 | setCallbackHandle:_setCallbackHandle, |
| 1794 | setFormatterValues:_setFormatterValues |
| 1795 | }; |
| 1796 | } |
| 1797 | |
| 1798 | function _createDivInput(label) { |
| 1799 | return $('<div/>').css({ |
| 1800 | "display": "inline-block", |
| 1801 | "margin-bottom": "15px", |
| 1802 | "margin-right": "15px" |
| 1803 | }).html(label+"<br>"); |
| 1804 | } |
| 1805 | |
| 1806 | class Layout { |
| 1807 | constructor(){ |
| 1808 | DIV.addClass("sngmbh_container"); |
| 1809 | this.div_liste = $('<div style="background:white;padding:15px;border-radius:15px;"/>').html(_getSpinnerHTML()); |
| 1810 | this.div_codes = $('<div style="background:white;padding:15px;border-radius:15px;"/>').html(_getSpinnerHTML()); |
| 1811 | this.div_spinner = $('<div style="display: none;position: fixed;z-index: 1031;top: 50%;right: 50%;margin-top: 0.5vh;background-color: white;margin-left: 0.5vw;border: 4px solid #2e74b5;padding: 10px;border-radius:10%;"/>').html(_getSpinnerHTML("loading")); |
| 1812 | $("body").append(this.div_spinner); |
| 1813 | } |
| 1814 | renderMainBody() { |
| 1815 | let premium_status = '<div style="color:red;font-weight:bold;">'+_x('FREE version', 'label', 'event-tickets-with-ticket-scanner')+'</div>'; |
| 1816 | if (isPremium()) { |
| 1817 | premium_status = '<div style="color:green;font-weight:bold;">'+_x('PREMIUM', 'label', 'event-tickets-with-ticket-scanner')+'</div>'; |
| 1818 | } |
| 1819 | $('body').find('td[data-id=plugin_info_area_premium_status]').html(premium_status); |
| 1820 | |
| 1821 | /* |
| 1822 | $('body').find('div[data-id=plugin_addons]').html("") |
| 1823 | .css("display", "flex") |
| 1824 | .css("justify-content", "space-between") |
| 1825 | .css("width", "100%") |
| 1826 | .css("padding-bottom", "20px") |
| 1827 | .css("padding-top", "20px") |
| 1828 | .css("box-sizing", "border-box") |
| 1829 | .append( $('<button style="flex-grow:1;margin-right:20px;background-color:cornflowerblue;border:none;color:white;padding:10px;">').html("How to start") ) |
| 1830 | .append( $('<button style="flex-grow:1;margin-right:20px;background-color:cornflowerblue;border:none;color:white;padding:10px;">').html("Quick start") ) |
| 1831 | .append( $('<button style="flex-grow:1;margin-right:20px;background-color:cornflowerblue;border:none;color:white;padding:10px;">').html("Ticket scanner") ) |
| 1832 | ; |
| 1833 | if (isPremium() == false) { |
| 1834 | $('body').find('div[data-id=plugin_addons]') |
| 1835 | .append( $('<button style="flex-grow:1;margin-right:20px;background-color:cornflowerblue;border:none;color:white;padding:10px;">').html("Upgrade now") ); |
| 1836 | } |
| 1837 | */ |
| 1838 | |
| 1839 | let div_body = $('<div/>'); |
| 1840 | div_body.append($('<div style="text-align:right;">').html(_displaySettingAreaButton())); |
| 1841 | div_body.append($('<h3/>').html(_x('List of tickets', 'title', 'event-tickets-with-ticket-scanner'))); |
| 1842 | div_body.append($('<p/>').html(__("Organize your tickets in lists. You can assign tickets to a list.", 'event-tickets-with-ticket-scanner'))); |
| 1843 | div_body.append(this.div_liste); |
| 1844 | div_body.append($('<hr/>')); |
| 1845 | div_body.append($('<h3/>').html(_x("Event Tickets", 'title', 'event-tickets-with-ticket-scanner'))); |
| 1846 | div_body.append(this.div_codes); |
| 1847 | return div_body; |
| 1848 | } |
| 1849 | renderAddCodes() { |
| 1850 | DIV.html(_getSpinnerHTML()); |
| 1851 | getDataLists(()=>{ |
| 1852 | function __generateCodes() { |
| 1853 | // generate codes and |
| 1854 | let amount_codes = parseInt(input_amount_codes.val().trim(),10); |
| 1855 | if (isNaN(amount_codes) || amount_codes < 1) { |
| 1856 | input_amount_codes.select(); |
| 1857 | return alert(_x("Enter an amount of how many ticket numbers you need", 'title', 'event-tickets-with-ticket-scanner')); |
| 1858 | } |
| 1859 | if (amount_codes > _maxCodes) { |
| 1860 | input_amount_codes.val(_maxCodes); |
| 1861 | amount_codes = _maxCodes; |
| 1862 | |
| 1863 | } |
| 1864 | let uniq = {}; |
| 1865 | let versuche = 0; |
| 1866 | if (serialCodeFormatterForm.isTypeNumbers()) { // numbers |
| 1867 | for(let a=0; a < amount_codes; a++) { |
| 1868 | let code = serialCodeFormatterForm.generateSerialCode( a ); |
| 1869 | if (typeof uniq[code] !== "undefined") { |
| 1870 | continue; |
| 1871 | } |
| 1872 | uniq[code] = true; |
| 1873 | } |
| 1874 | versuche = amount_codes; |
| 1875 | } else { |
| 1876 | // erstmal kein check ob mit dem alphabet und die geforderte Menge an letters, unique codes erstellt werden können |
| 1877 | let counter = 0; |
| 1878 | let versuche_max = amount_codes * 1.5; |
| 1879 | while(counter < amount_codes && versuche < versuche_max) { |
| 1880 | versuche++; |
| 1881 | let code = serialCodeFormatterForm.generateSerialCode(); |
| 1882 | if (typeof uniq[code] !== "undefined") { |
| 1883 | continue; |
| 1884 | } |
| 1885 | uniq[code] = true; |
| 1886 | counter++; |
| 1887 | } |
| 1888 | } |
| 1889 | return [Object.keys(uniq), versuche]; |
| 1890 | } // __generateCodes |
| 1891 | |
| 1892 | let div = $('<div>').append(getBackButtonDiv()); |
| 1893 | // eingabe generator options |
| 1894 | let div_generator = $('<div/>').css("padding", "10px").css("border","1px solid black").html('<h3>'+_x('1. Ticket number generator (optional step)', 'title', 'event-tickets-with-ticket-scanner')+'</h3>').appendTo(div); |
| 1895 | div_generator.append($('<p>').html(__("You can generate ticket numbers.", 'event-tickets-with-ticket-scanner'))); |
| 1896 | if (isPremium()) div_generator.append('<p>'+__('Up 100.000 tickets generation per run. The limit is to prevent performance issues.', 'event-tickets-with-ticket-scanner')+'<br>'+__('You can repeat the "store tickets" operations as often as needed.', 'event-tickets-with-ticket-scanner')+'</p>'); |
| 1897 | // anzahl codes |
| 1898 | let div_amount_codes = _createDivInput(_x('Enter amount of needed ticket numbers', 'label', 'event-tickets-with-ticket-scanner')).appendTo(div_generator); |
| 1899 | let _maxCodes = myAjax._max.codes; |
| 1900 | if (!isPremium()) div_amount_codes.append(sprintf(/* translators: 1: amount of possible codes 2: premium info */__('%1$d max. %2$s up to 100.000 for each run', 'event-tickets-with-ticket-scanner'), _maxCodes, getLabelPremiumOnly())+'<br>'); |
| 1901 | let input_amount_codes = $('<input type="number" required value="100" min="1" max="'+_maxCodes+'">').appendTo(div_amount_codes); |
| 1902 | |
| 1903 | // predefine elements |
| 1904 | let serialCodeFormatterForm = _form_fields_serial_format(div_generator); |
| 1905 | serialCodeFormatterForm.render(); |
| 1906 | |
| 1907 | let elem_clean_codebox = $('<input checked type="checkbox" />'); |
| 1908 | $('<div/>').css({"margin-bottom": "15px","margin-right": "15px"}) |
| 1909 | .html(elem_clean_codebox) |
| 1910 | .append(_x('Clear the ticket numbers list textarea field below to add fill in the new generated ticket numbers', 'label', 'event-tickets-with-ticket-scanner')) |
| 1911 | .appendTo(div_generator); |
| 1912 | |
| 1913 | let elem_create_cvv = $('<input type="checkbox" />'); |
| 1914 | $('<div/>').css({"margin-bottom": "15px","margin-right": "15px"}) |
| 1915 | .html(elem_create_cvv) |
| 1916 | .append(_x('Generate Code Verification Value (CVV) for each ticket number', 'label', 'event-tickets-with-ticket-scanner')) |
| 1917 | .appendTo(div_generator); |
| 1918 | |
| 1919 | // button generate |
| 1920 | div_generator.append($('<button/>').addClass("button-secondary").html(_x('Generate ticket numbers', 'label', 'event-tickets-with-ticket-scanner')).on("click", function(){ |
| 1921 | let time_start = performance.now(); |
| 1922 | btn_store_codes.prop("disabled", false); |
| 1923 | input_textarea.prop("disabled", false); |
| 1924 | if (elem_clean_codebox[0].checked) { |
| 1925 | input_textarea.html(""); |
| 1926 | } |
| 1927 | input_textarea.prop("disabled", true); |
| 1928 | div_textarea_info.css("padding-bottom", "50px").html(_getSpinnerHTML()); |
| 1929 | setTimeout(function(){ |
| 1930 | let r = __generateCodes(); |
| 1931 | let codes = r[0]; |
| 1932 | let secs = ((performance.now() - time_start) / 1000)+""; |
| 1933 | if (elem_create_cvv[0].checked) { |
| 1934 | codes = codes.map(v=>{ |
| 1935 | return v += ';'+(Math.floor(Math.random() * 10000) + 10000).toString().substring(1); |
| 1936 | }); |
| 1937 | } |
| 1938 | input_textarea.append(codes.join("\n")).append("\n"); |
| 1939 | input_textarea.prop("disabled", false); |
| 1940 | div_textarea_info.html(sprintf(/* translators: 1: amount of created tickets 2: seconds 3: amount of runs */__('Created %1$d tickets. In %2$s seconds, with %3$d runs to find unique ticket numbers.', 'event-tickets-with-ticket-scanner'), codes.length, secs.slice(0,5), r[1])); |
| 1941 | _calcLinesOfCodeTextArea(); |
| 1942 | },250); |
| 1943 | })); |
| 1944 | |
| 1945 | // eingabe maske textarea |
| 1946 | function _calcLinesOfCodeTextArea() { |
| 1947 | let codesAmount = 0; |
| 1948 | input_textarea.val().trim().split('\n').forEach(v=>{ |
| 1949 | if (v.trim() !== "") codesAmount++; |
| 1950 | }); |
| 1951 | input_textarea_info.html(sprintf(/* translators: %d: amout of ticket numbers */__('contains %d tickets', 'event-tickets-with-ticket-scanner'), codesAmount)); |
| 1952 | } |
| 1953 | let div_textarea = $('<div/>').html('<h3>'+_x('2. Ticket numbers to store on the server', 'title', 'event-tickets-with-ticket-scanner')+'</h3><p>'+__('One number per line and/or comma-separated (,). <br>If you want to add the CVV number then separate your ticket number with (;) and append your CVV number.<br>While storing the numbers to the server, it will check if the ticket number is unique and mark the ones, that are not.', 'event-tickets-with-ticket-scanner')+'</p>').appendTo(div); |
| 1954 | let div_textarea_info = $('<div/>').appendTo(div_textarea); |
| 1955 | let input_textarea = $('<textarea>').change(_calcLinesOfCodeTextArea).css("height","135px").css("width","100%").appendTo(div_textarea); |
| 1956 | let input_textarea_info = $('<div/>').appendTo(div_textarea); |
| 1957 | div_textarea.append("<br>"); |
| 1958 | _calcLinesOfCodeTextArea(); |
| 1959 | // list auswahl |
| 1960 | let div_code_list = _createDivInput(_x('Assign to this ticket list', 'label', 'event-tickets-with-ticket-scanner')).appendTo(div_textarea); |
| 1961 | let input_code_list = $('<select><option value="0">'+_x('None', 'option value', 'event-tickets-with-ticket-scanner')+'</select></select>').appendTo(div_code_list); |
| 1962 | DATA_LISTS.forEach(v=>{ |
| 1963 | input_code_list.append('<option value="'+v.id+'">'+v.name+'</option>'); |
| 1964 | }); |
| 1965 | div_textarea.append("<br>"); |
| 1966 | |
| 1967 | // additional prem fields |
| 1968 | if (isPremium() && PREMIUM.addAddCodeFields) { |
| 1969 | div_textarea.append(PREMIUM.addAddCodeFields()); |
| 1970 | } |
| 1971 | |
| 1972 | // button store codes |
| 1973 | if (!isPremium()) div_textarea.append('<b>'+sprintf(/* translators: 1: max amout of ticket numbers 2: premium info */__('You can store up to %1$d. %2$s unlimited', 'event-tickets-with-ticket-scanner'), myAjax._max.codes_total, getLabelPremiumOnly())+'<br>'); |
| 1974 | let btn_store_codes = $('<button/>'); |
| 1975 | btn_store_codes.addClass("button-primary").html(_x('Store ticket numbers', 'label', 'event-tickets-with-ticket-scanner')).on("click", function(){ |
| 1976 | // extract codes and |
| 1977 | let codes = []; |
| 1978 | let codesLines = input_textarea.val().split("\n").map(x=>x.trim()); |
| 1979 | codesLines.forEach(x=>{ |
| 1980 | x.split(",").forEach(y=>{ |
| 1981 | y = y.trim(); |
| 1982 | y = destroy_tags(y); |
| 1983 | if (y != "") codes.push(y); |
| 1984 | }); |
| 1985 | }); |
| 1986 | if (codes.length === 0) return; |
| 1987 | |
| 1988 | // sperre btn store codes |
| 1989 | btn_store_codes.prop("disabled", true); |
| 1990 | input_textarea.prop("disabled", true); |
| 1991 | |
| 1992 | div_textarea_info.append($('<div/>').addClass("notice notice-info").html(__("Each entry will turn green (successfull stored) or red (NOT OK - duplicat entry on the server).<br>Scroll down and wait for all to finish.<br>In the textarea below you will find all the successful stored tickets.", 'event-tickets-with-ticket-scanner'))); |
| 1993 | let _output = $('<ol/>').appendTo(div_textarea_info); |
| 1994 | div_textarea_info.append('<h3>'+_x('Successfull stored ticket numbers', 'title', 'event-tickets-with-ticket-scanner')+'</h3>'); |
| 1995 | let output_textarea_codes_done = $('<textarea disabled style="4px solid green;width:100%;height:150px;"></textarea>').appendTo(div_textarea_info); |
| 1996 | |
| 1997 | let list_id = parseInt(input_code_list.val(),10); |
| 1998 | |
| 1999 | function __addCodesInChunks(chunk_size) { |
| 2000 | let dlg = $('<div/>').html(_getSpinnerHTML()); |
| 2001 | dlg.dialog({title:_x('Importing', 'title', 'event-tickets-with-ticket-scanner'),closeOnEscape: true,modal: true, dialogClass: "no-close", close: function(event, ui){ abort=true; } }); |
| 2002 | |
| 2003 | let abort = false; |
| 2004 | let counter_ok = 0; |
| 2005 | let counter_notok = 0; |
| 2006 | let counter_all = codes.length; |
| 2007 | const array_chunks = (array, chunk_size) => Array(Math.ceil(array.length / chunk_size)).fill().map((_, index) => index * chunk_size).map(begin => array.slice(begin, begin + chunk_size)); |
| 2008 | let chunks = array_chunks(codes, chunk_size); |
| 2009 | function _addCodeChunk(idx) { |
| 2010 | if (abort) return; |
| 2011 | if (idx >= chunks.length) { |
| 2012 | dlg.append('<p>'+__('Import process finished', 'event-tickets-with-ticket-scanner')+'</p>'); |
| 2013 | $('<center/>').append($('<button class="button-primary" />').html(_x('Ok', 'label', 'event-tickets-with-ticket-scanner')).on("click", ()=>{ closeDialog(dlg); })).appendTo(dlg); |
| 2014 | return; |
| 2015 | } |
| 2016 | let arr = chunks[idx]; |
| 2017 | arr.forEach(v=>{ |
| 2018 | let div_info_entry = $('<li data-id="code_'+v+'"/>').html(v); |
| 2019 | _output.append(div_info_entry); |
| 2020 | }); |
| 2021 | let attr = {"codes":arr, "list_id":list_id}; |
| 2022 | if (isPremium() && PREMIUM.addAddCodeFieldsData) { |
| 2023 | attr = PREMIUM.addAddCodeFieldsData(div_textarea, attr); |
| 2024 | } |
| 2025 | |
| 2026 | _makePost("addCodes", attr, function(data){ |
| 2027 | counter_ok += data.ok.length; |
| 2028 | counter_notok += data.notok.length; |
| 2029 | if (myAjax._max.codes_total > 0 && myAjax._max.codes_total <= parseInt(data.total_size)) { |
| 2030 | div_textarea_info.prepend('<h3 style="color:red;">'+sprintf(/* translators: %d: total ticket count */_x('Your Limit of %d tickets is reached. Use the premium version to have unlimited tickets', 'title', 'event-tickets-with-ticket-scanner'),myAjax._max.codes_total)+'</h3>'); |
| 2031 | } |
| 2032 | let per = Math.ceil(((counter_ok+counter_notok)/counter_all)*100); |
| 2033 | let info_content = '<div style="width:100%;border:1px solid #efefef;background-color:white;"><div style="text-align:center;height:20px;background-color:#428bca;color:white;width:'+per+'%;">'+per+'%</div></div>'; |
| 2034 | info_content += '<p style="margin-top:20px;">'+_x('Amount', 'title', 'event-tickets-with-ticket-scanner')+': '+(counter_ok+counter_notok)+'/'+counter_all+'<br>'+_x('Ok', 'label', 'event-tickets-with-ticket-scanner')+': '+counter_ok+'<br>'+_x('Not Ok', 'label', 'event-tickets-with-ticket-scanner')+': '+counter_notok+'</p>'; |
| 2035 | dlg.html(info_content); |
| 2036 | data.ok.forEach(_v=> { |
| 2037 | _output.find('li[data-id="code_'+_v+'"]').css("color","green").append(' ('+_x('Ok', 'label', 'event-tickets-with-ticket-scanner')+')'); |
| 2038 | output_textarea_codes_done.append(_v+"\n"); |
| 2039 | }); |
| 2040 | data.notok.forEach(_v=> { |
| 2041 | _output.find('li[data-id="code_'+_v+'"]').css("color","red").append(' ('+_x('Not Ok', 'label', 'event-tickets-with-ticket-scanner')+')'); |
| 2042 | }); |
| 2043 | setTimeout(()=>{ |
| 2044 | _addCodeChunk(idx+1); |
| 2045 | }, 100); |
| 2046 | }, function(response){ |
| 2047 | if (response.data.slice(0,4) === "#208") { |
| 2048 | FATAL_ERROR === false && LAYOUT.renderFatalError(response.data); |
| 2049 | FATAL_ERROR = true; |
| 2050 | } |
| 2051 | }); |
| 2052 | } |
| 2053 | |
| 2054 | if (chunks.length === 0) { |
| 2055 | closeDialog(dlg); |
| 2056 | } else { |
| 2057 | _addCodeChunk(0); |
| 2058 | } |
| 2059 | } // __addCodesInChunks |
| 2060 | __addCodesInChunks(100); |
| 2061 | |
| 2062 | // zeige ok button, der info area leer macht und den btn store codes wieder aktiviert |
| 2063 | div_textarea_info.append($('<button/>').addClass("button-primary").css("margin-bottom", "20px").html(_x('Ok', 'label', 'event-tickets-with-ticket-scanner')).on("click", function(){ |
| 2064 | div_textarea_info.html(""); |
| 2065 | btn_store_codes.prop("disabled", false); |
| 2066 | input_textarea.prop("disabled", false); |
| 2067 | window.scrollTo(0,0); |
| 2068 | })); |
| 2069 | |
| 2070 | }).appendTo(div_textarea); |
| 2071 | DIV.html(div); |
| 2072 | }); |
| 2073 | } |
| 2074 | renderAdminPageLayout(cbf) { |
| 2075 | function __showMaskExport(totalRecordCount) { |
| 2076 | if (!totalRecordCount) totalRecordCount = 0; |
| 2077 | let maxRange = totalRecordCount > 40000 ? 40000 : totalRecordCount; |
| 2078 | let _options = { |
| 2079 | title: _x('Export tickets', 'title', 'event-tickets-with-ticket-scanner'), |
| 2080 | modal: true, |
| 2081 | minWidth: 400, |
| 2082 | minHeight: 200, |
| 2083 | buttons: [ |
| 2084 | { |
| 2085 | text: _x('Export', 'label', 'event-tickets-with-ticket-scanner'), |
| 2086 | click: function() { |
| 2087 | ___submitForm(); |
| 2088 | } |
| 2089 | }, |
| 2090 | { |
| 2091 | text: _x('Cancel', 'label', 'event-tickets-with-ticket-scanner'), |
| 2092 | click: function() { |
| 2093 | closeDialog(this); |
| 2094 | } |
| 2095 | } |
| 2096 | ] |
| 2097 | }; |
| 2098 | let formdlg = $('<form/>').html('<b>'+_x('Choose your export settings', 'title', 'event-tickets-with-ticket-scanner')+'</b><p>'); |
| 2099 | formdlg.append(_x('Choose the delimiter for the column values', 'label', 'event-tickets-with-ticket-scanner')+'<br><select name="delimiter"><option value="1">, ('+_x('Comma', 'option value', 'event-tickets-with-ticket-scanner')+')</option><option value="2">; ('+_x('Semicolon', 'option value', 'event-tickets-with-ticket-scanner')+')</option><option value="3">| ('+_x('Pipe', 'option value', 'event-tickets-with-ticket-scanner')+')</option></select><p>'); |
| 2100 | formdlg.append(_x('Choose a file suffix', 'label', 'event-tickets-with-ticket-scanner')+'<br><select name="suffix"><option value="1">.csv</option><option value="2">.txt</option></select><p>'); |
| 2101 | |
| 2102 | let _listChooser = $('<select name="listchooser"><option value="0">'+_x('All', 'option value', 'event-tickets-with-ticket-scanner')+'</option></select>'); |
| 2103 | for(let a=0;a<DATA_LISTS.length;a++) { |
| 2104 | _listChooser.append('<option value="'+DATA_LISTS[a].id+'">'+DATA_LISTS[a].name+'</option>'); |
| 2105 | } |
| 2106 | formdlg.append(_x('Limit export to ticket list', 'label', 'event-tickets-with-ticket-scanner')+'<br>').append(_listChooser).append('<p>'); |
| 2107 | |
| 2108 | formdlg.append(_x('Choose a sorting field', 'label', 'event-tickets-with-ticket-scanner')+'<br><select name="orderby"><option value="1" selected>'+_x('Creation date', 'option value', 'event-tickets-with-ticket-scanner')+'</option><option value="2">'+__('Ticket number', 'event-tickets-with-ticket-scanner')+'</option><option value="3">'+__('Ticket display number', 'event-tickets-with-ticket-scanner')+'</option><option value="4">'+_x('List name', 'option value', 'event-tickets-with-ticket-scanner')+'</option></select><p>'); |
| 2109 | formdlg.append(_x('Choose a sorting direction', 'label', 'event-tickets-with-ticket-scanner')+'<br><select name="orderbydirection"><option value="1" selected>'+_x('Ascending', 'option value', 'event-tickets-with-ticket-scanner')+'</option><option value="2">'+_x('Descending', 'option value', 'event-tickets-with-ticket-scanner')+'</option></select><p>'); |
| 2110 | formdlg.append(_x('Set a range', 'label', 'event-tickets-with-ticket-scanner')+'<br><i>'+sprintf(/* translators: %d: total record count */__('You have %d tickets stored.', 'event-tickets-with-ticket-scanner'), totalRecordCount)+'<br>'+__('Some systems are slow and the connection timeout interupts the export, if you have too many tickets. In that case, you can export your tickets in several steps. e.g. 0 and 20000 amount and then 20001 and 20000 amount.', 'event-tickets-with-ticket-scanner')+'</i><br>'+__('Enter your row start (0 = from the first)', 'event-tickets-with-ticket-scanner')+'<br><input type="number" name="rangestart" value="0"><br>'+_x('Enter amount of tickets', 'label', 'event-tickets-with-ticket-scanner')+'<br><input type="number" name="rangeamount" value="'+maxRange+'"><p>'); |
| 2111 | if (isPremium() && PREMIUM && PREMIUM.addExportTicketsInputFields) { |
| 2112 | formdlg.append(PREMIUM.addExportTicketsInputFields()); |
| 2113 | } |
| 2114 | let dlg = $('<div/>').append(formdlg); |
| 2115 | |
| 2116 | dlg.dialog(_options); |
| 2117 | |
| 2118 | let form = dlg.find("form").on("submit", function(event) { |
| 2119 | event.preventDefault(); |
| 2120 | ___submitForm(); |
| 2121 | }); |
| 2122 | |
| 2123 | function ___submitForm() { |
| 2124 | let delimiter = dlg.find('select[name="delimiter"]').val(); |
| 2125 | let filesuffix = dlg.find('select[name="suffix"]').val(); |
| 2126 | let orderby = dlg.find('select[name="orderby"]').val(); |
| 2127 | let orderbydirection = dlg.find('select[name="orderbydirection"]').val(); |
| 2128 | let rangestart = dlg.find('input[name="rangestart"]').val(); |
| 2129 | let rangeamount = dlg.find('input[name="rangeamount"]').val(); |
| 2130 | let listchooser = dlg.find('select[name="listchooser"]').val(); |
| 2131 | |
| 2132 | let data = {'delimiter':delimiter, 'filesuffix':filesuffix, 'orderby':orderby, 'orderbydirection':orderbydirection, 'rangestart':rangestart, 'rangeamount':rangeamount, 'listchooser':listchooser}; |
| 2133 | if (isPremium() && PREMIUM && PREMIUM.addExportTicketsInputFieldsData) { |
| 2134 | data = PREMIUM.addExportTicketsInputFieldsData(data, dlg); |
| 2135 | } |
| 2136 | |
| 2137 | let url = _requestURL('exportTableCodes', data); |
| 2138 | closeDialog(dlg); |
| 2139 | window.open(url, "_blank"); |
| 2140 | } |
| 2141 | } |
| 2142 | function __showMaskList(editValues){ |
| 2143 | let _options = { |
| 2144 | title: editValues !== null ? _x('Edit List', 'title', 'event-tickets-with-ticket-scanner') : _x('Add List', 'title', 'event-tickets-with-ticket-scanner'), |
| 2145 | modal: true, |
| 2146 | minWidth: 600, |
| 2147 | minHeight: 400, |
| 2148 | open: function(e) { |
| 2149 | //$(e.target).parent().css('background-color','orangered'); |
| 2150 | }, |
| 2151 | buttons: [ |
| 2152 | { |
| 2153 | text: _x('Ok', 'label', 'event-tickets-with-ticket-scanner'), |
| 2154 | click: function() { |
| 2155 | ___submitForm(); |
| 2156 | } |
| 2157 | }, |
| 2158 | { |
| 2159 | text: _x('Cancel', 'label', 'event-tickets-with-ticket-scanner'), |
| 2160 | click: function() { |
| 2161 | closeDialog(this); |
| 2162 | } |
| 2163 | } |
| 2164 | ] |
| 2165 | }; |
| 2166 | let dlg = $('<div/>').html('<form>'+_x('Name', 'label', 'event-tickets-with-ticket-scanner')+'<br><input name="inputName" type="text" style="width:100%;" required></form>'); |
| 2167 | dlg.dialog(_options); |
| 2168 | |
| 2169 | dlg.find("form").append($('<p>'+_x('Description', 'label', 'event-tickets-with-ticket-scanner')+'<br><textarea name="desc" style="width:100%;"></textarea></p>')); |
| 2170 | |
| 2171 | if (isPremium()) PREMIUM.addListMaskEditFields(dlg, editValues); |
| 2172 | else { |
| 2173 | if (_getOptions_isActivatedByKey("oneTimeUseOfRegisterCode")) { |
| 2174 | dlg.append($('<p><b>'+sprintf(/* translators: %s: h4 option name */__('Overrule %s per Ticket list', 'event-tickets-with-ticket-scanner'), _getOptions_getLabelByKey("h4"))+'</b> '+getLabelPremiumOnly()+'</p>')); |
| 2175 | } |
| 2176 | } |
| 2177 | |
| 2178 | let metaObj = []; |
| 2179 | if (editValues && typeof editValues.meta !== "undefined" && editValues.meta != "") { |
| 2180 | try { |
| 2181 | metaObj = JSON.parse(editValues.meta); |
| 2182 | } catch(e) {} |
| 2183 | } |
| 2184 | |
| 2185 | if (_getOptions_isActivatedByKey("userJSRedirectActiv")) { |
| 2186 | dlg.find("form").append($('<p>'+_getOptions_getLabelByKey("userJSRedirectURL")+'<br><input type="text" name="redirecturl" style="width:100%;"></p>')); |
| 2187 | } |
| 2188 | |
| 2189 | dlg.find("form").append($('<p><input name="serialformatter" type="checkbox"> '+_x('Overrule the ticket format settings', 'label', 'event-tickets-with-ticket-scanner')+'</p>')); |
| 2190 | let extra_div = $('<div>').appendTo(dlg).css("margin-top", "10px").css("margin-left", "24px").css("padding", "10px").css("border", "1px solid black") |
| 2191 | .html('<p><b>'+_x('Note', 'label', 'event-tickets-with-ticket-scanner')+':</b> '+__('Will be overriden if you set the ticket number format settings on the product!', 'event-tickets-with-ticket-scanner')+'</p>'); |
| 2192 | let serialCodeFormatter = _form_fields_serial_format(extra_div); |
| 2193 | serialCodeFormatter.setNoNumberOptions(); |
| 2194 | if (typeof metaObj.formatter !== "undefined" && metaObj.formatter.format != "") { |
| 2195 | let formatterValues; |
| 2196 | try { |
| 2197 | let o = metaObj.formatter.format.replace(new RegExp("\\\\", "g"), "").trim(); |
| 2198 | formatterValues = JSON.parse(o); |
| 2199 | serialCodeFormatter.setFormatterValues(formatterValues); |
| 2200 | } catch (e) {} |
| 2201 | } |
| 2202 | serialCodeFormatter.render(); |
| 2203 | |
| 2204 | $('<hr>').appendTo(dlg); |
| 2205 | $('<h4>').html(_x('Webhook', 'heading', 'event-tickets-with-ticket-scanner')).appendTo(dlg); |
| 2206 | if (!_getOptions_isActivatedByKey("webhooksActiv")) { |
| 2207 | $('<div style="color:red">').html(_x('The webhook need to be activated first in the options to be executed, even if the URL is set here.', 'label', 'event-tickets-with-ticket-scanner')).appendTo(dlg); |
| 2208 | } |
| 2209 | $('<div>').html(_x('URL to your service if the WooCommerce ticket is sold', 'label', 'event-tickets-with-ticket-scanner')).appendTo(dlg); |
| 2210 | let meta_webhooks_webhookURLaddwcticketsold = $('<input name="meta_webhooks_webhookURLaddwcticketsold" type="text" style="width:100%;">').appendTo(dlg); |
| 2211 | |
| 2212 | let form = dlg.find("form").on("submit", function(event) { |
| 2213 | event.preventDefault(); |
| 2214 | ___submitForm(); |
| 2215 | }); |
| 2216 | |
| 2217 | if (editValues) { |
| 2218 | form[0].elements['inputName'].value = editValues.name; |
| 2219 | form[0].elements['inputName'].select(); |
| 2220 | if (typeof metaObj.desc !== "undefined") { |
| 2221 | form[0].elements['desc'].value = metaObj.desc; |
| 2222 | } |
| 2223 | if (typeof metaObj.formatter !== "undefined" && metaObj.formatter.active) { |
| 2224 | form[0].elements['serialformatter'].checked = true; |
| 2225 | } |
| 2226 | if (_getOptions_isActivatedByKey("userJSRedirectActiv") && typeof metaObj.redirect !== "undefined" && metaObj.redirect.url) { |
| 2227 | form[0].elements['redirecturl'].value = metaObj.redirect.url.trim(); |
| 2228 | } |
| 2229 | if (typeof metaObj.webhooks != "undefined") { |
| 2230 | if (typeof metaObj.webhooks.webhookURLaddwcticketsold != "undefined") { |
| 2231 | meta_webhooks_webhookURLaddwcticketsold.val(metaObj.webhooks.webhookURLaddwcticketsold); |
| 2232 | } |
| 2233 | } |
| 2234 | } |
| 2235 | |
| 2236 | function ___submitForm() { |
| 2237 | let inputName = form[0].elements['inputName'].value.trim(); |
| 2238 | if (inputName === "") return; |
| 2239 | |
| 2240 | dlg.html(_getSpinnerHTML()); |
| 2241 | let _data = {"name":inputName}; |
| 2242 | _data['meta'] = {"desc":"", "formatter":{}, "webhooks":{}}; |
| 2243 | _data['meta']['desc'] = form[0].elements['desc'].value.trim(); |
| 2244 | _data['meta']['formatter']['active'] = form[0].elements['serialformatter'].checked ? 1 : 0; |
| 2245 | _data['meta']['formatter']['format'] = JSON.stringify(serialCodeFormatter.getFormatterValues()); |
| 2246 | if (_getOptions_isActivatedByKey("userJSRedirectActiv")) { |
| 2247 | _data['meta']['redirect'] = {"url":form[0].elements['redirecturl'].value.trim()}; |
| 2248 | } |
| 2249 | _data['meta']['webhooks']['webhookURLaddwcticketsold'] = meta_webhooks_webhookURLaddwcticketsold.val().trim(); |
| 2250 | if (isPremium()) PREMIUM.addListMaskEditFieldsData(_data, form[0], editValues); |
| 2251 | |
| 2252 | form[0].reset(); |
| 2253 | if (editValues) { |
| 2254 | _data.id = editValues.id; |
| 2255 | _makePost('editList', _data, result=>{ |
| 2256 | DATA_LISTS = null; |
| 2257 | __renderTabelleListen(); |
| 2258 | tabelle_codes_datatable.ajax.reload(); |
| 2259 | setTimeout(function(){closeDialog(dlg);},250); |
| 2260 | }, function() { |
| 2261 | closeDialog(dlg); |
| 2262 | }); |
| 2263 | } else { |
| 2264 | _makePost('addList', _data, result=>{ |
| 2265 | DATA_LISTS = null; |
| 2266 | __renderTabelleListen(); |
| 2267 | closeDialog(dlg); |
| 2268 | }, function(response) { |
| 2269 | closeDialog(dlg); |
| 2270 | if (response.data.slice(0,1) === "#") { |
| 2271 | FATAL_ERROR === false && LAYOUT.renderFatalError(response.data); |
| 2272 | FATAL_ERROR = true; |
| 2273 | } |
| 2274 | }); |
| 2275 | } |
| 2276 | } |
| 2277 | |
| 2278 | } // ende showmaskliste |
| 2279 | |
| 2280 | function __showMaskCode(editValues){ |
| 2281 | let _options = { |
| 2282 | title: editValues !== null ? _x('Edit Ticket', 'title', 'event-tickets-with-ticket-scanner') : _x('Add Ticket', 'title', 'event-tickets-with-ticket-scanner'), |
| 2283 | modal: true, |
| 2284 | minWidth: 400, |
| 2285 | minHeight: 200, |
| 2286 | buttons: [ |
| 2287 | { |
| 2288 | text: _x('Ok', 'label', 'event-tickets-with-ticket-scanner'), |
| 2289 | click: function() { |
| 2290 | ___submitForm(); |
| 2291 | } |
| 2292 | }, |
| 2293 | { |
| 2294 | text: _x('Cancel', 'label', 'event-tickets-with-ticket-scanner'), |
| 2295 | click: function() { |
| 2296 | $( this ).dialog( "close" ); |
| 2297 | $( this ).html(''); |
| 2298 | } |
| 2299 | } |
| 2300 | ] |
| 2301 | }; |
| 2302 | let dlg = $('<div />').html('<form>'+_x('List', 'label', 'event-tickets-with-ticket-scanner')+'<br><select name="inputListId"><option value="0">'+_x('None', 'option value', 'event-tickets-with-ticket-scanner')+'</option></select></form>'); |
| 2303 | DATA_LISTS.forEach(v=>{ |
| 2304 | $(dlg).find('select[name="inputListId"]').append('<option '+(editValues && parseInt(editValues.list_id,10) === parseInt(v.id,10) ? 'selected ':'')+'value="'+v.id+'">'+v.name+'</option>'); |
| 2305 | }); |
| 2306 | |
| 2307 | let elem_cvv = $('<input type="text" size="6" minlength="5" maxlength="4" />'); |
| 2308 | $('<div/>').css({"margin-top":"10px","margin-bottom": "15px","margin-right": "15px"}) |
| 2309 | .html(_x('CVV - use 4 digits for best results', 'label', 'event-tickets-with-ticket-scanner')+'<br>') |
| 2310 | .append(elem_cvv) |
| 2311 | .append('<br><i>'+__('If CVV is set, then your user will be asked to enter also the CVV to check the ticket number.', 'event-tickets-with-ticket-scanner')+'</i>') |
| 2312 | .appendTo(dlg.find("form")); |
| 2313 | |
| 2314 | let div_status = $('<div/>'); |
| 2315 | div_status.append( |
| 2316 | $('<select name="inputStatus"/>') |
| 2317 | .append('<option '+(editValues.aktiv === "1"?'selected':'')+' value="1">'+_x('is activ', 'option value', 'event-tickets-with-ticket-scanner')+'</option>') |
| 2318 | .append('<option '+(editValues.aktiv === "0"?'selected':'')+' '+(!isPremium()?'disabled':'')+' value="0">'+_x('is inactiv', 'option value', 'event-tickets-with-ticket-scanner')+' '+(!isPremium()?getLabelPremiumOnly():'')+'</option>') |
| 2319 | .append('<option '+(editValues.aktiv === "2"?'selected':'')+' value="2">'+_x('is stolen', 'label', 'event-tickets-with-ticket-scanner')+'</option>') |
| 2320 | ) |
| 2321 | .appendTo(dlg); |
| 2322 | |
| 2323 | dlg.dialog(_options); |
| 2324 | |
| 2325 | if (editValues) { |
| 2326 | if (editValues.cvv) elem_cvv.val(editValues.cvv); |
| 2327 | } |
| 2328 | |
| 2329 | if (isPremium()) PREMIUM.addCodeMaskEditFields(dlg, editValues); |
| 2330 | |
| 2331 | let form = dlg.find("form").on("submit", function(event) { |
| 2332 | event.preventDefault(); |
| 2333 | ___submitForm(); |
| 2334 | }); |
| 2335 | function ___submitForm() { |
| 2336 | let inputListId = parseInt($(dlg).find('select[name="inputListId"]').val(),10); |
| 2337 | let inputStatusValue = $(dlg).find('select[name="inputStatus"]').val(); |
| 2338 | dlg.html(_getSpinnerHTML()); |
| 2339 | let _data = {"list_id":inputListId, "aktiv":inputStatusValue, "cvv":elem_cvv.val().trim()}; |
| 2340 | if (isPremium()) PREMIUM.addCodeMaskEditFieldsData(_data, form[0], editValues); |
| 2341 | form[0].reset(); |
| 2342 | if (editValues) { |
| 2343 | _data.code = editValues.code; |
| 2344 | _makeGet('editCode', _data, ()=>{ |
| 2345 | tabelle_codes_datatable.ajax.reload(); |
| 2346 | closeDialog(dlg); |
| 2347 | }, function() { |
| 2348 | closeDialog(dlg); |
| 2349 | }); |
| 2350 | } else { |
| 2351 | alert(__("Use the add option", 'event-tickets-with-ticket-scanner')); |
| 2352 | } |
| 2353 | } |
| 2354 | } // ende __showMaskCode |
| 2355 | |
| 2356 | let id_codes = myAjax.divPrefix+'_tabelle_codes'; |
| 2357 | let tabelle_liste_datatable; |
| 2358 | let tabelle_codes_datatable; |
| 2359 | let tabelle_codes = $('<table/>').attr("id", id_codes); |
| 2360 | let tplace = $('<div/>'); |
| 2361 | |
| 2362 | function __renderTabelleListen() { |
| 2363 | getDataLists(()=>{ |
| 2364 | let id_liste = myAjax.divPrefix+'_tabelle_liste'; |
| 2365 | let tabelle_liste = $('<table/>').attr("id", id_liste); |
| 2366 | tabelle_liste.html('<thead><tr><th align="left">'+_x('Name', 'label', 'event-tickets-with-ticket-scanner')+'</th><th align="left">'+_x('Created', 'label', 'event-tickets-with-ticket-scanner')+'</th><th></th></tr></thead>'); |
| 2367 | tplace.html(tabelle_liste); |
| 2368 | |
| 2369 | let table = $('#'+id_liste); |
| 2370 | $(table).DataTable().clear().destroy(); |
| 2371 | tabelle_liste_datatable = $(table).DataTable({ |
| 2372 | "responsive": true, |
| 2373 | "visible": true, |
| 2374 | "searching": true, |
| 2375 | "ordering": true, |
| 2376 | "processing": true, |
| 2377 | "serverSide": false, |
| 2378 | "stateSave": true, |
| 2379 | "data": DATA_LISTS, |
| 2380 | "order": [[ 0, "asc" ]], |
| 2381 | "columns":[ |
| 2382 | {"data":"name", "orderable":true}, |
| 2383 | {"data":"time", "orderable":true, "width":80, |
| 2384 | "render":function (data, type, row) { |
| 2385 | return '<span style="display:none;">'+data+'</span>'+DateTime2Text(data); |
| 2386 | } |
| 2387 | }, |
| 2388 | {"data":null,"orderable":false,"defaultContent":'',"className":"buttons dt-right","width":110, |
| 2389 | "render": function ( data, type, row ) { |
| 2390 | return '<button class="button-secondary" data-type="showCodes">'+_x('Tickets', 'label', 'event-tickets-with-ticket-scanner')+'</button> <button class="button-secondary" data-type="edit">'+_x('Edit', 'label', 'event-tickets-with-ticket-scanner')+'</button> <button class="button-secondary" data-type="delete">'+_x('Delete', 'label', 'event-tickets-with-ticket-scanner')+'</button>'; |
| 2391 | } |
| 2392 | } |
| 2393 | ] |
| 2394 | }); |
| 2395 | tabelle_liste.css("width", "100%"); |
| 2396 | table.on('click', 'button[data-type="showCodes"]', e=>{ |
| 2397 | let data = tabelle_liste_datatable.row( $(e.target).parents('tr') ).data(); |
| 2398 | tabelle_codes_datatable.search("LIST:"+data.id).draw(); |
| 2399 | }); |
| 2400 | table.on('click', 'button[data-type="edit"]', e=>{ |
| 2401 | let data = tabelle_liste_datatable.row( $(e.target).parents('tr') ).data(); |
| 2402 | __showMaskList(data); |
| 2403 | }); |
| 2404 | table.on('click', 'button[data-type="delete"]', e=>{ |
| 2405 | let data = tabelle_liste_datatable.row( $(e.target).parents('tr') ).data(); |
| 2406 | LAYOUT.renderYesNo(_x('Do you want to delete?', 'title', 'event-tickets-with-ticket-scanner'), __('Are you sure, you want to delete this list?', 'event-tickets-with-ticket-scanner')+'<br><p><b>'+data.name+'</b></p>'+__('No ticket will be deleted. Just the list.', 'event-tickets-with-ticket-scanner'), ()=>{ |
| 2407 | let _data = {'id':data.id}; |
| 2408 | _makePost('removeList', _data, result=>{ |
| 2409 | __renderTabelleListen(); |
| 2410 | tabelle_codes_datatable.ajax.reload(); |
| 2411 | }); |
| 2412 | }); |
| 2413 | }); |
| 2414 | }); // end of loading lists |
| 2415 | } // __renderTabelleListen |
| 2416 | tabelle_codes.css("width", "100%"); |
| 2417 | |
| 2418 | STATE = 'admin'; |
| 2419 | DIV.html(_getSpinnerHTML()); |
| 2420 | getOptionsFromServer(optionData=>{ |
| 2421 | DIV.html(''); |
| 2422 | DIV.append(this.renderMainBody()); |
| 2423 | |
| 2424 | let btn_liste_empty = $('<button/>').addClass("button-secondary").html(__('Empty table', 'event-tickets-with-ticket-scanner')).on("click", ()=>{ |
| 2425 | LAYOUT.renderYesNo(__('Empty table', 'event-tickets-with-ticket-scanner'), sprintf(/* translators: %s: title list of tickets */__('Do you want to empty the "%s" table? All data will be lost. No ticket will be deleted. Just the lists.', 'event-tickets-with-ticket-scanner'), _x('List of tickets', 'title', 'event-tickets-with-ticket-scanner')), ()=>{ |
| 2426 | LAYOUT.renderYesNo(__('Empty table - last chance', 'event-tickets-with-ticket-scanner'), sprintf(/* translators: %s: title list of tickets */__('Are you sure? You will not be able to restore the data, except you have a backup of your database. All data will be lost. No ticket will be deleted. Just the lists.', 'event-tickets-with-ticket-scanner'), _x('List of tickets', 'title', 'event-tickets-with-ticket-scanner')), ()=>{ |
| 2427 | _makeGet('emptyTableLists', null, ()=>{ |
| 2428 | tabelle_codes_datatable.ajax.reload(); |
| 2429 | __renderTabelleListen(); |
| 2430 | }); |
| 2431 | }); |
| 2432 | }); |
| 2433 | }); |
| 2434 | let btn_liste_new = $('<button/>').addClass("button-primary").html(_x('Add', 'label', 'event-tickets-with-ticket-scanner')).on("click", ()=>{ |
| 2435 | __showMaskList(null); |
| 2436 | }); |
| 2437 | this.div_liste.html($('<div/>').css('text-align', 'right').css('margin-bottom','10px').append(btn_liste_empty).append(isPremium()?'':' '+sprintf(/* translators: 1: max possible lists amount 2: link to premium */__('Max. %1$d list. Unlimited with %2$s', 'event-tickets-with-ticket-scanner'), myAjax._max.lists, getLabelPremiumOnly())+' ').append(btn_liste_new)); |
| 2438 | this.div_liste.append(tplace); |
| 2439 | |
| 2440 | __renderTabelleListen(); |
| 2441 | |
| 2442 | let additionalColumn = {customerName:'',customerCompany:'',redeemAmount:'',confirmedCount:''}; |
| 2443 | if (_getOptions_isActivatedByKey('displayAdminAreaColumnConfirmedCount')) { |
| 2444 | additionalColumn.confirmedCount = '<th>'+_x('Confirmed Count', 'label', 'event-tickets-with-ticket-scanner')+'</th>'; |
| 2445 | } |
| 2446 | if (_getOptions_isActivatedByKey('displayAdminAreaColumnBillingName')) { |
| 2447 | additionalColumn.customerName = '<th>'+_x('Customer', 'label', 'event-tickets-with-ticket-scanner')+'</th>'; |
| 2448 | } |
| 2449 | if (_getOptions_isActivatedByKey('displayAdminAreaColumnBillingCompany')) { |
| 2450 | additionalColumn.customerCompany = '<th>'+_x('Company', 'label', 'event-tickets-with-ticket-scanner')+'</th>'; |
| 2451 | } |
| 2452 | if (_getOptions_isActivatedByKey('displayAdminAreaColumnRedeemedInfo')) { |
| 2453 | additionalColumn.redeemAmount = '<th>'+_x('Redeem Amount', 'label', 'event-tickets-with-ticket-scanner')+'</th>'; |
| 2454 | } |
| 2455 | |
| 2456 | tabelle_codes.html('<thead><tr><th style="text-align:left;padding-left:10px;"><input type="checkbox" data-id="checkAll"></th><th> </th><th align="left">' |
| 2457 | +_x('Ticket', 'label', 'event-tickets-with-ticket-scanner')+'</th>'+additionalColumn.customerName+additionalColumn.customerCompany+'<th align="left">' |
| 2458 | +_x('List', 'label', 'event-tickets-with-ticket-scanner')+'</th><th align="left">' |
| 2459 | +_x('Created', 'label', 'event-tickets-with-ticket-scanner')+'</th>'+additionalColumn.confirmedCount+'<th align="left">' |
| 2460 | +_x('Redeemed', 'label', 'event-tickets-with-ticket-scanner')+'</th>'+additionalColumn.redeemAmount+'<th>' |
| 2461 | +_x('OrderId', 'label', 'event-tickets-with-ticket-scanner')+'</th><th>CVV</th><th>' |
| 2462 | +_x('Status', 'label', 'event-tickets-with-ticket-scanner')+'</th><th></th></tr></thead><tfoot><th colspan="10" style="text-align:left;font-weight:normal;padding-left:0;padding-bottom:0;"></th></tfoot>'); |
| 2463 | tabelle_codes.find('input[data-id="checkAll"]').on('click', (e)=> { |
| 2464 | let isChecked = $(e.currentTarget).prop('checked'); |
| 2465 | let found = false; |
| 2466 | tabelle_codes.find('input[data-type="select-checkbox"]').each((i,v)=>{ |
| 2467 | $(v).prop('checked', isChecked); |
| 2468 | found = true; |
| 2469 | }); |
| 2470 | if (isChecked && found) { |
| 2471 | //drop_codes_bulk.prop("disabled", false); |
| 2472 | } else { |
| 2473 | //drop_codes_bulk.prop("disabled", true); |
| 2474 | } |
| 2475 | }); |
| 2476 | let btn_codes_new = $('<button/>').addClass("button-primary").html(_x('Add', 'label', 'event-tickets-with-ticket-scanner')).on("click", ()=>{ |
| 2477 | if (!isPremium() && tabelle_codes_datatable.page.info().recordsTotal > myAjax._max.codes_total) { |
| 2478 | alert(__("You reached maximum amount of tickets. You need to delete tickets before you can add more new tickets or buy the premium version to have unlimited tickets.", 'event-tickets-with-ticket-scanner')); |
| 2479 | } else { |
| 2480 | LAYOUT.renderAddCodes(); |
| 2481 | } |
| 2482 | }); |
| 2483 | let btn_codes_empty = $('<button/>').addClass("button-secondary").html(__('Empty table', 'event-tickets-with-ticket-scanner')).on("click", ()=>{ |
| 2484 | LAYOUT.renderYesNo(__('Empty table', 'event-tickets-with-ticket-scanner'), sprintf(/* translators: %s: name of ticket table */__('Do you want to empty the "%s" table? All data will be lost.', 'event-tickets-with-ticket-scanner'), _x("Event Tickets", 'title', 'event-tickets-with-ticket-scanner')), ()=>{ |
| 2485 | LAYOUT.renderYesNo(__('Empty table - last chance', 'event-tickets-with-ticket-scanner'), sprintf(/* translators: %s: name of ticket table */__('Are you sure? You will not be able to restore the data, except you have a backup of your database. All data will be lost.', 'event-tickets-with-ticket-scanner'), _x("Event Tickets", 'title', 'event-tickets-with-ticket-scanner')), ()=>{ |
| 2486 | _makeGet('emptyTableCodes', null, ()=>{ |
| 2487 | tabelle_codes_datatable.ajax.reload(); |
| 2488 | }); |
| 2489 | }); |
| 2490 | }); |
| 2491 | }); |
| 2492 | let btn_codes_reload = $('<button/>').addClass("button-secondary").html(__('Refresh table', 'event-tickets-with-ticket-scanner')).on("click", ()=>{ |
| 2493 | LAYOUT.renderSpinnerShow(); |
| 2494 | tabelle_codes_datatable.ajax.reload(); |
| 2495 | window.setTimeout(()=>{LAYOUT.renderSpinnerHide();}, 1500); |
| 2496 | }); |
| 2497 | let btn_codes_export = $('<button/>').addClass("button-secondary").html(_x('Export tickets', 'label', 'event-tickets-with-ticket-scanner')).on("click", ()=>{ |
| 2498 | //let url = _requestURL('exportTableCodes', null); |
| 2499 | //window.open(url, "_blank"); |
| 2500 | //console.log(tabelle_codes_datatable.page.info()); |
| 2501 | __showMaskExport(tabelle_codes_datatable.page.info().recordsTotal); |
| 2502 | }); |
| 2503 | let drop_codes_bulk = $('<select data-id="bulk-code-action" />') |
| 2504 | .html('<option value="">'+_x('Bulk Action', 'option value', 'event-tickets-with-ticket-scanner')+'</option>'); |
| 2505 | //.append('<option value="delete">'+_x('Delete', 'label', 'event-tickets-with-ticket-scanner')+'</option>'); |
| 2506 | for (var key in BulkActions.codes) { |
| 2507 | let entry = BulkActions.codes[key]; |
| 2508 | drop_codes_bulk.append('<option value="'+key+'">'+entry.label+'</option>'); |
| 2509 | } |
| 2510 | drop_codes_bulk.on('change', ()=>{ |
| 2511 | let val = drop_codes_bulk.val(); |
| 2512 | if (val !== "") { |
| 2513 | let selectedElems = []; |
| 2514 | tabelle_codes.find('input[data-type="select-checkbox"]').each((i,v)=>{ |
| 2515 | if ($(v).prop("checked")) selectedElems.push(v); |
| 2516 | }); |
| 2517 | if (selectedElems.length) { |
| 2518 | let fkt = null; |
| 2519 | if (typeof BulkActions.codes[val] == "function") { |
| 2520 | fkt = BulkActions.codes[val]; |
| 2521 | } else { |
| 2522 | fkt = BulkActions.codes[val].fkt; |
| 2523 | } |
| 2524 | fkt && fkt(selectedElems, tabelle_codes_datatable); |
| 2525 | } |
| 2526 | } |
| 2527 | drop_codes_bulk.val(''); |
| 2528 | }); |
| 2529 | let drop_search = $('<select data-id="filter_type" />'); |
| 2530 | drop_search.append('<option value="">'+_x('Default search filter', 'option value', 'event-tickets-with-ticket-scanner')+'</option>'); |
| 2531 | drop_search.append('<option value="LIST:">'+_x('Filter for list id', 'option value', 'event-tickets-with-ticket-scanner')+'</option>'); |
| 2532 | drop_search.append('<option value="ORDERID:">'+_x('Filter for order id', 'option value', 'event-tickets-with-ticket-scanner')+'</option>'); |
| 2533 | drop_search.append('<option value="CVV:">'+_x('Filter for cvv value', 'option value', 'event-tickets-with-ticket-scanner')+'</option>'); |
| 2534 | drop_search.append('<option value="STATUS:">'+_x('Filter for status (1:active, 0:inactive, 2:stolen)', 'option value', 'event-tickets-with-ticket-scanner')+'</option>'); |
| 2535 | drop_search.append('<option value="REDEEMED:">'+_x('Filter for redeemed status (0:not redeemed yet, 1:redeemed)', 'option value', 'event-tickets-with-ticket-scanner')+'</option>'); |
| 2536 | drop_search.append('<option value="USERID:">'+_x('Filter for registered user id', 'option value', 'event-tickets-with-ticket-scanner')+'</option>'); |
| 2537 | drop_search.append('<option value="CUSTOMER:">'+_x('Filter for customer name in billing first and last name', 'option value', 'event-tickets-with-ticket-scanner')+'</option>'); |
| 2538 | drop_search.append('<option value="PRODUCTID:">'+_x('Filter for product id', 'option value', 'event-tickets-with-ticket-scanner')+'</option>'); |
| 2539 | drop_search.append('<option value="DAYPERTICKET:">'+_x('Filter for choosen date (enter YYYY-MM-DD)', 'option value', 'event-tickets-with-ticket-scanner')+'</option>'); |
| 2540 | drop_search.on("change", e=>{ |
| 2541 | let old_search = tabelle_codes_datatable.search().trim(); |
| 2542 | let search = drop_search.val(); |
| 2543 | if (old_search && old_search.length > 0) { |
| 2544 | search = old_search + " & " + search; |
| 2545 | } |
| 2546 | tabelle_codes_datatable.search(search); |
| 2547 | }); |
| 2548 | this.div_codes |
| 2549 | .html($('<div/>').css('text-align', 'right').css('margin-bottom','10px') |
| 2550 | .append(drop_codes_bulk) |
| 2551 | .append(drop_search) |
| 2552 | .append(btn_codes_export) |
| 2553 | .append(btn_codes_empty) |
| 2554 | .append(btn_codes_reload) |
| 2555 | .append(isPremium()?'':' '+sprintf(/* translators: 1: max amount tickets 2: premium link */__('Max. %1$d tickets. Unlimited with %2$s', 'event-tickets-with-ticket-scanner'), myAjax._max.codes_total, getLabelPremiumOnly())+' ').append(btn_codes_new)); |
| 2556 | this.div_codes.append(tabelle_codes); |
| 2557 | |
| 2558 | let table_columns = [ |
| 2559 | {"data":null,"orderable":false,"defaultContent":'', "render":function (data, type, row) { |
| 2560 | return '<input type="checkbox" data-type="select-checkbox" data-key="'+data.id+'" data-code="'+data.code+'">'; |
| 2561 | }}, |
| 2562 | {"data":null,"className":'details-control',"orderable":false,"defaultContent":''}, |
| 2563 | {"data":"code_display", "orderable":true, "render":(data,type,row)=>{ |
| 2564 | return destroy_tags(data); |
| 2565 | }}, |
| 2566 | {"data":"list_name", "orderable":true, "render":(data,type,row)=>{ |
| 2567 | return destroy_tags(data); |
| 2568 | }}, |
| 2569 | {"data":"time", "className":"dt-center", "orderable":true, |
| 2570 | "render":function (data, type, row) { |
| 2571 | return '<span style="display:none;">'+data+'</span>'+DateTime2Text(data); |
| 2572 | } |
| 2573 | }, |
| 2574 | {"data":"redeemed", "orderable":true, "className":"dt-center", "render":function(data, type, row) { |
| 2575 | if (data == 1) { |
| 2576 | return 'yes'; |
| 2577 | } else { |
| 2578 | return ''; |
| 2579 | } |
| 2580 | }}, |
| 2581 | {"data":"order_id", "className":"dt-right", "orderable":true}, |
| 2582 | {"data":null, "orderable":false, "className":"dt-center", "render":function(data, type, row){ |
| 2583 | return data.cvv === "" ? "" : '****'; |
| 2584 | }}, |
| 2585 | {"data":null, "orderable":true, "className":"dt-center", "render":function(data, type, row){ |
| 2586 | let _stat = ''; |
| 2587 | if (data.meta != "") { |
| 2588 | let metaObj = JSON.parse(data.meta); |
| 2589 | if (typeof metaObj['used'] !== "undefined") { |
| 2590 | if (metaObj.used.reg_request !== "") _stat = '/used'; |
| 2591 | } |
| 2592 | } |
| 2593 | if (data.aktiv === "2") return '<span style="color:red;">'+_x('stolen', 'label', 'event-tickets-with-ticket-scanner')+'</span>'+_stat; |
| 2594 | return data.aktiv === "1" ? '<span style="color:green;">'+__('active', 'event-tickets-with-ticket-scanner')+'</span>'+_stat : '<span style="color:grey;">'+_x('is inactiv', 'label', 'event-tickets-with-ticket-scanner')+'</span>'+_stat; |
| 2595 | }}, |
| 2596 | {"data":null,"orderable":false,"defaultContent":'',"className":"buttons dt-right", |
| 2597 | "render": function ( data, type, row ) { |
| 2598 | return '<button class="button-secondary" data-type="edit">'+_x('Edit', 'label', 'event-tickets-with-ticket-scanner')+'</button> <button class="button-secondary" data-type="delete">'+_x('Delete', 'label', 'event-tickets-with-ticket-scanner')+'</button>'; |
| 2599 | } |
| 2600 | } |
| 2601 | ]; |
| 2602 | let addition_column_offset = 0; |
| 2603 | if (_getOptions_isActivatedByKey('displayAdminAreaColumnBillingName')) { |
| 2604 | addition_column_offset++; |
| 2605 | table_columns.splice(3, 0, { |
| 2606 | "data":"_customer_name","orderable":false |
| 2607 | }); |
| 2608 | } |
| 2609 | if (_getOptions_isActivatedByKey('displayAdminAreaColumnBillingCompany')) { |
| 2610 | addition_column_offset++; |
| 2611 | table_columns.splice(3, 0, { |
| 2612 | "data":"_customer_company","orderable":false |
| 2613 | }); |
| 2614 | } |
| 2615 | if (_getOptions_isActivatedByKey('displayAdminAreaColumnConfirmedCount')) { |
| 2616 | addition_column_offset++; |
| 2617 | table_columns.splice(4+addition_column_offset, 0, { |
| 2618 | "data":null,"orderable":false,"defaultContent":'',"className":"dt-center", |
| 2619 | "render":function(data,type,row) { |
| 2620 | let ret = 0; |
| 2621 | let metaObj = getCodeObjectMeta(data); |
| 2622 | if(!metaObj) return ret; |
| 2623 | if (typeof metaObj.confirmedCount != "undefined") { |
| 2624 | ret = metaObj.confirmedCount; |
| 2625 | } |
| 2626 | return ret; |
| 2627 | } |
| 2628 | }); |
| 2629 | } |
| 2630 | if (_getOptions_isActivatedByKey('displayAdminAreaColumnRedeemedInfo')) { |
| 2631 | addition_column_offset++; |
| 2632 | table_columns.splice(5+addition_column_offset, 0, { |
| 2633 | "data":null,"orderable":false,"defaultContent":'',"className":"dt-center", |
| 2634 | "render":function(data,type,row) { |
| 2635 | let ret = ''; |
| 2636 | if (row._max_redeem_amount > 0) { |
| 2637 | ret = row._redeemed_counter+'/'+row._max_redeem_amount; |
| 2638 | } else { |
| 2639 | ret = row._redeemed_counter+'/unlimited'; |
| 2640 | } |
| 2641 | return ret; |
| 2642 | } |
| 2643 | }); |
| 2644 | } |
| 2645 | |
| 2646 | tabelle_codes_datatable = $(this.div_codes).find('#'+id_codes).DataTable({ |
| 2647 | "responsive": true, |
| 2648 | "search": { |
| 2649 | "search": typeof PARAS.code !== "undefined" ? encodeURIComponent(PARAS.code.trim()) : '' |
| 2650 | }, |
| 2651 | footerCallback: function(row, data, start, end, display) { |
| 2652 | let data_anser = tabelle_codes_datatable.ajax.json(); |
| 2653 | let text = sprintf(/* translators: 1: amount tickets 2: total amount tickets */__('Redeemed tickets: %1$d (filtered) of %2$d (total redeemed tickets)', 'event-tickets-with-ticket-scanner'), data_anser.redeemedRecordsFiltered, data_anser.redeemedRecordsTotal); |
| 2654 | var api = this.api(); |
| 2655 | $(api.column(1).footer()).html(text); |
| 2656 | //$(api.tables().footer()).html(text); |
| 2657 | }, |
| 2658 | "processing": true, |
| 2659 | "serverSide": true, |
| 2660 | "stateSave": false, |
| 2661 | "ajax": { |
| 2662 | "url": _requestURL('getCodes'), |
| 2663 | "type": 'GET' |
| 2664 | }, |
| 2665 | "order": [[ 4 + (additionalColumn.customerName != "" ? 1 : 0), "desc" ]], |
| 2666 | "columns": table_columns, |
| 2667 | "initComplete": function () { |
| 2668 | LAYOUT.renderSpinnerHide(); |
| 2669 | }, |
| 2670 | "autowidth":true |
| 2671 | }); |
| 2672 | tabelle_codes.on('click', 'button[data-type="edit"]', function (e) { |
| 2673 | let data = tabelle_codes_datatable.row( $(this).parents('tr') ).data(); |
| 2674 | __showMaskCode(data); |
| 2675 | }); |
| 2676 | tabelle_codes.on('click', 'button[data-type="delete"]', function (e) { |
| 2677 | let data = tabelle_codes_datatable.row( $(this).parents('tr') ).data(); |
| 2678 | LAYOUT.renderYesNo(_x('Do you want to delete?', 'title', 'event-tickets-with-ticket-scanner'), __('Are you sure, you want to delete this ticket?', 'event-tickets-with-ticket-scanner')+'<br><br><b>'+data.code+'</b>', ()=>{ |
| 2679 | let _data = {'id':data.id}; |
| 2680 | _makePost('removeCode', _data, result=>{ |
| 2681 | tabelle_codes_datatable.ajax.reload(); |
| 2682 | }); |
| 2683 | }); |
| 2684 | }); |
| 2685 | $('#'+id_codes+' tbody').on('click', 'td.details-control', function () { |
| 2686 | function ___format(d) { |
| 2687 | let metaObj = []; |
| 2688 | if (d.meta) { |
| 2689 | metaObj = JSON.parse(d.meta); |
| 2690 | } |
| 2691 | let div = $('<div/>'); |
| 2692 | |
| 2693 | // hole das aktuelle Metaobj |
| 2694 | function __getData(_codeObj) { |
| 2695 | div.html(_getSpinnerHTML()); |
| 2696 | _makeGet('getMetaOfCode',{'code':d.code}, dataMeta=>{ |
| 2697 | if (_codeObj) { // um eine Aktualisierung in das codeObj aufzunehmen |
| 2698 | _codeObj.meta = JSON.stringify(dataMeta); |
| 2699 | updateCodeObject(d, _codeObj); |
| 2700 | metaObj = getCodeObjectMeta(d); |
| 2701 | } |
| 2702 | |
| 2703 | div.html(""); |
| 2704 | d.meta = JSON.stringify(dataMeta); |
| 2705 | d.metaObj = dataMeta; |
| 2706 | |
| 2707 | let btn_grp = $('<div/>').addClass("btn-group").appendTo(div); |
| 2708 | $('<button>').html(_x('Display QR with ticket number', 'label', 'event-tickets-with-ticket-scanner')).appendTo(btn_grp).on("click", e=>{ |
| 2709 | let id = 'qrcode_'+d.code+'_'+time(); |
| 2710 | let content = _x('This QR image contains', 'label', 'event-tickets-with-ticket-scanner')+':<br><b>'+d.code+'</b><br><br><div id="'+id+'" style="text-align:center;"></div><script>jQuery("#'+id+'").qrcode("'+d.code+'");</script>'; |
| 2711 | LAYOUT.renderInfoBox(_x('QR with ticket number', 'title', 'event-tickets-with-ticket-scanner'), content); |
| 2712 | }); |
| 2713 | if (d.metaObj.wc_ticket.is_ticket && typeof d.metaObj.wc_ticket._public_ticket_id !== "undefined" && d.metaObj.wc_ticket._public_ticket_id != "") { |
| 2714 | $('<button>').html(_x('Display QR with PUBLIC ticket number', 'label', 'event-tickets-with-ticket-scanner')).appendTo(btn_grp).on("click", e=>{ |
| 2715 | let id = 'qrcode_'+d.code+'_'+time(); |
| 2716 | let content = _x('This QR image contains', 'label', 'event-tickets-with-ticket-scanner')+':<br><b>'+d.metaObj.wc_ticket._public_ticket_id+'</b><br>'+_x('Can be used with the ticket scanner', 'label', 'event-tickets-with-ticket-scanner')+'<br><br><div id="'+id+'" style="text-align:center;"></div><script>jQuery("#'+id+'").qrcode("'+d.metaObj.wc_ticket._public_ticket_id+'");</script>'; |
| 2717 | LAYOUT.renderInfoBox(_x('QR with ticket number', 'title', 'event-tickets-with-ticket-scanner'), content); |
| 2718 | }); |
| 2719 | } |
| 2720 | if (d.metaObj.wc_ticket.is_ticket && typeof d.metaObj.wc_ticket._qr_content !== "undefined" && d.metaObj.wc_ticket._qr_content != "") { |
| 2721 | $('<button>').html(_x('Display QR with your own QR content', 'label', 'event-tickets-with-ticket-scanner')).appendTo(btn_grp).on("click", e=>{ |
| 2722 | let id = 'qrcode_own_'+d.code+'_'+time(); |
| 2723 | let content = _x('This QR image contains', 'label', 'event-tickets-with-ticket-scanner')+':<br><b>'+d.metaObj.wc_ticket._qr_content+'</b><br>'+_x('Can be used with the ticket scanner', 'label', 'event-tickets-with-ticket-scanner')+'<br><br><div id="'+id+'" style="text-align:center;"></div><script>jQuery("#'+id+'").qrcode("'+d.metaObj.wc_ticket._qr_content+'");</script>'; |
| 2724 | LAYOUT.renderInfoBox(_x('QR with ticket number', 'title', 'event-tickets-with-ticket-scanner'), content); |
| 2725 | }); |
| 2726 | } |
| 2727 | if (typeof d.metaObj._QR != "undefined" && typeof d.metaObj._QR.directURL != "undefined" && d.metaObj._QR.directURL != "") { |
| 2728 | $('<button>').html(_x('Display QR with URL', 'label', 'event-tickets-with-ticket-scanner')).appendTo(btn_grp).on("click", e=>{ |
| 2729 | let id = 'qrcode_url_'+d.code+'_'+time(); |
| 2730 | let qr_content = d.metaObj._QR.directURL; |
| 2731 | let content = _x('This QR image contains', 'label', 'event-tickets-with-ticket-scanner')+':<br><b>'+qr_content+'</b><br><br><div id="'+id+'" style="text-align:center;"></div><script>jQuery("#'+id+'").qrcode("'+qr_content+'");</script>'; |
| 2732 | LAYOUT.renderInfoBox(_x('QR with URL and code', 'title', 'event-tickets-with-ticket-scanner'), content); |
| 2733 | }); |
| 2734 | } |
| 2735 | div.append('<div/>'); |
| 2736 | |
| 2737 | // male die Inhalte |
| 2738 | div.append('#'+d.id+'<br><b>'+_x('Created', 'label', 'event-tickets-with-ticket-scanner')+':</b> '+DateTime2Text(d.time)+' ('+d.time+')<br><b>'+__('Ticket number', 'event-tickets-with-ticket-scanner')+':</b> '+d.code+'<br><b>'+__('Ticket display number', 'event-tickets-with-ticket-scanner')+':</b> '+d.code_display+'<br><b>'+_x('Code Verification Value (CVV)', 'label', 'event-tickets-with-ticket-scanner')+':</b> '+(d.cvv == "" ? '-' : d.cvv)+'<br><b>'+_x('is active', 'event-tickets-with-ticket-scanner')+':</b> '+(parseInt(d.aktiv,10) === 1?'True':'False')); |
| 2739 | div.append(_displayCodeDetails(d, metaObj, tabelle_codes_datatable)); |
| 2740 | |
| 2741 | div.append('<h3>'+_x('WooCommerce Order', 'title', 'event-tickets-with-ticket-scanner')+'</h3>'); |
| 2742 | if (!_getOptions_Versions_isActivatedByKey("is_wc_available")) { |
| 2743 | div.append($("<div>").css("color", "red").html(__("WooCommerce not found", 'event-tickets-with-ticket-scanner'))); |
| 2744 | } |
| 2745 | div.append('<b>'+_x('OrderId', 'label', 'event-tickets-with-ticket-scanner')+':</b> ' + (parseInt(d.order_id) === 0 ? '-' : '#'+d.order_id+' <a target="_blank" href="post.php?post='+d.order_id+'&action=edit">'+_x('Show in WooCommerce Orders', 'label', 'event-tickets-with-ticket-scanner')+'</a>')); |
| 2746 | if (typeof metaObj['woocommerce'] !== "undefined") { |
| 2747 | if (metaObj.woocommerce.order_id !== 0) { |
| 2748 | div.append($("<div>").html('<b>'+_x('Order from', 'label', 'event-tickets-with-ticket-scanner')+':</b> ').append($('<span>').text(DateTime2Text(metaObj.woocommerce.creation_date)+' ('+metaObj.woocommerce.creation_date+')'))); |
| 2749 | div.append($("<div>").html('<b>'+_x('Product Id', 'label', 'event-tickets-with-ticket-scanner')+':</b> ').append($('<span>').html(metaObj.woocommerce.product_id+' <a target="_blank" href="post.php?post='+encodeURIComponent(metaObj.woocommerce.product_id)+'&action=edit">'+_x('Show Product', 'label', 'event-tickets-with-ticket-scanner')+'</a>'))); |
| 2750 | } |
| 2751 | } |
| 2752 | if (parseInt(d.order_id) > 0) { |
| 2753 | div.append($('<div style="margin-top:10px;">').html($('<button>').addClass("button-delete").html(_x('Delete WooCommerce order info for this ticket', 'label', 'event-tickets-with-ticket-scanner')).on("click", ()=>{ |
| 2754 | LAYOUT.renderYesNo(_x('Remove order', 'title', 'event-tickets-with-ticket-scanner'), sprintf(/* translators: %s: ticket number */__('Do you really want to remove your order information of this ticket "%s"? This will also remove the ticket number from the order! For the PREMIUM PLUGIN: It will only remove it from the position of the order. If you have in one order more than one item with ticket number, then it will only remove the ticket number(s) from this item on the order. For the BASIC PLUGIN, it will remove all tickets from all items on this order. Click OK to proceed the removal.', 'event-tickets-with-ticket-scanner'), d.code_display), ()=>{ |
| 2755 | _makeGet('removeWoocommerceOrderInfoFromCode', {'code':d.code}, _codeObj=>{ |
| 2756 | //tabelle_codes_datatable.ajax.reload(); |
| 2757 | __getData(_codeObj); |
| 2758 | }); |
| 2759 | }); |
| 2760 | }))); |
| 2761 | } |
| 2762 | |
| 2763 | div.append('<h4>'+__('WooCommerce ticket sale', 'event-tickets-with-ticket-scanner')+'</h4>'); |
| 2764 | div.append(_displayWCETicket(d, tabelle_codes_datatable)); |
| 2765 | |
| 2766 | div.append('<h3>'+__('WooCommerce Purchase Restriction', 'event-tickets-with-ticket-scanner')+'</h3>'); |
| 2767 | if (typeof metaObj['wc_rp'] !== "undefined") { |
| 2768 | if (metaObj.wc_rp.order_id !== 0) { |
| 2769 | div.append($("<div>").html('<b>'+_x('Used for Order ID', 'label', 'event-tickets-with-ticket-scanner')+':</b> ').append($('<span>').html('#'+metaObj.wc_rp.order_id+' <a target="_blank" href="post.php?post='+encodeURIComponent(metaObj.wc_rp.order_id)+'&action=edit">'+_x('Open WooCommerce Order', 'label', 'event-tickets-with-ticket-scanner')+'</a>'))); |
| 2770 | div.append($("<div>").html('<b>'+_x('Order from', 'label', 'event-tickets-with-ticket-scanner')+':</b> ').append($('<span>').text(metaObj.wc_rp.creation_date))); |
| 2771 | div.append($("<div>").html('<b>'+_x('Product Id', 'label', 'event-tickets-with-ticket-scanner')+'s:</b> ').append($('<span>').html(metaObj.wc_rp.product_id+' <a target="_blank" href="post.php?post='+encodeURIComponent(metaObj.wc_rp.product_id)+'&action=edit">'+_x('Show Product', 'label', 'event-tickets-with-ticket-scanner')+'</a>'))); |
| 2772 | div.append($('<div style="margin-top:10px;">').html($('<button>').addClass("button-delete").html(__('Remove purchase ticket information', 'event-tickets-with-ticket-scanner')).on("click", ()=>{ |
| 2773 | LAYOUT.renderYesNo(__('Remove purchase ticket information', 'event-tickets-with-ticket-scanner'), sprintf(/* translators: %s: ticket nummer */__('Do you really want to remove the purchase ticket information from the order of this ticket "%s"? This will remove the also the ticket(s) from the order items! This ticket can then be reused for purchases. Click OK to proceed the removal.', 'event-tickets-with-ticket-scanner'), d.code_display), ()=>{ |
| 2774 | _makeGet('removeWoocommerceRstrPurchaseInfoFromCode', {'code':d.code}, _codeObj=>{ |
| 2775 | //tabelle_codes_datatable.ajax.reload(); |
| 2776 | __getData(_codeObj); |
| 2777 | }); |
| 2778 | }); |
| 2779 | }))); |
| 2780 | } else { |
| 2781 | div.append($("<div>").html('<b>'+_x('Used for Order ID', 'label', 'event-tickets-with-ticket-scanner')+':</b> -')); |
| 2782 | } |
| 2783 | } |
| 2784 | |
| 2785 | div.append('<h3>'+_x('Registered user', 'title', 'event-tickets-with-ticket-scanner')+'</h3>'); |
| 2786 | div.append(_displayRegisteredUserForCode(d, metaObj, tabelle_codes_datatable)); |
| 2787 | |
| 2788 | div.append('<h3>Redeem operations</h3>'); |
| 2789 | div.append(_displayRedeemOperationsForCode(d, metaObj)); |
| 2790 | |
| 2791 | div.append('<h3>'+_x('IP list checked for this ticket', 'title', 'event-tickets-with-ticket-scanner')+'</h3>'); |
| 2792 | if (isPremium()) { |
| 2793 | div.append(PREMIUM.displayTrackedIPsForCode(d.code)); |
| 2794 | } else { |
| 2795 | div.append(getLabelPremiumOnly()); |
| 2796 | } |
| 2797 | |
| 2798 | if (isPremium() && PREMIUM.displayCodeDetailsAtEnd) div.append(PREMIUM.displayCodeDetailsAtEnd(d, tabelle_codes_datatable, metaObj)); |
| 2799 | |
| 2800 | div.append("<hr>"); |
| 2801 | }); |
| 2802 | } |
| 2803 | __getData(); |
| 2804 | return div; |
| 2805 | } |
| 2806 | |
| 2807 | var tr = $(this).closest('tr'); |
| 2808 | var row = tabelle_codes_datatable.row( tr ); |
| 2809 | if ( row.child.isShown() ) { |
| 2810 | // This row is already open - close it |
| 2811 | row.child.hide(); |
| 2812 | tr.removeClass('shown'); |
| 2813 | } else { |
| 2814 | // Open this row |
| 2815 | row.child( ___format(row.data()) ).show(); |
| 2816 | tr.addClass('shown'); |
| 2817 | } |
| 2818 | }); |
| 2819 | cbf && cbf(); |
| 2820 | }); // end getOptions |
| 2821 | } // render layout |
| 2822 | |
| 2823 | renderInfoBox(title, content, displayPlain) { |
| 2824 | let _options = { |
| 2825 | title: title, |
| 2826 | modal: true, |
| 2827 | minWidth: 400, |
| 2828 | minHeight: 200, |
| 2829 | buttons: [{text:_x('Ok', 'label', 'event-tickets-with-ticket-scanner'), |
| 2830 | click: function() { |
| 2831 | $(this).dialog("close"); |
| 2832 | $(this).html(""); |
| 2833 | }}] |
| 2834 | }; |
| 2835 | let dlg = $('<div/>'); |
| 2836 | if (displayPlain) { |
| 2837 | dlg.text(content); |
| 2838 | } else { |
| 2839 | dlg.html(content); |
| 2840 | } |
| 2841 | dlg.dialog(_options); |
| 2842 | return dlg; |
| 2843 | } |
| 2844 | renderSpinnerShow() { |
| 2845 | this.div_spinner.css("display", "block"); |
| 2846 | } |
| 2847 | renderSpinnerHide() { |
| 2848 | this.div_spinner.css("display", "none"); |
| 2849 | } |
| 2850 | renderFatalError(content) { |
| 2851 | return LAYOUT.renderInfoBox(_x('Error', 'title', 'event-tickets-with-ticket-scanner'), content); |
| 2852 | } |
| 2853 | renderYesNo(title, content, cbfYes, cbfNo) { |
| 2854 | let _options = { |
| 2855 | title: title, |
| 2856 | modal: true, |
| 2857 | minWidth: 400, |
| 2858 | minHeight: 200, |
| 2859 | buttons: [{text:_x('Yes', 'label', 'event-tickets-with-ticket-scanner'), click:function(){ |
| 2860 | $(this).dialog("close"); |
| 2861 | $(this).html(""); |
| 2862 | cbfYes && cbfYes(dlg); |
| 2863 | }},{text:_x('No', 'label', 'event-tickets-with-ticket-scanner'), click:function(){ |
| 2864 | $(this).dialog("close"); |
| 2865 | $(this).html(""); |
| 2866 | cbfNo && cbfNo(); |
| 2867 | }}] |
| 2868 | }; |
| 2869 | let dlg = $('<div/>').html(content); |
| 2870 | dlg.dialog(_options); |
| 2871 | return dlg; |
| 2872 | } |
| 2873 | } |
| 2874 | |
| 2875 | function _displayCodeDetails(codeObj, metaObj, tabelle) { |
| 2876 | let div = $('<div/>'); |
| 2877 | function __getData(_codeObj) { |
| 2878 | if (_codeObj) { // um eine Aktualisierung in das codeObj aufzunehmen |
| 2879 | updateCodeObject(codeObj, _codeObj); |
| 2880 | } |
| 2881 | |
| 2882 | div.html(""); |
| 2883 | if (codeObj.meta !== "") { |
| 2884 | let metaObj = getCodeObjectMeta(codeObj); |
| 2885 | if (typeof metaObj.confirmedCount !== "undefined") { |
| 2886 | div.append($('<div/>').html('<b>Confirmed count:</b> '+metaObj.confirmedCount)); |
| 2887 | if (metaObj.confirmedCount > 0 && metaObj.validation) { |
| 2888 | if (metaObj.validation.first_success != "") { |
| 2889 | div.append($('<div/>').html('<b>First successful validation at:</b> '+metaObj.validation.first_success)); |
| 2890 | div.append($('<div/>').html('<b>First successful validation IP:</b> '+metaObj.validation.first_ip)); |
| 2891 | } |
| 2892 | if (metaObj.validation.last_success != "" && metaObj.validation.last_success != metaObj.validation.first_success) { |
| 2893 | div.append($('<div/>').html('<b>Last successful validation at:</b> '+metaObj.validation.last_success)); |
| 2894 | div.append($('<div/>').html('<b>Last successful validation IP:</b> '+metaObj.validation.last_ip)); |
| 2895 | } |
| 2896 | } |
| 2897 | } |
| 2898 | let btngrp = $('<div style="margin-top:10px;">'); |
| 2899 | if (typeof metaObj.used !== "undefined") { |
| 2900 | div.append("<h3>Code marked as used</h3>"); |
| 2901 | if (metaObj.used.reg_request !== "") { |
| 2902 | div.append($("<div>").html("<b>Request from:</b> ").append($('<span>').text(DateTime2Text(metaObj.used.reg_request)+' ('+metaObj.used.reg_request+')'))); |
| 2903 | div.append($("<div>").html("<b>Request by wordpress user:</b> ").append($('<span>').text(metaObj.used.reg_userid))); |
| 2904 | if (metaObj.used._reg_username) div.append($("<div>").html("<b>Request by wordpress user:</b> ").append($('<span>').text(metaObj.used._reg_username))); |
| 2905 | div.append($("<div>").html("<b>Request from IP:</b> ").append($('<span>').text(metaObj.used.reg_ip))); |
| 2906 | |
| 2907 | btngrp.append($('<button/>').addClass("button-delete").html('Delete ticket used information').on("click", function(){ |
| 2908 | LAYOUT.renderYesNo('Remove usage information', 'Do you really want to remove the usage information of this ticket "'+codeObj.code_display+'"? This will also reset the "Confirmed count" to 0.', ()=>{ |
| 2909 | _makeGet('removeUsedInformationFromCode', {'code':codeObj.code}, _codeObj=>{ |
| 2910 | //tabelle.ajax.reload(); |
| 2911 | __getData(_codeObj); |
| 2912 | }); |
| 2913 | }); |
| 2914 | })); |
| 2915 | } else { |
| 2916 | div.append("Not used - still available"); |
| 2917 | } |
| 2918 | |
| 2919 | btngrp.append($('<button/>').addClass("button-edit").html('Edit wordpress user information').on("click", function(){ |
| 2920 | // display eingabe maske für userid |
| 2921 | function __showMask(){ |
| 2922 | let _options = { |
| 2923 | title: 'Edit requested wordpress user', |
| 2924 | modal: true, |
| 2925 | minWidth: 400, |
| 2926 | minHeight: 200, |
| 2927 | buttons: [ |
| 2928 | { |
| 2929 | id: 'okBtn', |
| 2930 | text: "Ok", |
| 2931 | click: function() { |
| 2932 | ___submitForm(); |
| 2933 | } |
| 2934 | }, |
| 2935 | { |
| 2936 | text: "Cancel", |
| 2937 | click: function() { |
| 2938 | $( this ).dialog( "close" ); |
| 2939 | $( this ).html(''); |
| 2940 | } |
| 2941 | } |
| 2942 | ] |
| 2943 | }; |
| 2944 | let dlg = $('<div />'); |
| 2945 | let form = $('<form />').appendTo(dlg); |
| 2946 | |
| 2947 | let elem_userid = $('<input type="number" min="0" value="'+metaObj.used.reg_userid+'" />'); |
| 2948 | $('<div/>').css({"margin-top":"10px","margin-bottom": "15px","margin-right": "15px"}) |
| 2949 | .html('Requested wordpress userid<br>') |
| 2950 | .append(elem_userid) |
| 2951 | .appendTo(form); |
| 2952 | |
| 2953 | dlg.append('<p>Changes will trigger the webhook, if activated.<br>The IP will be updated too. The requested date will only be changed, if it was not set already.</p>'); |
| 2954 | dlg.dialog(_options); |
| 2955 | |
| 2956 | form.on("submit", function(event) { |
| 2957 | event.preventDefault(); |
| 2958 | ___submitForm(); |
| 2959 | }); |
| 2960 | function ___submitForm() { |
| 2961 | let reg_userid = intval(elem_userid.val().trim()); |
| 2962 | dlg.html(_getSpinnerHTML()); |
| 2963 | let _data = {"reg_userid":reg_userid}; |
| 2964 | form[0].reset(); |
| 2965 | _data.code = codeObj.code; |
| 2966 | $('#okBtn').remove(); |
| 2967 | _makeGet('editUseridForUsedInformationFromCode', _data, _codeObj=>{ |
| 2968 | //tabelle.ajax.reload(); |
| 2969 | __getData(_codeObj); |
| 2970 | closeDialog(dlg); |
| 2971 | }, function() { |
| 2972 | closeDialog(dlg); |
| 2973 | }); |
| 2974 | } |
| 2975 | } // ende __showMask |
| 2976 | __showMask(); |
| 2977 | })); // end button-edit |
| 2978 | } |
| 2979 | div.append(btngrp); |
| 2980 | |
| 2981 | if (isPremium()) div.append(PREMIUM.displayCodeDetails(codeObj, tabelle, metaObj)); |
| 2982 | } // endif codeObj.meta !== "" |
| 2983 | } |
| 2984 | __getData(); |
| 2985 | return div; |
| 2986 | } |
| 2987 | |
| 2988 | function _displayWCETicket(codeObj, tabelle) { |
| 2989 | let div = $('<div/>'); |
| 2990 | function __getData(_codeObj) { |
| 2991 | if (_codeObj) { // um eine Aktualisierung in das codeObj aufzunehmen |
| 2992 | updateCodeObject(codeObj, _codeObj); |
| 2993 | } |
| 2994 | |
| 2995 | div.html(""); |
| 2996 | let metaObj = getCodeObjectMeta(codeObj); |
| 2997 | if(metaObj) { |
| 2998 | if (typeof metaObj.wc_ticket != "undefined" && typeof metaObj.wc_ticket.day_per_ticket != "undefined") { |
| 2999 | div.append($('<div>').html('<b>Date per Ticket (choosen by customer):</b> '+metaObj.wc_ticket.day_per_ticket +" ").append( |
| 3000 | $("<button>").html("Edit").on("click", ()=>{ |
| 3001 | |
| 3002 | let _options = { |
| 3003 | title: 'Edit Ticket Date', |
| 3004 | modal: true, |
| 3005 | minWidth: 400, |
| 3006 | minHeight: 200, |
| 3007 | buttons: [ |
| 3008 | { |
| 3009 | id: 'okBtn', |
| 3010 | text: "Ok", |
| 3011 | click: function() { |
| 3012 | ___submitForm(); |
| 3013 | } |
| 3014 | }, |
| 3015 | { |
| 3016 | text: "Cancel", |
| 3017 | click: function() { |
| 3018 | $( this ).dialog( "close" ); |
| 3019 | $( this ).html(''); |
| 3020 | } |
| 3021 | } |
| 3022 | ] |
| 3023 | }; |
| 3024 | let dlg = $('<div />'); |
| 3025 | let form = $('<form />').appendTo(dlg); |
| 3026 | |
| 3027 | let elem_input = $('<input type="date" value="'+metaObj.wc_ticket.day_per_ticket+'" />'); |
| 3028 | $('<div/>').css({"margin-top":"10px","margin-bottom": "15px","margin-right": "15px"}) |
| 3029 | .html('Date per Ticket (yyyy-mm-dd).<br><b>Very important to not break the date format and syntax, if you want to change the date!</b><br>') |
| 3030 | .append(elem_input) |
| 3031 | .appendTo(form); |
| 3032 | |
| 3033 | dlg.dialog(_options); |
| 3034 | |
| 3035 | form.on("submit", function(event) { |
| 3036 | event.preventDefault(); |
| 3037 | ___submitForm(); |
| 3038 | }); |
| 3039 | function ___submitForm() { |
| 3040 | let v = elem_input.val().trim(); |
| 3041 | dlg.html(_getSpinnerHTML()); |
| 3042 | let _data = {"value":v, "key":'wc_ticket.day_per_ticket'}; |
| 3043 | form[0].reset(); |
| 3044 | _data.code = codeObj.code; |
| 3045 | $('#okBtn').remove(); |
| 3046 | _makeGet('editTicketMetaEntry', _data, _codeObj=>{ |
| 3047 | //tabelle.ajax.reload(); |
| 3048 | __getData(_codeObj); |
| 3049 | closeDialog(dlg); |
| 3050 | }, function() { |
| 3051 | closeDialog(dlg); |
| 3052 | }); |
| 3053 | } |
| 3054 | }) |
| 3055 | )); |
| 3056 | } |
| 3057 | if (typeof metaObj.wc_ticket != "undefined" && typeof metaObj.wc_ticket.name_per_ticket != "undefined") { |
| 3058 | div.append($('<div>').html('<b>Name per Ticket (product detail setting):</b> '+metaObj.wc_ticket.name_per_ticket +" ").append( |
| 3059 | $("<button>").html("Edit").on("click", ()=>{ |
| 3060 | |
| 3061 | let _options = { |
| 3062 | title: 'Edit Ticket Name', |
| 3063 | modal: true, |
| 3064 | minWidth: 400, |
| 3065 | minHeight: 200, |
| 3066 | buttons: [ |
| 3067 | { |
| 3068 | id: 'okBtn', |
| 3069 | text: "Ok", |
| 3070 | click: function() { |
| 3071 | ___submitForm(); |
| 3072 | } |
| 3073 | }, |
| 3074 | { |
| 3075 | text: "Cancel", |
| 3076 | click: function() { |
| 3077 | $( this ).dialog( "close" ); |
| 3078 | $( this ).html(''); |
| 3079 | } |
| 3080 | } |
| 3081 | ] |
| 3082 | }; |
| 3083 | let dlg = $('<div />'); |
| 3084 | let form = $('<form />').appendTo(dlg); |
| 3085 | |
| 3086 | let elem_input = $('<input type="text" value="'+metaObj.wc_ticket.name_per_ticket+'" />'); |
| 3087 | $('<div/>').css({"margin-top":"10px","margin-bottom": "15px","margin-right": "15px"}) |
| 3088 | .html('Name per Ticket<br>') |
| 3089 | .append(elem_input) |
| 3090 | .appendTo(form); |
| 3091 | |
| 3092 | dlg.dialog(_options); |
| 3093 | |
| 3094 | form.on("submit", function(event) { |
| 3095 | event.preventDefault(); |
| 3096 | ___submitForm(); |
| 3097 | }); |
| 3098 | function ___submitForm() { |
| 3099 | let v = elem_input.val().trim(); |
| 3100 | dlg.html(_getSpinnerHTML()); |
| 3101 | let _data = {"value":v, "key":'wc_ticket.name_per_ticket'}; |
| 3102 | form[0].reset(); |
| 3103 | _data.code = codeObj.code; |
| 3104 | $('#okBtn').remove(); |
| 3105 | _makeGet('editTicketMetaEntry', _data, _codeObj=>{ |
| 3106 | //tabelle.ajax.reload(); |
| 3107 | __getData(_codeObj); |
| 3108 | closeDialog(dlg); |
| 3109 | }, function() { |
| 3110 | closeDialog(dlg); |
| 3111 | }); |
| 3112 | } |
| 3113 | }) |
| 3114 | )); |
| 3115 | } |
| 3116 | if (typeof metaObj.wc_ticket != "undefined" && typeof metaObj.wc_ticket.value_per_ticket != "undefined") { |
| 3117 | div.append($('<div>').html('<b>Value per Ticket (product detail setting):</b> '+metaObj.wc_ticket.value_per_ticket +" ").append( |
| 3118 | $("<button>").html("Edit").on("click", ()=>{ |
| 3119 | |
| 3120 | let _options = { |
| 3121 | title: 'Edit Ticket Value', |
| 3122 | modal: true, |
| 3123 | minWidth: 400, |
| 3124 | minHeight: 200, |
| 3125 | buttons: [ |
| 3126 | { |
| 3127 | id: 'okBtn', |
| 3128 | text: "Ok", |
| 3129 | click: function() { |
| 3130 | ___submitForm(); |
| 3131 | } |
| 3132 | }, |
| 3133 | { |
| 3134 | text: "Cancel", |
| 3135 | click: function() { |
| 3136 | $( this ).dialog( "close" ); |
| 3137 | $( this ).html(''); |
| 3138 | } |
| 3139 | } |
| 3140 | ] |
| 3141 | }; |
| 3142 | let dlg = $('<div />'); |
| 3143 | let form = $('<form />').appendTo(dlg); |
| 3144 | |
| 3145 | let elem_input = $('<input type="text" value="'+metaObj.wc_ticket.value_per_ticket+'" />'); |
| 3146 | $('<div/>').css({"margin-top":"10px","margin-bottom": "15px","margin-right": "15px"}) |
| 3147 | .html('Value per Ticket<br>') |
| 3148 | .append(elem_input) |
| 3149 | .appendTo(form); |
| 3150 | |
| 3151 | dlg.dialog(_options); |
| 3152 | |
| 3153 | form.on("submit", function(event) { |
| 3154 | event.preventDefault(); |
| 3155 | ___submitForm(); |
| 3156 | }); |
| 3157 | function ___submitForm() { |
| 3158 | let v = elem_input.val().trim(); |
| 3159 | dlg.html(_getSpinnerHTML()); |
| 3160 | let _data = {"value":v, "key":'wc_ticket.value_per_ticket'}; |
| 3161 | form[0].reset(); |
| 3162 | _data.code = codeObj.code; |
| 3163 | $('#okBtn').remove(); |
| 3164 | _makeGet('editTicketMetaEntry', _data, _codeObj=>{ |
| 3165 | //tabelle.ajax.reload(); |
| 3166 | __getData(_codeObj); |
| 3167 | closeDialog(dlg); |
| 3168 | }, function() { |
| 3169 | closeDialog(dlg); |
| 3170 | }); |
| 3171 | } |
| 3172 | }) |
| 3173 | )); |
| 3174 | } |
| 3175 | if (typeof metaObj['woocommerce'] !== "undefined" && metaObj.woocommerce.order_id !== 0 && typeof metaObj.wc_ticket !== "undefined") { |
| 3176 | if (metaObj.wc_ticket.set_by_admin > 0) { |
| 3177 | div.append($("<div>").html("<b>Ticket set by admin user:</b> ").append($('<span>').text(metaObj.wc_ticket._set_by_admin_username+' ('+metaObj.wc_ticket.set_by_admin+') '+metaObj.wc_ticket.set_by_admin_date))); |
| 3178 | } |
| 3179 | if (metaObj.wc_ticket.redeemed_date != '') { |
| 3180 | div.append($("<div>").html("<b>Redeemed at:</b> ").append($('<span>').text(DateTime2Text(metaObj.wc_ticket.redeemed_date)+' ('+metaObj.wc_ticket.redeemed_date+')'))); |
| 3181 | div.append($("<div>").html("<b>Redeemed by wordpress userid:</b> ").append($('<span>').text(metaObj.wc_ticket.userid))); |
| 3182 | if (metaObj.wc_ticket._username) div.append($("<div>").html("<b>Redeemed by wordpress user:</b> ").append($('<span>').text(metaObj.wc_ticket._username))); |
| 3183 | div.append($("<div>").html("<b>IP while redeemed:</b> ").append($('<span>').text(metaObj.wc_ticket.ip))); |
| 3184 | if (metaObj.wc_ticket.redeemed_by_admin > 0) { |
| 3185 | div.append($("<div>").html("<b>Redeemed by admin user:</b> ").append($('<span>').text(metaObj.wc_ticket._redeemed_by_admin_username+' ('+metaObj.wc_ticket.redeemed_by_admin+')'))); |
| 3186 | } |
| 3187 | } |
| 3188 | if (metaObj.wc_ticket.is_ticket == 1) { |
| 3189 | let _max_redeem_amount = typeof metaObj.wc_ticket._max_redeem_amount !== "undefined" ? metaObj.wc_ticket._max_redeem_amount : 1; |
| 3190 | $("<div>").html("<b>Ticket number: </b>"+codeObj.code_display).appendTo(div); |
| 3191 | $("<div>").html("<b>Public Ticket number: </b>"+metaObj.wc_ticket._public_ticket_id).appendTo(div); |
| 3192 | if (typeof metaObj.wc_ticket.stats_redeemed !== "undefined") { |
| 3193 | $("<div>").html("<b>Redeem usage: </b>"+metaObj.wc_ticket.stats_redeemed.length + ' of ' + (_max_redeem_amount == 0 ? 'unlimited' : _max_redeem_amount)).appendTo(div); |
| 3194 | } |
| 3195 | $("<div>").html('<b>Ticket Page:</b> <a target="_blank" href="'+metaObj.wc_ticket._url+'">Open Ticket Detail Page</a>').appendTo(div); |
| 3196 | $("<div>").html('<b>Ticket Page Testmode:</b> <a target="_blank" href="'+metaObj.wc_ticket._url+'?testDesigner=1">Open Ticket Detail Page with template test code</a>').appendTo(div); |
| 3197 | $("<div>").html('<b>Ticket PDF:</b> <a target="_blank" href="'+metaObj.wc_ticket._url+'?pdf">Open Ticket PDF</a>').appendTo(div); |
| 3198 | $("<div>").html('<b>Ticket PDF Testmode:</b> <a target="_blank" href="'+metaObj.wc_ticket._url+'?pdf&testDesigner=1">Open Ticket PDF with template test code</a>').appendTo(div); |
| 3199 | $("<div>").html('<b>Order Ticket Page:</b> <a target="_blank" href="'+metaObj.wc_ticket._order_page_url+'">Open Order Ticket Page</a>').appendTo(div); |
| 3200 | $("<div>").html('<b>Order PDF:</b> <a target="_blank" href="'+metaObj.wc_ticket._order_url+'">Open Order Ticket PDF</a>').appendTo(div); |
| 3201 | } |
| 3202 | |
| 3203 | let btngrp = $('<div style="margin-top:10px;">').appendTo(div); |
| 3204 | if (metaObj.wc_ticket.is_ticket == 1) { |
| 3205 | $('<button>').html("Download PDF").appendTo(btngrp).on("click", ()=>{ |
| 3206 | _downloadFile('downloadPDFTicket', {'code':codeObj.code}, "eventticket_"+codeObj.code+".pdf"); |
| 3207 | return false; |
| 3208 | }); |
| 3209 | $('<button>').html("Download Ticket Badge").appendTo(btngrp).on("click", ()=>{ |
| 3210 | _downloadFile('downloadPDFTicketBadge', {'code':codeObj.code}, "eventticket_badge_"+codeObj.code+".pdf"); |
| 3211 | return false; |
| 3212 | }); |
| 3213 | $('<button>').html("Display QR with URL to PDF").appendTo(btngrp).on("click", e=>{ |
| 3214 | let id = 'qrcode_'+codeObj.code+'_'+time(); |
| 3215 | let content = 'This QR image contains:<br><b>'+codeObj.code+'</b><br><br><div id="'+id+'" style="text-align:center;"></div><script>jQuery("#'+id+'").qrcode("'+metaObj.wc_ticket._url+'?pdf");</script>'; |
| 3216 | LAYOUT.renderInfoBox('QR with URL to PDF', content); |
| 3217 | }); |
| 3218 | } |
| 3219 | if (metaObj.wc_ticket.is_ticket == 0) { |
| 3220 | $('<button>').html("Set as ticket sale").on("click", ()=>{ |
| 3221 | LAYOUT.renderYesNo('Set as a ticket', 'Do you want to set this purchased ticket number as a ticket sale?', ()=>{ |
| 3222 | _makeGet('setWoocommerceTicketForCode', {'code':codeObj.code}, _codeObj=>{ |
| 3223 | __getData(_codeObj); |
| 3224 | }); |
| 3225 | }); |
| 3226 | }).appendTo(btngrp); |
| 3227 | } |
| 3228 | let btn_redeem = $('<button>').addClass("button-delete").html('Redeem ticket').on("click", ()=>{ |
| 3229 | let reg_userid = (metaObj.user && metaObj.user.reg_userid) ? metaObj.user.reg_userid : 0; |
| 3230 | LAYOUT.renderYesNo('Redeem ticket', 'Do you really want to redeem the ticket number "'+codeObj.code_display+'"? Click OK to redeem the ticket.', ()=>{ |
| 3231 | let userid = prompt('Optional. You can enter a userid you redeem the ticket for', reg_userid); |
| 3232 | _makeGet('redeemWoocommerceTicketForCode', {'code':codeObj.code, 'userid':userid}, _codeObj=>{ |
| 3233 | __getData(_codeObj); |
| 3234 | }); |
| 3235 | }); |
| 3236 | }).appendTo(btngrp); |
| 3237 | let _max_redeem_amount = typeof metaObj.wc_ticket._max_redeem_amount !== "undefined" ? metaObj.wc_ticket._max_redeem_amount : 1; |
| 3238 | if (metaObj.wc_ticket.is_ticket == 0 || _max_redeem_amount == 0 || metaObj.wc_ticket.stats_redeemed.length >= _max_redeem_amount) { |
| 3239 | btn_redeem.attr("disabled", true); |
| 3240 | } |
| 3241 | |
| 3242 | let btn_unredeem = $('<button>').addClass("button-delete").html('Delete redeem information').on("click", ()=>{ |
| 3243 | LAYOUT.renderYesNo('Remove ticket information', 'Do you really want to remove the information that the ticket number "'+codeObj.code_display+'" is redeemed? Click OK to un-redeem the ticket and allow your customer to use the ticket again.', ()=>{ |
| 3244 | _makeGet('removeRedeemWoocommerceTicketForCode', {'code':codeObj.code}, _codeObj=>{ |
| 3245 | __getData(_codeObj); |
| 3246 | }); |
| 3247 | }); |
| 3248 | }).appendTo(btngrp); |
| 3249 | if (metaObj.wc_ticket.is_ticket == 0 || metaObj.wc_ticket.redeemed_date == "") { |
| 3250 | btn_unredeem.attr("disabled", true); |
| 3251 | } |
| 3252 | if (metaObj.wc_ticket.is_ticket == 1 && metaObj.wc_ticket.redeemed_date == "") { |
| 3253 | $('<button>').addClass("button-delete").html("Unset Ticket").on("click", ()=>{ |
| 3254 | LAYOUT.renderYesNo('Remove ticket', 'Do you really want to remove the ticket info from this ticket number? The WooCommerce sale will be set and you need to remove it manually.', ()=>{ |
| 3255 | _makeGet('removeWoocommerceTicketForCode', {'code':codeObj.code}, _codeObj=>{ |
| 3256 | __getData(_codeObj); |
| 3257 | }); |
| 3258 | }); |
| 3259 | }).appendTo(btngrp); |
| 3260 | } |
| 3261 | } |
| 3262 | } |
| 3263 | } |
| 3264 | __getData(); |
| 3265 | return div; |
| 3266 | } |
| 3267 | |
| 3268 | function _displayRedeemOperationsForCode(d, metaObj) { |
| 3269 | let div = $('<div/>'); |
| 3270 | if (typeof metaObj.wc_ticket.stats_redeemed !== "undefined") { |
| 3271 | if (metaObj.wc_ticket.stats_redeemed.length > 0) { |
| 3272 | let t = $('<table>').appendTo(div); |
| 3273 | t.html('<tr><th>#</th><th>Date</th><th>IP</th><th>By admin</th><th>User ID</th></tr>').appendTo(t); |
| 3274 | metaObj.wc_ticket.stats_redeemed.forEach((v,idx)=>{ |
| 3275 | let tr = $('<tr>').appendTo(t); |
| 3276 | $('<td>').html('#'+(idx+1)).appendTo(tr); |
| 3277 | $('<td>').html(DateTime2Text(v.redeemed_date)+' ('+v.redeemed_date+')').appendTo(tr); |
| 3278 | $('<td>').html(v.ip).appendTo(tr); |
| 3279 | $('<td>').html(v.redeemed_by_admin == 1 ? 'Yes' : 'No').appendTo(tr); |
| 3280 | $('<td>').html(v.userid).appendTo(tr); |
| 3281 | }); |
| 3282 | } else { |
| 3283 | div.html("no redeem operations yet"); |
| 3284 | } |
| 3285 | } |
| 3286 | return div; |
| 3287 | } |
| 3288 | |
| 3289 | function _displayRegisteredUserForCode(codeObj, metaObj, tabelle) { |
| 3290 | let div = $('<div/>'); |
| 3291 | function __getData(_codeObj) { |
| 3292 | if (_codeObj) { // um eine Aktualisierung in das codeObj aufzunehmen |
| 3293 | updateCodeObject(codeObj, _codeObj); |
| 3294 | } |
| 3295 | div.html(""); |
| 3296 | let btngrp = $('<div style="margin-top:10px;">'); |
| 3297 | if (typeof codeObj.meta !== "undefined" && codeObj.meta !== "") { |
| 3298 | let metaObj = getCodeObjectMeta(codeObj); |
| 3299 | if (metaObj.user.reg_request !== "") { |
| 3300 | div.append($("<div>").html("<b>Register value:</b> ").append($('<span>').text(metaObj.user.value))); |
| 3301 | div.append($("<div>").html("<b>Register by wordpress userid:</b> ").append($('<span>').text(metaObj.user.reg_userid))); |
| 3302 | if (metaObj.user._reg_username) div.append($("<div>").html("<b>Register by wordpress user:</b> ").append($('<span>').text(metaObj.user._reg_username))); |
| 3303 | div.append($("<div>").html("<b>Request from:</b> ").append($('<span>').text(metaObj.user.reg_request))); |
| 3304 | div.append($("<div>").html("<b>Request from IP:</b> ").append($('<span>').text(metaObj.user.reg_ip))); |
| 3305 | btngrp.append($('<button/>').addClass("button-delete").html('Delete registered user information').on("click", function(){ |
| 3306 | LAYOUT.renderYesNo('Remove register user value', 'Do you really want to remove the registered user value of this ticket "'+codeObj.code_display+'"?', ()=>{ |
| 3307 | // sende delete user from code operation zum server |
| 3308 | div.html(_getSpinnerHTML()); |
| 3309 | _makeGet('removeUserRegistrationFromCode', {'code':codeObj.code}, _codeObj=>{ |
| 3310 | //tabelle.ajax.reload(); |
| 3311 | __getData(_codeObj); |
| 3312 | }); |
| 3313 | }); |
| 3314 | })); |
| 3315 | } else { |
| 3316 | div.append("No registration to this ticket done"); |
| 3317 | } |
| 3318 | |
| 3319 | btngrp.append($('<button/>').addClass("button-edit").html('Edit registered user information').on("click", function(){ |
| 3320 | // display eingabe maske für value und userid |
| 3321 | function __showMask(){ |
| 3322 | let _options = { |
| 3323 | title: 'Edit registered user', |
| 3324 | modal: true, |
| 3325 | minWidth: 400, |
| 3326 | minHeight: 200, |
| 3327 | buttons: [ |
| 3328 | { |
| 3329 | id: 'okBtn', |
| 3330 | text: "Ok", |
| 3331 | click: function() { |
| 3332 | ___submitForm(); |
| 3333 | } |
| 3334 | }, |
| 3335 | { |
| 3336 | text: "Cancel", |
| 3337 | click: function() { |
| 3338 | $( this ).dialog( "close" ); |
| 3339 | $( this ).html(''); |
| 3340 | } |
| 3341 | } |
| 3342 | ] |
| 3343 | }; |
| 3344 | let dlg = $('<div />'); |
| 3345 | let form = $('<form />').appendTo(dlg); |
| 3346 | |
| 3347 | let elem_value = $('<input type="text" value="'+metaObj.user.value+'" />'); |
| 3348 | $('<div/>').css({"margin-top":"10px","margin-bottom": "15px","margin-right": "15px"}) |
| 3349 | .html('Registered value<br>') |
| 3350 | .append(elem_value) |
| 3351 | //.append('<br><i>If CVV is set, then your user will be asked to enter also the CVV to check the serial code.</i>') |
| 3352 | .appendTo(form); |
| 3353 | let elem_userid = $('<input type="number" min="0" value="'+metaObj.user.reg_userid+'" />'); |
| 3354 | $('<div/>').css({"margin-top":"10px","margin-bottom": "15px","margin-right": "15px"}) |
| 3355 | .html('Registered wordpress userid<br>') |
| 3356 | .append(elem_userid) |
| 3357 | .appendTo(form); |
| 3358 | |
| 3359 | dlg.append('<p>Changes will trigger the webhook, if activated.<br>The IP will updated too. The registered date will only be changed, if it was not set already.</p>'); |
| 3360 | dlg.dialog(_options); |
| 3361 | |
| 3362 | form.on("submit", function(event) { |
| 3363 | event.preventDefault(); |
| 3364 | ___submitForm(); |
| 3365 | }); |
| 3366 | function ___submitForm() { |
| 3367 | let reg_userid = intval(elem_userid.val().trim()); |
| 3368 | let reg_value = elem_value.val().trim(); |
| 3369 | dlg.html(_getSpinnerHTML()); |
| 3370 | let _data = {"value":reg_value, "reg_userid":reg_userid}; |
| 3371 | form[0].reset(); |
| 3372 | _data.code = codeObj.code; |
| 3373 | $('#okBtn').remove(); |
| 3374 | _makeGet('editUseridForUserRegistrationFromCode', _data, _codeObj=>{ |
| 3375 | //tabelle.ajax.reload(); |
| 3376 | __getData(_codeObj); |
| 3377 | closeDialog(dlg); |
| 3378 | }, function() { |
| 3379 | closeDialog(dlg); |
| 3380 | }); |
| 3381 | } |
| 3382 | } // ende __showMask |
| 3383 | __showMask(); |
| 3384 | })); // end button-edit |
| 3385 | div.append(btngrp); |
| 3386 | if (isPremium()) div.append(PREMIUM.displayRegisteredUserForCode(codeObj, tabelle, metaObj)); |
| 3387 | } // endif typeof codeObj.meta !== "undefined" && codeObj.meta !== "" |
| 3388 | } |
| 3389 | __getData(); |
| 3390 | return div; |
| 3391 | } |
| 3392 | |
| 3393 | function addStyleCode(content) { |
| 3394 | let c = document.createElement('style'); |
| 3395 | c.innerHTML = content; |
| 3396 | document.getElementsByTagName("head")[0].appendChild(c); |
| 3397 | } |
| 3398 | function addStyleTag(url, id, onloadfkt, attrListe, loadLatest) { |
| 3399 | var script = document.createElement('link'); |
| 3400 | script.type = 'text/css'; |
| 3401 | script.rel = "stylesheet"; |
| 3402 | let myId = id; |
| 3403 | if (!myId) myId = url; |
| 3404 | if (document.getElementById(id) && document.getElementById(id).src === url) { |
| 3405 | onloadfkt && onloadfkt(); |
| 3406 | return; // prevent re-adding the same tag |
| 3407 | } |
| 3408 | script.id = id; |
| 3409 | if (attrListe) for(var attr in attrListe) script.setAttribute(attr, attrListe[attr]); |
| 3410 | script.href = url; |
| 3411 | if (loadLatest) script.href += '?t='+new Date().getTime(); |
| 3412 | if (typeof onloadfkt !== "undefined") script.onload = onloadfkt; |
| 3413 | document.getElementsByTagName("head")[0].appendChild(script); |
| 3414 | } |
| 3415 | function addScriptCode(content, id) { |
| 3416 | if (typeof system.DYNJS_CACHE.scriptCodeElements === "undefined") { |
| 3417 | system.DYNJS_CACHE.scriptCodeElements = {}; |
| 3418 | } |
| 3419 | let c; |
| 3420 | if (id && typeof system.DYNJS_CACHE.scriptCodeElements[id] !== "undefined") { |
| 3421 | c = system.DYNJS_CACHE.scriptCodeElements[id]; |
| 3422 | document.getElementsByTagName("head")[0].removeChild(c); |
| 3423 | } else { |
| 3424 | c = document.createElement('script'); |
| 3425 | } |
| 3426 | c.innerHTML = content; |
| 3427 | if (id) { |
| 3428 | system.DYNJS_CACHE.scriptCodeElements[id] = c; |
| 3429 | } |
| 3430 | document.getElementsByTagName("head")[0].appendChild(c); |
| 3431 | } |
| 3432 | function addScriptTag(url, id, onloadfkt, attrListe, loadLatest) { |
| 3433 | var head = document.getElementsByTagName("head")[0]; |
| 3434 | var script = document.createElement('script'); |
| 3435 | script.type = 'text/javascript'; |
| 3436 | let myId = id; |
| 3437 | if (!myId) myId = url; |
| 3438 | if (document.getElementById(id) && document.getElementById(id).src === url) { |
| 3439 | onloadfkt && onloadfkt(); |
| 3440 | return; // prevent re-adding the same tag |
| 3441 | } |
| 3442 | script.id = id; |
| 3443 | if (attrListe) for(var attr in attrListe) script.setAttribute(attr, attrListe[attr]); |
| 3444 | script.src = url; |
| 3445 | if (loadLatest) script.src += '?t='+new Date().getTime(); |
| 3446 | if (typeof onloadfkt !== "undefined") script.onload = onloadfkt; |
| 3447 | head.appendChild(script); |
| 3448 | } |
| 3449 | |
| 3450 | function getLabelPremiumOnly() { |
| 3451 | return '[<a href="https://vollstart.com/event-tickets-with-ticket-scanner/">PREMIUM ONLY</a>]'; |
| 3452 | } |
| 3453 | |
| 3454 | function _getSpinnerHTML() { |
| 3455 | return '<span class="lds-dual-ring"></span>'; |
| 3456 | } |
| 3457 | |
| 3458 | function _loadingJSDatatables(cbf) { |
| 3459 | let loaded = {}; |
| 3460 | addStyleCode('table.dataTable tr.shown td.details-control {background: url('+myAjax._plugin_home_url+'/img/details_close.png) no-repeat center center;}td.details-control {background: url('+myAjax._plugin_home_url+'/img/details_open.png) no-repeat center center;cursor: pointer;}'); |
| 3461 | addStyleTag(myAjax._plugin_home_url+'/3rd/datatables.min.css', 'jquery_dataTables', ()=>{ |
| 3462 | loaded['1'] = true; |
| 3463 | if (loaded['2']) { |
| 3464 | cbf && cbf(); |
| 3465 | } |
| 3466 | }, {'crossorigin':"anonymous"}); |
| 3467 | addScriptTag(myAjax._plugin_home_url+"/3rd/datatables.min.js", 'jquery_dataTables', ()=>{ |
| 3468 | loaded['2'] = true; |
| 3469 | if (loaded['1']) { |
| 3470 | cbf && cbf(); |
| 3471 | } |
| 3472 | }, {'crossorigin':"anonymous", "charset":"utf8"}); |
| 3473 | } |
| 3474 | |
| 3475 | function isPremium() { |
| 3476 | return myAjax._isPremium == "1" || myAjax._isPremium === true; |
| 3477 | } |
| 3478 | |
| 3479 | var BulkActions = { |
| 3480 | 'codes': { |
| 3481 | 'delete': { |
| 3482 | "label": _x('Delete', 'label', 'event-tickets-with-ticket-scanner'), |
| 3483 | "fkt": (selectedElems, tabelle_codes_datatable)=>{ |
| 3484 | LAYOUT.renderYesNo('Delete all selected tickets?', 'Are you sure, you want to delete all selected tickets?<br><br>'+selectedElems.length+' tickets will be deleted.', ()=>{ |
| 3485 | let _data = {'ids':[]}; |
| 3486 | selectedElems.forEach(v=>{ |
| 3487 | _data.ids.push($(v).attr("data-key")); |
| 3488 | }); |
| 3489 | _makePost('removeCodes', _data, result=>{ |
| 3490 | tabelle_codes_datatable.ajax.reload(); |
| 3491 | }); |
| 3492 | }); |
| 3493 | } |
| 3494 | }, |
| 3495 | 'remove_marked_used': { |
| 3496 | "label": _x("Remove marked as used", 'option', 'event-tickets-with-ticket-scanner'), |
| 3497 | "fkt": (selectedElems, tabelle_codes_datatable)=>{ |
| 3498 | LAYOUT.renderYesNo('Remove marked used?', 'Are you sure, you want to remove the used marked from all selected tickets?<br><br>'+selectedElems.length+' tickets will be changed.', ()=>{ |
| 3499 | let _data = {'ids':[], 'codes':[]}; |
| 3500 | selectedElems.forEach(v=>{ |
| 3501 | _data.ids.push($(v).attr("data-key")); |
| 3502 | _data.codes.push($(v).attr("data-code")); |
| 3503 | }); |
| 3504 | _makePost('removeUsedInformationFromCodeBulk', _data, result=>{ |
| 3505 | tabelle_codes_datatable.ajax.reload(); |
| 3506 | }); |
| 3507 | }); |
| 3508 | } |
| 3509 | }, |
| 3510 | 'remove_ticket_redeemed': { |
| 3511 | "label": _x("Delete Redeem Information", 'option', 'event-tickets-with-ticket-scanner'), |
| 3512 | "fkt": (selectedElems, tabelle_codes_datatable)=>{ |
| 3513 | LAYOUT.renderYesNo('Delete the redeem information?', 'Are you sure, you want to remove the the information about the redeem operation of the ticket?<br><br>'+selectedElems.length+' tickets will be changed.', ()=>{ |
| 3514 | let _data = {'ids':[], 'codes':[]}; |
| 3515 | selectedElems.forEach(v=>{ |
| 3516 | _data.ids.push($(v).attr("data-key")); |
| 3517 | _data.codes.push($(v).attr("data-code")); |
| 3518 | }); |
| 3519 | _makePost('removeRedeemWoocommerceTicketForCodeBulk', _data, result=>{ |
| 3520 | tabelle_codes_datatable.ajax.reload(); |
| 3521 | }); |
| 3522 | }); |
| 3523 | } |
| 3524 | }, |
| 3525 | 'generate_pdf': { |
| 3526 | "label": _x("Generate ticket PDF", 'option', 'event-tickets-with-ticket-scanner'), |
| 3527 | "fkt": (selectedElems, tabelle_codes_datatable)=>{ |
| 3528 | LAYOUT.renderYesNo('Generate the ticket PDF?', 'Are you sure, you want to generate the ticket PDFs for the selected tickets? This can take a while an could timeout the server.<br><br>'+selectedElems.length+' tickets will be added in one PDF.', ()=>{ |
| 3529 | let _data = {'ids':[], 'codes':[]}; |
| 3530 | selectedElems.forEach(v=>{ |
| 3531 | _data.ids.push($(v).attr("data-key")); |
| 3532 | _data.codes.push($(v).attr("data-code")); |
| 3533 | }); |
| 3534 | _downloadFile('generateOnePDFForTicketsBulk', _data, "tickets_merged.pdf"); |
| 3535 | }); |
| 3536 | } |
| 3537 | }, |
| 3538 | 'generate_badge': { |
| 3539 | "label": _x("Generate badge ticket", 'option', 'event-tickets-with-ticket-scanner'), |
| 3540 | "fkt": (selectedElems, tabelle_codes_datatable)=>{ |
| 3541 | LAYOUT.renderYesNo('Generate the ticket badge PDF?', 'Are you sure, you want to generate the ticket badge PDFs for the selected tickets? This can take a while an could timeout the server.<br><br>'+selectedElems.length+' badges will be added in one PDF.', ()=>{ |
| 3542 | let _data = {'ids':[], 'codes':[]}; |
| 3543 | selectedElems.forEach(v=>{ |
| 3544 | _data.ids.push($(v).attr("data-key")); |
| 3545 | _data.codes.push($(v).attr("data-code")); |
| 3546 | }); |
| 3547 | _downloadFile('generateOnePDFForBadgesBulk', _data, "ticketbadges_merged.pdf"); |
| 3548 | }); |
| 3549 | } |
| 3550 | }, |
| 3551 | 'move_to_list':{ |
| 3552 | "label": _x("Move to ticket list", 'option', 'event-tickets-with-ticket-scanner'), |
| 3553 | "fkt": (selectedElems, tabelle_codes_datatable)=>{ |
| 3554 | let content = $('<div>'); |
| 3555 | let div_code_list = _createDivInput(_x('Assign selected tickets to this ticket list', 'label', 'event-tickets-with-ticket-scanner')).appendTo(content); |
| 3556 | let input_code_list = $('<select><option value="0">'+_x('None', 'option value', 'event-tickets-with-ticket-scanner')+'</select></select>').appendTo(div_code_list); |
| 3557 | DATA_LISTS.forEach(v=>{ |
| 3558 | input_code_list.append('<option value="'+v.id+'">'+v.name+'</option>'); |
| 3559 | }); |
| 3560 | content.append("<br>"); |
| 3561 | LAYOUT.renderYesNo('Move ticket(s) to ticket list', content, ()=>{ |
| 3562 | let _data = {'ids':[], 'codes':[], 'list_id':input_code_list.val()}; |
| 3563 | selectedElems.forEach(v=>{ |
| 3564 | _data.ids.push($(v).attr("data-key")); |
| 3565 | _data.codes.push($(v).attr("data-code")); |
| 3566 | }); |
| 3567 | _makePost('assignTicketListToTicketsBulk', _data, result=>{ |
| 3568 | tabelle_codes_datatable.ajax.reload(); |
| 3569 | }); |
| 3570 | }); |
| 3571 | } |
| 3572 | } |
| 3573 | } |
| 3574 | } |
| 3575 | |
| 3576 | function addTabCSS() { |
| 3577 | $('<style>') |
| 3578 | .prop('type', 'text/css') |
| 3579 | .html(` |
| 3580 | .tabs { |
| 3581 | width: 100%; |
| 3582 | display: block; |
| 3583 | } |
| 3584 | .tab-nav { |
| 3585 | list-style: none; |
| 3586 | padding: 0; |
| 3587 | margin: 0; |
| 3588 | display: flex; |
| 3589 | border-bottom: 1px solid #ccc; |
| 3590 | } |
| 3591 | .tab-nav li { |
| 3592 | margin: 0; |
| 3593 | } |
| 3594 | .tab-nav a { |
| 3595 | display: block; |
| 3596 | padding: 10px 20px; |
| 3597 | text-decoration: none; |
| 3598 | color: #333; |
| 3599 | border: 1px solid #ccc; |
| 3600 | border-bottom: none; |
| 3601 | background: #f9f9f9; |
| 3602 | margin-right: 5px; |
| 3603 | border-radius: 5px 5px 0 0; |
| 3604 | } |
| 3605 | .tab-nav a.active { |
| 3606 | background: #fff; |
| 3607 | border-bottom: 1px solid #fff; |
| 3608 | font-weight: bold; |
| 3609 | } |
| 3610 | .tab-content { |
| 3611 | display: none; |
| 3612 | padding: 20px; |
| 3613 | border: 1px solid #ccc; |
| 3614 | border-radius: 0 5px 5px 5px; |
| 3615 | background: #fff; |
| 3616 | } |
| 3617 | `) |
| 3618 | .appendTo('head'); |
| 3619 | } |
| 3620 | |
| 3621 | function getHelperFunktions() { |
| 3622 | return { |
| 3623 | _getSpinnerHTML:_getSpinnerHTML, |
| 3624 | _makePost:_makePost, |
| 3625 | _makeGet:_makeGet, |
| 3626 | _downloadFile:_downloadFile, |
| 3627 | _requestURL:_requestURL, |
| 3628 | _getLAYOUT:function(){ return LAYOUT;}, |
| 3629 | _getDIV:function(){ return DIV;}, |
| 3630 | _BulkActions:BulkActions, |
| 3631 | _closeDialog:closeDialog, |
| 3632 | _OPTIONS:function(){ return OPTIONS;}, |
| 3633 | _updateCodeObject:updateCodeObject, |
| 3634 | _getCodeObjectMeta:getCodeObjectMeta, |
| 3635 | _DateTime2Text:DateTime2Text, |
| 3636 | _compareVersions:compareVersions, |
| 3637 | _getBackButtonDiv:getBackButtonDiv |
| 3638 | }; |
| 3639 | } |
| 3640 | |
| 3641 | function refreshNoncePeriodically() { |
| 3642 | // check if the last check of nonce is older than 4 minutes |
| 3643 | // do a ping to get the new nonce |
| 3644 | setInterval(()=>{ |
| 3645 | let last_check = DATA.last_nonce_check; |
| 3646 | if (last_check == null || last_check == "") { |
| 3647 | last_check = 0; |
| 3648 | } |
| 3649 | let now = new Date().getTime(); |
| 3650 | if (now - last_check > 240000) { |
| 3651 | _makeGet('ping', [], data=>{ |
| 3652 | }); |
| 3653 | } |
| 3654 | }, 60000); |
| 3655 | } |
| 3656 | |
| 3657 | function init() { |
| 3658 | addStyleCode('.lds-dual-ring {display:inline-block;width:64px;height:64px;}.lds-dual-ring:after {content:" ";display:block;width:46px;height:46px;margin:1px;border-radius:50%;border:5px solid #fff;border-color:#2e74b5 transparent #2e74b5 transparent;animation:lds-dual-ring 0.6s linear infinite;}@keyframes lds-dual-ring {0% {transform: rotate(0deg);}100% {transform: rotate(360deg);}}'); |
| 3659 | addStyleTag(myAjax._plugin_home_url+'/css/styles_backend.css'); |
| 3660 | |
| 3661 | addScriptTag(myAjax._plugin_home_url+'/3rd/ace/ace.js'); |
| 3662 | |
| 3663 | addTabCSS(); |
| 3664 | |
| 3665 | DIV = $('#'+myAjax.divId); |
| 3666 | DIV.html(_getSpinnerHTML()); |
| 3667 | LAYOUT = new Layout(); |
| 3668 | function _init() { |
| 3669 | _loadingJSDatatables(function() { |
| 3670 | if (typeof PARAS.display !== "undefined" && PARAS.display == 'options') { |
| 3671 | _displayOptionsArea(); |
| 3672 | } else if (typeof PARAS.display !== "undefined" && PARAS.display == 'support') { |
| 3673 | _displaySupportInfoArea(); |
| 3674 | } else if (typeof PARAS.display !== "undefined" && PARAS.display == 'authtokens') { |
| 3675 | _displayAuthTokensArea(); |
| 3676 | } else if (typeof PARAS.display !== "undefined" && PARAS.display == 'faq') { |
| 3677 | _displayFAQArea(); |
| 3678 | } else if (typeof PARAS.display !== "undefined" && PARAS.display == 'seatingplan') { |
| 3679 | _displaySeatingplanArea(); |
| 3680 | } else { |
| 3681 | LAYOUT.renderAdminPageLayout(); |
| 3682 | } |
| 3683 | }); |
| 3684 | } |
| 3685 | |
| 3686 | if (isPremium() && myAjax._premJS !== "") { |
| 3687 | addScriptTag(myAjax._premJS, null, function() { |
| 3688 | PREMIUM = new sasoEventticketsPremium(myAjax, getHelperFunktions()); |
| 3689 | _init(); |
| 3690 | }); |
| 3691 | } else { |
| 3692 | _init(); |
| 3693 | } |
| 3694 | $('#wpfooter').css('display', 'none'); |
| 3695 | refreshNoncePeriodically(); |
| 3696 | } |
| 3697 | if (!doNotInit) init(); |
| 3698 | return { |
| 3699 | init: init, |
| 3700 | form_fields_serial_format:_form_fields_serial_format |
| 3701 | }; |
| 3702 | |
| 3703 | } |
| 3704 | if (typeof Ajax_sasoEventtickets !== "undefined") { |
| 3705 | window.sasoEventtickets_backend = sasoEventtickets(Ajax_sasoEventtickets); |
| 3706 | } |