diff --git a/Controllers/RvlController.cs b/Controllers/RvlController.cs index 0da4325..8ec4145 100644 --- a/Controllers/RvlController.cs +++ b/Controllers/RvlController.cs @@ -108,7 +108,10 @@ namespace rockfishCore.Controllers newLicense.RegisteredTo = l.RegisteredTo; newLicense.DbId = l.DbId; - newLicense.LicenseExpiration = DateUtil.EpochToDate(l.LicenseExpirationDate); + if (l.LicenseExpires) + newLicense.LicenseExpiration = DateUtil.EpochToDate(l.LicenseExpirationDate); + else + newLicense.LicenseExpiration = DateUtil.EmptyDateValue; newLicense.MaintenanceExpiration = DateUtil.EpochToDate(l.MaintenanceExpirationDate); foreach (dtoLicenseFeature f in l.Features) { @@ -125,6 +128,7 @@ namespace rockfishCore.Controllers DBLicense.SiteId = l.SiteId; DBLicense.Email = Customer.AdminEmail; DBLicense.DbId = l.DbId; + DBLicense.Code = "na"; DBLicense.Key = Key; DBLicense.RegTo = l.RegisteredTo; await ct.License.AddAsync(DBLicense); @@ -142,7 +146,7 @@ throw new System.Exception("UNCOMMENT THIS FOR PRODUCTION"); #endif - return NoContent(); + return Ok("ok"); } catch (Exception ex) { diff --git a/wwwroot/js/app.ravLicense.js b/wwwroot/js/app.ravLicense.js index 9e61391..b48971a 100644 --- a/wwwroot/js/app.ravLicense.js +++ b/wwwroot/js/app.ravLicense.js @@ -64,18 +64,28 @@ app.ravLicense = (function () { }); var submitData = app.utilB.objectifyFormDataArray(formData); + //do features separately, above can't deal with multi select and we need to add schedtechs anyway + let features = []; + features.push({ + Feature: "ServiceTechs", + Count: Number($("#techcount").val()) + }); + let options = $("#options").val(); - //clean up the data before submit -debugger; + for (let i = 0; i < options.length; i++) { + features.push({ Feature: options[i], Count: 0 }); + } + + submitData["features"]=features; //submit - // alert("STUB submit"); + // alert("STUB submit"); app.api.createRavLicense(submitData, function (res) { - if (res.error) { - $.gevent.publish('app-show-error', res.msg); - } else { - $('#key').val(res); - return false; - } + if (res.error) { + $.gevent.publish("app-show-error", res.msg); + } else { + $("#key").val(res); + return false; + } }); return false; //prevent default diff --git a/wwwroot/js/app.utilB.js b/wwwroot/js/app.utilB.js index ae1d255..36b98ef 100644 --- a/wwwroot/js/app.utilB.js +++ b/wwwroot/js/app.utilB.js @@ -13,322 +13,320 @@ /*global $, app, getComputedStyle */ app.utilB = (function () { - 'use strict'; - //---------------- BEGIN MODULE SCOPE VARIABLES -------------- - var - configMap = { - regex_encode_html: /[&"'><]/g, - regex_encode_noamp: /["'><]/g, - html_encode_map: { - '&': '&', - '"': '"', - "'": ''', - '>': '>', - '<': '<' - } - }, + "use strict"; + //---------------- BEGIN MODULE SCOPE VARIABLES -------------- + var configMap = { + regex_encode_html: /[&"'><]/g, + regex_encode_noamp: /["'><]/g, + html_encode_map: { + "&": "&", + '"': """, + "'": "'", + ">": ">", + "<": "<" + } + }, + decodeHtml, + encodeHtml, + getEmSize, + getApiUrl, + getUrlParams, + formData, + objectifyFormDataArray, + getMediaSize, + prepareObjectForClient, + fixDatesToStrings, + epochToShortDate, + epochToLocalShortDate, + epochToLocalShortDateTime, + getCurrentDateTimeAsEpoch, + genListColumn, + genListColumnNoLink, + autoComplete, + prepareObjectDatesForServer, + fixStringToServerDate; - decodeHtml, encodeHtml, getEmSize, getApiUrl, getUrlParams, formData, objectifyFormDataArray, - getMediaSize, prepareObjectForClient, fixDatesToStrings, - epochToShortDate, epochToLocalShortDate, epochToLocalShortDateTime, getCurrentDateTimeAsEpoch, - genListColumn, - genListColumnNoLink, autoComplete, prepareObjectDatesForServer, - fixStringToServerDate; + configMap.encode_noamp_map = $.extend({}, configMap.html_encode_map); + delete configMap.encode_noamp_map["&"]; + //----------------- END MODULE SCOPE VARIABLES --------------- - configMap.encode_noamp_map = $.extend({}, configMap.html_encode_map); - delete configMap.encode_noamp_map['&']; - //----------------- END MODULE SCOPE VARIABLES --------------- + //------------------- BEGIN UTILITY METHODS ------------------ - //------------------- BEGIN UTILITY METHODS ------------------ + // Begin decodeHtml + // Decodes HTML entities in a browser-friendly way + // See http://stackoverflow.com/questions/1912501/\ + // unescape-html-entities-in-javascript + // + decodeHtml = function (str) { + return $("
") + .html(str || "") + .text(); + }; + // End decodeHtml + // Begin encodeHtml + // This is single pass encoder for html entities and handles + // an arbitrary number of characters + // + encodeHtml = function (input_arg_str, exclude_amp) { + var input_str = String(input_arg_str), + regex, + lookup_map; - // Begin decodeHtml - // Decodes HTML entities in a browser-friendly way - // See http://stackoverflow.com/questions/1912501/\ - // unescape-html-entities-in-javascript - // - decodeHtml = function (str) { - return $('
').html(str || '').text(); - }; - // End decodeHtml + if (exclude_amp) { + lookup_map = configMap.encode_noamp_map; + regex = configMap.regex_encode_noamp; + } else { + lookup_map = configMap.html_encode_map; + regex = configMap.regex_encode_html; + } + return input_str.replace(regex, function (match, name) { + return lookup_map[match] || ""; + }); + }; + // End encodeHtml + // Begin getEmSize + // returns size of ems in pixels + // + getEmSize = function (elem) { + return Number(getComputedStyle(elem, "").fontSize.match(/\d*\.?\d*/)[0]); + }; + // End getEmSize - // Begin encodeHtml - // This is single pass encoder for html entities and handles - // an arbitrary number of characters - // - encodeHtml = function (input_arg_str, exclude_amp) { - var - input_str = String(input_arg_str), - regex, lookup_map; + //Begin getApiUrl + //returns url for api methods by parsing current window location url + // + getApiUrl = function () { + var u = + window.location.href + .replace(window.location.hash, "") + .replace("default.htm", "") + "api/"; + //is it a dev local url? + if (u.indexOf("localhost:8080") != -1) { + u = u.replace("8080", "8081"); + } + // End getApiUrl - if (exclude_amp) { - lookup_map = configMap.encode_noamp_map; - regex = configMap.regex_encode_noamp; + //fix for random recurrence of extraneous ? on iPhone when using api + //(Cannot post to http://gl-gztw.rhcloud.com/?api/list (404)) + u = u.replace("?", ""); + + return u; + }; + + // Begin formData + // Get or set all form fields + // + formData = function (data) { + //fix dates into strings + prepareObjectForClient(data); + + var inps = $(":input").get(); + + if (typeof data != "object") { + // return all data + data = {}; + + $.each(inps, function () { + if ( + this.name && + (this.checked || + /select|textarea/i.test(this.nodeName) || + /text|hidden|password/i.test(this.type)) + ) { + data[this.name] = $(this).val(); + } + }); + return data; + } else { + $.each(inps, function () { + if (this.name && data[this.name]) { + if (this.type == "checkbox" || this.type == "radio") { + $(this).prop("checked", data[this.name]); + } else { + $(this).val(data[this.name]); + } + } else if (this.type == "checkbox") { + $(this).prop("checked", false); + } + }); + return $(this); + } + }; + // End formdata + + // Begin getMediaSize + // Retrieves results of css media query in hidden pseudo element + // :after body element + //objectifyFormDataArray + getMediaSize = function () { + return window + .getComputedStyle(document.querySelector("body"), ":after") + .getPropertyValue("content") + .replace(/\"/g, ""); + }; + // End getMediaSize + + //Begin objectifyFormDataArray + //takes name value form input pairs in array and turns into a keyed object + //suitable for sending as json object + // + objectifyFormDataArray = function (arr) { + var rv = {}; + for (var i = 0; i < arr.length; ++i) + if (arr[i] !== undefined) { + rv[arr[i].name] = arr[i].value.trim(); //case 3205 added trim + } + return prepareObjectDatesForServer(rv); + }; + + //Prepare an object for server needed format before submission + //called by objectifyFormDataArray + prepareObjectDatesForServer = function (obj) { + if (Array.isArray(obj)) { + for (var i = 0; i < obj.length; i++) { + fixStringToServerDate(obj[i]); + } + } else { + fixStringToServerDate(obj); + } + return obj; + }; + // + + //Turn string date fields from client into server compatible format (Unix epoch like this: 1498262400 1499904000) + fixStringToServerDate = function (obj) { + var keys = Object.keys(obj); + keys.forEach(function (key) { + if (key.endsWith("Date") || key.startsWith("dt")) { + var value = obj[key]; + if (value == null) { + obj[key] = ""; } else { - lookup_map = configMap.html_encode_map; - regex = configMap.regex_encode_html; + //this is the sample format we will see: 2017-07-13 + //TODO: is this assuming UTC? + obj[key] = moment.utc(value, "YYYY-MM-DD").unix(); } - return input_str.replace(regex, - function (match, name) { - return lookup_map[match] || ''; - } - ); - }; - // End encodeHtml + } + }); + }; - // Begin getEmSize - // returns size of ems in pixels - // - getEmSize = function (elem) { - return Number( - getComputedStyle(elem, '').fontSize.match(/\d*\.?\d*/)[0] - ); - }; - // End getEmSize - - - //Begin getApiUrl - //returns url for api methods by parsing current window location url - // - getApiUrl = function () { - var u = window.location.href.replace(window.location.hash, "").replace('default.htm', '') + "api/"; - //is it a dev local url? - if (u.indexOf("localhost:8080") != -1) { - u = u.replace("8080", "8081"); - } - // End getApiUrl - - //fix for random recurrence of extraneous ? on iPhone when using api - //(Cannot post to http://gl-gztw.rhcloud.com/?api/list (404)) - u = u.replace("?", ""); - - return u; + //This function exists to change the properties of the passed in object + //to values compatible with jquery form filling functions (mostly dates to strings for now) + // + prepareObjectForClient = function (obj) { + if (Array.isArray(obj)) { + for (var i = 0; i < obj.length; i++) { + fixDatesToStrings(obj[i]); + } + } else { + fixDatesToStrings(obj); } + return obj; + }; + // - - - - - // Begin formData - // Get or set all form fields - // - formData = function (data) { - - //fix dates into strings - prepareObjectForClient(data); - - - var inps = $(":input").get(); - - if (typeof data != "object") { - // return all data - data = {}; - - $.each(inps, function () { - if (this.name && (this.checked || /select|textarea/i.test(this.nodeName) || /text|hidden|password/i.test(this.type))) { - data[this.name] = $(this).val(); - } - }); - return data; + //Turn date fields of object coming from db into stringified values for consumption by client + //turn null dates into empty strings and iso date values into strings in iso format + fixDatesToStrings = function (obj) { + var keys = Object.keys(obj); + keys.forEach(function (key) { + if (key.endsWith("Date") || key.startsWith("dt")) { + var value = obj[key]; + if (value == null) { + obj[key] = ""; } else { - $.each(inps, function () { - if (this.name && data[this.name]) { - if (this.type == "checkbox" || this.type == "radio") { - $(this).prop("checked", (data[this.name])); - } else { - $(this).val(data[this.name]); - } - } else if (this.type == "checkbox") { - $(this).prop("checked", false); - } - }); - return $(this); + //Now with sqlite they come and go as unix epoch seconds + //needs to be yyyy-MM-dd + obj[key] = moment.utc(new Date(value * 1000)).format("YYYY-MM-DD"); } - }; - // End formdata + } + }); + }; + // - // Begin getMediaSize - // Retrieves results of css media query in hidden pseudo element - // :after body element - //objectifyFormDataArray - getMediaSize = function () { - return window.getComputedStyle(document.querySelector('body'), ':after').getPropertyValue('content').replace(/\"/g, ''); - }; - // End getMediaSize + //Turn date values coming in from server into displayable short date format + //used to display dates in various lists (where the source epoch is already localized) + epochToShortDate = function (epoch) { + if (epoch == null || epoch == 0) return ""; + return moment.utc(new Date(epoch * 1000)).format("YYYY-MM-DD"); + }; + // + //LOCAL VERSION: Turn date values coming in from server into displayable short date format + //used to display dates in various lists where the source epoch is in UTC + epochToLocalShortDate = function (epoch) { + if (epoch == null || epoch == 0) return ""; + var utdate = moment.utc(new Date(epoch * 1000)); + var localdate = moment(utdate).local(); + return localdate.format("YYYY-MM-DD"); + }; + //LOCAL VERSION: Turn date values coming in from server into displayable short date AND TIME format + //used to display dates in various lists where the source epoch is in UTC + epochToLocalShortDateTime = function (epoch) { + if (epoch == null || epoch == 0) return ""; + var utdate = moment.utc(new Date(epoch * 1000)); + var localdate = moment(utdate).local(); + return localdate.format("YYYY-MM-DD LT"); + }; + ////////////////////////// + //Get current date and time as a utc unix epoch + getCurrentDateTimeAsEpoch = function () { + return moment().utc().unix(); + }; + // Begin genListColumn + // This function is used to demarcate 'columns' of fields in basic list forms by wrapping each column field in html + // + genListColumn = function (val) { + return '' + val + ""; + }; + // End genListColumn - //Begin objectifyFormDataArray - //takes name value form input pairs in array and turns into a keyed object - //suitable for sending as json object - // - objectifyFormDataArray = function (arr) { - var rv = {}; - for (var i = 0; i < arr.length; ++i) - if (arr[i] !== undefined) { - rv[arr[i].name] = arr[i].value.trim();//case 3205 added trim - } - return prepareObjectDatesForServer(rv); - } + // Begin genListColumnNoLink + // This function is used to demarcate and style 'columns' of fields in basic list forms by wrapping each column field in html + // that are not link columns + genListColumnNoLink = function (val) { + return '' + val + ""; + }; + // End genListColumn + // Begin autoComplete + // This function is used to attach an autocomplete method to an input + // + autoComplete = function (controlId, acGetToken) { + $("#" + controlId).autocomplete({ + serviceUrl: app.shell.stateMap.apiUrl + "autocomplete", + params: { + acget: acGetToken + }, + ajaxSettings: { + headers: app.api.getAuthHeaderObject() + } + }); + }; + // End autoComplete - - - - //Prepare an object for server needed format before submission - //called by objectifyFormDataArray - prepareObjectDatesForServer = function (obj) { - if (Array.isArray(obj)) { - for (var i = 0; i < obj.length; i++) { - fixStringToServerDate(obj[i]); - } - } else { - fixStringToServerDate(obj); - } - return obj; - } - // - - //Turn string date fields from client into server compatible format (Unix epoch like this: 1498262400 1499904000) - fixStringToServerDate = function (obj) { - var keys = Object.keys(obj); - keys.forEach(function (key) { - if (key.endsWith('Date') || key.startsWith('dt')) { - var value = obj[key]; - if (value == null) { - obj[key] = ''; - } else { - //this is the sample format we will see: 2017-07-13 - //TODO: is this assuming UTC? - obj[key] = moment.utc(value, "YYYY-MM-DD").unix(); - } - } - }); - } - - - - //This function exists to change the properties of the passed in object - //to values compatible with jquery form filling functions (mostly dates to strings for now) - // - prepareObjectForClient = function (obj) { - if (Array.isArray(obj)) { - for (var i = 0; i < obj.length; i++) { - fixDatesToStrings(obj[i]); - } - } else { - fixDatesToStrings(obj); - } - return obj; - } - // - - //Turn date fields of object coming from db into stringified values for consumption by client - //turn null dates into empty strings and iso date values into strings in iso format - fixDatesToStrings = function (obj) { - var keys = Object.keys(obj); - keys.forEach(function (key) { - if (key.endsWith('Date') || key.startsWith('dt')) { - var value = obj[key]; - if (value == null) { - obj[key] = ''; - } else { - //Now with sqlite they come and go as unix epoch seconds - //needs to be yyyy-MM-dd - obj[key] = moment.utc(new Date(value * 1000)).format("YYYY-MM-DD"); - } - } - }); - } - // - - //Turn date values coming in from server into displayable short date format - //used to display dates in various lists (where the source epoch is already localized) - epochToShortDate = function (epoch) { - if (epoch == null || epoch == 0) return ''; - return moment.utc(new Date(epoch * 1000)).format("YYYY-MM-DD"); - } - // - - //LOCAL VERSION: Turn date values coming in from server into displayable short date format - //used to display dates in various lists where the source epoch is in UTC - epochToLocalShortDate = function (epoch) { - if (epoch == null || epoch == 0) return ''; - var utdate = moment.utc(new Date(epoch * 1000)); - var localdate = moment(utdate).local(); - return localdate.format("YYYY-MM-DD"); - } - - //LOCAL VERSION: Turn date values coming in from server into displayable short date AND TIME format - //used to display dates in various lists where the source epoch is in UTC - epochToLocalShortDateTime = function (epoch) { - if (epoch == null || epoch == 0) return ''; - var utdate = moment.utc(new Date(epoch * 1000)); - var localdate = moment(utdate).local(); - return localdate.format("YYYY-MM-DD LT"); - } - - ////////////////////////// - //Get current date and time as a utc unix epoch - getCurrentDateTimeAsEpoch = function () { - return moment().utc().unix(); - } - - // Begin genListColumn - // This function is used to demarcate 'columns' of fields in basic list forms by wrapping each column field in html - // - genListColumn = function (val) { - return '' + val + '' - }; - // End genListColumn - - // Begin genListColumnNoLink - // This function is used to demarcate and style 'columns' of fields in basic list forms by wrapping each column field in html - // that are not link columns - genListColumnNoLink = function (val) { - return '' + val + '' - }; - // End genListColumn - - - // Begin autoComplete - // This function is used to attach an autocomplete method to an input - // - autoComplete = function (controlId, acGetToken) { - $('#' + controlId).autocomplete({ - serviceUrl: app.shell.stateMap.apiUrl + 'autocomplete', - params: { - acget: acGetToken - }, - ajaxSettings: { - headers: app.api.getAuthHeaderObject() - } - }); - }; - // End autoComplete - - - - // export methods - return { - decodeHtml: decodeHtml, - encodeHtml: encodeHtml, - getEmSize: getEmSize, - getApiUrl: getApiUrl, - getUrlParams: getUrlParams, - formData: formData, - getMediaSize: getMediaSize, - objectifyFormDataArray: objectifyFormDataArray, - epochToShortDate: epochToShortDate, - epochToLocalShortDate: epochToLocalShortDate, - epochToLocalShortDateTime: epochToLocalShortDateTime, - getCurrentDateTimeAsEpoch: getCurrentDateTimeAsEpoch, - genListColumn: genListColumn, - genListColumnNoLink: genListColumnNoLink, - autoComplete: autoComplete - }; - //------------------- END PUBLIC METHODS --------------------- -}()); \ No newline at end of file + // export methods + return { + decodeHtml: decodeHtml, + encodeHtml: encodeHtml, + getEmSize: getEmSize, + getApiUrl: getApiUrl, + getUrlParams: getUrlParams, + formData: formData, + getMediaSize: getMediaSize, + objectifyFormDataArray: objectifyFormDataArray, + epochToShortDate: epochToShortDate, + epochToLocalShortDate: epochToLocalShortDate, + epochToLocalShortDateTime: epochToLocalShortDateTime, + getCurrentDateTimeAsEpoch: getCurrentDateTimeAsEpoch, + genListColumn: genListColumn, + genListColumnNoLink: genListColumnNoLink, + autoComplete: autoComplete + }; + //------------------- END PUBLIC METHODS --------------------- +})(); diff --git a/wwwroot/js/templates/app.ravLicense.handlebars b/wwwroot/js/templates/app.ravLicense.handlebars index 6b7cefd..80078fc 100644 --- a/wwwroot/js/templates/app.ravLicense.handlebars +++ b/wwwroot/js/templates/app.ravLicense.handlebars @@ -21,8 +21,8 @@
- +
@@ -32,7 +32,8 @@ Temporary key / expires - +
@@ -45,10 +46,10 @@
- - + +