<!DOCTYPE html> <html> <head> <title>Prorated Refund Calculator</title> <style> body { font-family: Calibri, Arial, sans-serif; font-size: 1.0em; } h1 { font-size: 1.2em; } </style> </head> <body> <h1>Prorated Refund Calculator</h1> <p>Input into the following fields and press Calculate.</p> <p style="color: red;">Enter date format as MM<strong>MM/DD/YYYY</strong><br/> Enter whole numbers for <strong>Term (in years)</strong> and <strong>Grace Period (in days)</strong>.</p> <form> <label>Product Purchase Date: <input type="text" id="productPurchaseDate" /> </label><br/> <label>Contract Purchase Date: <input type="text" id="contractPurchaseDate" /> </label><br/> <label>Purchase Price: <input type="text" id="purchasePrice" /> </label><br/> <label>Term (in years): <input type="text" id="termInYears" value="10" /> </label><br/> <label>Cancel Date: <input type="text" id="cancelDate" /> </label><br/> <label>Amount paid in claims: <input type="text" id="amtPaidInClaims" value="0" /> </label><br/> <label>Grace periodPeriod (in days): <input type="text" id="gracePeriodInDays" value="60" /></label><br/> </form> <br/> <button onclick="calculateProratedRefund()">Calculate</button> <script type="text/javascript"> /* Main function called by HTML form. * Validates input values, then performs calculations * and adds the result into the HTML document to display to the user. */ function calculateProratedRefund() { "use strict"; var productPurchaseDate = new Date (document.getElementById("productPurchaseDate").value); var contractPurchaseDate = new Date (document.getElementById("contractPurchaseDate").value); var purchasePrice = parseFloat (document.getElementById("purchasePrice").value).toFixed(2); var termInYears = parseInt parseFloat (document.getElementById("termInYears").value, 10).toFixed(2); var cancelDate = new Date (document.getElementById("cancelDate").value); var amtPaidInClaims = parseFloat (document.getElementById("amtPaidInClaims").value).toFixed(2); var gracePeriodInDays = parseInt parseFloat (document.getElementById("gracePeriodInDays").value, 10).toFixed(2); /* Underwriting policies specify that a Year of coverage is exactly 365 Days, regardless of Leap Years. * Hence the following calculations: */ var totalDays = termInYears * 365; var expirationDate = new Date(productPurchaseDate); expirationDate.setDate(productPurchaseDate.getDate() + (totalDays)); /* Validation of user input. * If any values are invalid, we return early and exit the function with error message to the user. * If all the input values are valid, we proceed to calculations. * NOTE: The two validation functions return an array of errors pushed from the called function. * If the array's length is 0 (i.e., empty array) there are no errors. */ var datesValid = validateDates(productPurchaseDate, contractPurchaseDate, cancelDate, expirationDate); var numsValid = validateNums(purchasePrice, termInYears, amtPaidInClaims, gracePeriodInDays); if (datesValid.length > 0 || numsValid.length > 0) { window.alert("Some values are invalid: \n"" + "\n""\n - " + datesValid.join("\n""\n - ") + "\n""\n - " + numsValid.join("\n""\n - ") ); return false; } /* All terms are calculated in Days, hence the following conversion from JavaScript's millisecond precision to Days. * (ms * secs * mins * hours) = 1 Day */ var msPerDay = 1000 * 60 * 60 * 24; var daysElapsed = Math.floor((Date.parse(cancelDate) - Date.parse(contractPurchaseDate)) / msPerDay); /* Policy holder is entitled to a full refund within the grace period. * Otherwise, if days elapsed exceed the grace period, the refund becomes prorated. */ var termUsed = 0.0; if (daysElapsed > gracePeriodInDays) { termUsed = (daysElapsed / totalDays); } var termLeft = 1.0 - termUsed; /* Finally we calculate the refund amount */ var proratedRefund = (purchasePrice * termLeft).toFixed(2); var finalRefund = (proratedRefund - amtPaidInClaims).toFixed(2); if (finalRefund < 0.0) { finalRefund = 0.0; } /* List of content to append into document. */ var contentToAppend = [ "Product Purchase date: " + formatDate(productPurchaseDate), "Contract Purchase date: " + formatDate(contractPurchaseDate), "Total days: " + totalDays + " (" + termInYears + " years)", "Expiration date: " + formatDate(expirationDate), "Cancel date: " + formatDate(cancelDate), "Grace period: " + gracePeriodInDays + " days", "Days elapsed: " + daysElapsed + " (" + parseFloat(daysElapsed / 365).toFixed(4) + " years)", "Refund percent: " + (termLeft * 100).toFixed(2) + " %", "Purchase price: $ " + purchasePrice, "Prorated refund: $ " + proratedRefund, "Paid in claims: ($ " + amtPaidInClaims + ")", "Final refund: $ " + finalRefund ]; /* Append calculation results to HTML document. */ var outputParagraph = document.createElement("p"); contentToAppend.forEach(function(element) { outputParagraph.appendChild(document.createTextNode(element)); outputParagraph.appendChild(document.createElement("br")); }); document.body.appendChild(outputParagraph); return true; } /** Confirm that all dates are valid Date values and that they follow business rules. * @param {Date} productPurchaseDate Date of purchase of the product(s) covered by the contract. * @param {Date} contractPurchaseDate Date of purchase of the contract to be cancelled. * @param {Date} cancelDate Date on which the cancellation of the contract was requested. * @param {Date} expirationDate Date on which the contract expires and is no longer eligible for cancellation or claims payment. * @return {Array} Array of Strings containing all applicable error messages. */ function validateDates(productPurchaseDate, contractPurchaseDate, cancelDate, expirationDate) { "use strict"; var dateErrors = new Array(); if (!isValidDate(productPurchaseDate)) { dateErrors.push("Invalid Product Purchase Date: " + productPurchaseDate); } if (!isValidDate(contractPurchaseDate)) { dateErrors.push("Invalid Contract Purchase Date: " + contractPurchaseDate); } if (contractPurchaseDate < productPurchaseDate) { dateErrors.push("Contract cannot be purchased (" + formatDate(contractPurchaseDate) + ") prior to the product (" + formatDate(productPurchaseDate) + ")"); } if (!isValidDate(cancelDate)) { dateErrors.push("Invalid Cancel Date: " + cancelDate); } if (cancelDate < productPurchaseDate || cancelDate < contractPurchaseDate) { dateErrors.push("Cancel date (" + formatDate(cancelDate) + ") cannot be prior to Product (" + formatDate(productPurchaseDate) + ") or Contract purchase (" + formatDate(contractPurchaseDate) + ")"); } if (cancelDate > expirationDate) { dateErrors.push("Cancel date (" + formatDate(cancelDate) + ") cannot be past Expiration date (" + formatDate(expirationDate) + ")"); } return dateErrors; } /** Confirm that all numbers are valid numbers and that they follow business rules. * @param {number} purchasePrice The dollar amount purchase price of the contract. * @param {number} termInYears The duration term of the policy in 365-day years. Must be whole number. * @param {number} amtPaidInClaims The dollar amount of claims paid against the contract prior to cancellation. * @param {number} gracePeriodInDays Grace period during which a contract holder can cancel with full refund/credit. Must be whole number. * @return {Array} Array of Strings containing all applicable error messages. */ function validateNums (purchasePrice, termInYears, amtPaidInClaims, gracePeriodInDays) { "use strict"; var numErrors = new Array(); if (isNaN(purchasePrice) || purchasePrice < 0) { numErrors.push("Invalid purchase price: " + purchasePrice); } if (isNaN(termInYears) || termInYears < 0) { numErrors.push("Invalid termTerm period(in years): " + termInYears); } if (isNaN(amtPaidInClaims) || amtPaidInClaims < 0) { numErrors.push("Invalid paid claims amount: " + amtPaidInClaims); } if (isNaN(gracePeriodInDays) || gracePeriodInDays < 0) { numErrors.push("Invalid grace period: " + gracePeriodInDays); } if (termInYears % 1 !== 0) { numErrors.push("Term (in years) " + termInYears + " is not a whole number."); } if (gracePeriodInDays % 1 !== 0) { numErrors.push("Grace periodPeriod (in days) " + gracePeriodInDays + " is not a whole number."); } return numErrors; } /** Utility function to make sure an input is a correct Date format * @param {Date} date A date or date-time value. * @returns {boolean} Whether the input date is a valid date. */ function isValidDate(date) { "use strict"; if (isNaN(date.getTime())) { return false; } return (Object.prototype.toString.call(date) === "[object Date]"); } /** Utility function to convert a Date to MM/DD/YYYY formatted String. * @param {Date} date A date or date-time value. * @returns {string} A String formatted as MM/DD/YYYY if date is valid, otherwise a String with error message. */ function formatDate(date) { "use strict"; var inputDate = new Date(date); if (isValidDate(inputDate)) { var year = inputDate.getFullYear().toString(); var month = (1 + inputDate.getMonth()).toString(); // months are 0-indexed hence the 1 + getMonth() var day = inputDate.getDate().toString(); return(month + '/' + day + '/' + year); } else { return("Invalid date: " + inputDate); } } </script> </body> </html> <!DOCTYPE html> <html> <head> <title>Prorated Refund Calculator</title> <style> body { font-family: Calibri, Arial, sans-serif; font-size: 1.0em; } h1 { font-size: 1.2em; } </style> </head> <body> <h1>Prorated Refund Calculator</h1> <p>Input into the following fields and press Calculate.</p> <p style="color: red;">Enter date format as MM/DD/YYYY</p> <form> <label>Product Purchase Date: <input type="text" id="productPurchaseDate" /> </label><br/> <label>Contract Purchase Date: <input type="text" id="contractPurchaseDate" /> </label><br/> <label>Purchase Price: <input type="text" id="purchasePrice" /> </label><br/> <label>Term (in years): <input type="text" id="termInYears" value="10" /> </label><br/> <label>Cancel Date: <input type="text" id="cancelDate" /> </label><br/> <label>Amount paid in claims: <input type="text" id="amtPaidInClaims" value="0" /> </label><br/> <label>Grace period (in days): <input type="text" id="gracePeriodInDays" value="60" /></label><br/> </form> <br/> <button onclick="calculateProratedRefund()">Calculate</button> <script type="text/javascript"> /* Main function called by HTML form. * Validates input values, then performs calculations * and adds the result into the HTML document to display to the user. */ function calculateProratedRefund() { "use strict"; var productPurchaseDate = new Date (document.getElementById("productPurchaseDate").value); var contractPurchaseDate = new Date (document.getElementById("contractPurchaseDate").value); var purchasePrice = parseFloat (document.getElementById("purchasePrice").value).toFixed(2); var termInYears = parseInt (document.getElementById("termInYears").value, 10); var cancelDate = new Date (document.getElementById("cancelDate").value); var amtPaidInClaims = parseFloat (document.getElementById("amtPaidInClaims").value).toFixed(2); var gracePeriodInDays = parseInt (document.getElementById("gracePeriodInDays").value, 10); /* Underwriting policies specify that a Year of coverage is exactly 365 Days, regardless of Leap Years. * Hence the following calculations: */ var totalDays = termInYears * 365; var expirationDate = new Date(productPurchaseDate); expirationDate.setDate(productPurchaseDate.getDate() + (totalDays)); /* Validation of user input. * If any values are invalid, we return early and exit the function with error message to the user. * If all the input values are valid, we proceed to calculations. * NOTE: The two validation functions return an array of errors pushed from the called function. * If the array's length is 0 (i.e., empty array) there are no errors. */ var datesValid = validateDates(productPurchaseDate, contractPurchaseDate, cancelDate, expirationDate); var numsValid = validateNums(purchasePrice, termInYears, amtPaidInClaims, gracePeriodInDays); if (datesValid.length > 0 || numsValid.length > 0) { window.alert("Some values are invalid: \n" + "\n" + datesValid.join("\n") + "\n" + numsValid.join("\n") ); return false; } /* All terms are calculated in Days, hence the following conversion from JavaScript's millisecond precision to Days. * (ms * secs * mins * hours) = 1 Day */ var msPerDay = 1000 * 60 * 60 * 24; var daysElapsed = Math.floor((Date.parse(cancelDate) - Date.parse(contractPurchaseDate)) / msPerDay); /* Policy holder is entitled to a full refund within the grace period. * Otherwise, if days elapsed exceed the grace period, the refund becomes prorated. */ var termUsed = 0.0; if (daysElapsed > gracePeriodInDays) { termUsed = (daysElapsed / totalDays); } var termLeft = 1.0 - termUsed; /* Finally we calculate the refund amount */ var proratedRefund = (purchasePrice * termLeft).toFixed(2); var finalRefund = (proratedRefund - amtPaidInClaims).toFixed(2); if (finalRefund < 0.0) { finalRefund = 0.0; } /* List of content to append into document. */ var contentToAppend = [ "Product Purchase date: " + formatDate(productPurchaseDate), "Contract Purchase date: " + formatDate(contractPurchaseDate), "Total days: " + totalDays + " (" + termInYears + " years)", "Expiration date: " + formatDate(expirationDate), "Cancel date: " + formatDate(cancelDate), "Grace period: " + gracePeriodInDays + " days", "Days elapsed: " + daysElapsed + " (" + parseFloat(daysElapsed / 365).toFixed(4) + " years)", "Refund percent: " + (termLeft * 100).toFixed(2) + " %", "Purchase price: $ " + purchasePrice, "Prorated refund: $ " + proratedRefund, "Paid in claims: ($ " + amtPaidInClaims + ")", "Final refund: $ " + finalRefund ]; /* Append calculation results to HTML document. */ var outputParagraph = document.createElement("p"); contentToAppend.forEach(function(element) { outputParagraph.appendChild(document.createTextNode(element)); outputParagraph.appendChild(document.createElement("br")); }); document.body.appendChild(outputParagraph); return true; } /** Confirm that all dates are valid Date values and that they follow business rules. * @param {Date} productPurchaseDate Date of purchase of the product(s) covered by the contract. * @param {Date} contractPurchaseDate Date of purchase of the contract to be cancelled. * @param {Date} cancelDate Date on which the cancellation of the contract was requested. * @param {Date} expirationDate Date on which the contract expires and is no longer eligible for cancellation or claims payment. * @return {Array} Array of Strings containing all applicable error messages. */ function validateDates(productPurchaseDate, contractPurchaseDate, cancelDate, expirationDate) { "use strict"; var dateErrors = new Array(); if (!isValidDate(productPurchaseDate)) { dateErrors.push("Invalid Product Purchase Date: " + productPurchaseDate); } if (!isValidDate(contractPurchaseDate)) { dateErrors.push("Invalid Contract Purchase Date: " + contractPurchaseDate); } if (contractPurchaseDate < productPurchaseDate) { dateErrors.push("Contract cannot be purchased (" + formatDate(contractPurchaseDate) + ") prior to the product (" + formatDate(productPurchaseDate) + ")"); } if (!isValidDate(cancelDate)) { dateErrors.push("Invalid Cancel Date: " + cancelDate); } if (cancelDate < productPurchaseDate || cancelDate < contractPurchaseDate) { dateErrors.push("Cancel date (" + formatDate(cancelDate) + ") cannot be prior to Product (" + formatDate(productPurchaseDate) + ") or Contract purchase (" + formatDate(contractPurchaseDate) + ")"); } if (cancelDate > expirationDate) { dateErrors.push("Cancel date (" + formatDate(cancelDate) + ") cannot be past Expiration date (" + formatDate(expirationDate) + ")"); } return dateErrors; } /** Confirm that all numbers are valid numbers and that they follow business rules. * @param {number} purchasePrice The dollar amount purchase price of the contract. * @param {number} termInYears The duration term of the policy in 365-day years. Must be whole number. * @param {number} amtPaidInClaims The dollar amount of claims paid against the contract prior to cancellation. * @param {number} gracePeriodInDays Grace period during which a contract holder can cancel with full refund/credit. Must be whole number. * @return {Array} Array of Strings containing all applicable error messages. */ function validateNums (purchasePrice, termInYears, amtPaidInClaims, gracePeriodInDays) { "use strict"; var numErrors = new Array(); if (isNaN(purchasePrice) || purchasePrice < 0) { numErrors.push("Invalid purchase price: " + purchasePrice); } if (isNaN(termInYears) || termInYears < 0) { numErrors.push("Invalid term period: " + termInYears); } if (isNaN(amtPaidInClaims) || amtPaidInClaims < 0) { numErrors.push("Invalid paid claims amount: " + amtPaidInClaims); } if (isNaN(gracePeriodInDays) || gracePeriodInDays < 0) { numErrors.push("Invalid grace period: " + gracePeriodInDays); } if (termInYears % 1 !== 0) { numErrors.push("Term " + termInYears + " is not a whole number."); } if (gracePeriodInDays % 1 !== 0) { numErrors.push("Grace period " + gracePeriodInDays + " is not a whole number."); } return numErrors; } /** Utility function to make sure an input is a correct Date format * @param {Date} date A date or date-time value. * @returns {boolean} Whether the input date is a valid date. */ function isValidDate(date) { "use strict"; if (isNaN(date.getTime())) { return false; } return (Object.prototype.toString.call(date) === "[object Date]"); } /** Utility function to convert a Date to MM/DD/YYYY formatted String. * @param {Date} date A date or date-time value. * @returns {string} A String formatted as MM/DD/YYYY if date is valid, otherwise a String with error message. */ function formatDate(date) { "use strict"; var inputDate = new Date(date); if (isValidDate(inputDate)) { var year = inputDate.getFullYear().toString(); var month = (1 + inputDate.getMonth()).toString(); // months are 0-indexed hence the 1 + getMonth() var day = inputDate.getDate().toString(); return(month + '/' + day + '/' + year); } else { return("Invalid date: " + inputDate); } } </script> </body> </html> <!DOCTYPE html> <html> <head> <title>Prorated Refund Calculator</title> <style> body { font-family: Calibri, Arial, sans-serif; font-size: 1.0em; } h1 { font-size: 1.2em; } </style> </head> <body> <h1>Prorated Refund Calculator</h1> <p>Input into the following fields and press Calculate.</p> <p style="color: red;">Enter date format as <strong>MM/DD/YYYY</strong><br/> Enter whole numbers for <strong>Term (in years)</strong> and <strong>Grace Period (in days)</strong>.</p> <form> <label>Product Purchase Date: <input type="text" id="productPurchaseDate" /> </label><br/> <label>Contract Purchase Date: <input type="text" id="contractPurchaseDate" /> </label><br/> <label>Purchase Price: <input type="text" id="purchasePrice" /> </label><br/> <label>Term (in years): <input type="text" id="termInYears" value="10" /> </label><br/> <label>Cancel Date: <input type="text" id="cancelDate" /> </label><br/> <label>Amount paid in claims: <input type="text" id="amtPaidInClaims" value="0" /> </label><br/> <label>Grace Period (in days): <input type="text" id="gracePeriodInDays" value="60" /></label><br/> </form> <br/> <button onclick="calculateProratedRefund()">Calculate</button> <script type="text/javascript"> /* Main function called by HTML form. * Validates input values, then performs calculations * and adds the result into the HTML document to display to the user. */ function calculateProratedRefund() { "use strict"; var productPurchaseDate = new Date (document.getElementById("productPurchaseDate").value); var contractPurchaseDate = new Date (document.getElementById("contractPurchaseDate").value); var purchasePrice = parseFloat (document.getElementById("purchasePrice").value).toFixed(2); var termInYears = parseFloat (document.getElementById("termInYears").value).toFixed(2); var cancelDate = new Date (document.getElementById("cancelDate").value); var amtPaidInClaims = parseFloat (document.getElementById("amtPaidInClaims").value).toFixed(2); var gracePeriodInDays = parseFloat (document.getElementById("gracePeriodInDays").value).toFixed(2); /* Underwriting policies specify that a Year of coverage is exactly 365 Days, regardless of Leap Years. * Hence the following calculations: */ var totalDays = termInYears * 365; var expirationDate = new Date(productPurchaseDate); expirationDate.setDate(productPurchaseDate.getDate() + (totalDays)); /* Validation of user input. * If any values are invalid, we return early and exit the function with error message to the user. * If all the input values are valid, we proceed to calculations. * NOTE: The two validation functions return an array of errors pushed from the called function. * If the array's length is 0 (i.e., empty array) there are no errors. */ var datesValid = validateDates(productPurchaseDate, contractPurchaseDate, cancelDate, expirationDate); var numsValid = validateNums(purchasePrice, termInYears, amtPaidInClaims, gracePeriodInDays); if (datesValid.length > 0 || numsValid.length > 0) { window.alert("Some values are invalid:" + "\n - " + datesValid.join("\n - ") + "\n - " + numsValid.join("\n - ") ); return false; } /* All terms are calculated in Days, hence the following conversion from JavaScript's millisecond precision to Days. * (ms * secs * mins * hours) = 1 Day */ var msPerDay = 1000 * 60 * 60 * 24; var daysElapsed = Math.floor((Date.parse(cancelDate) - Date.parse(contractPurchaseDate)) / msPerDay); /* Policy holder is entitled to a full refund within the grace period. * Otherwise, if days elapsed exceed the grace period, the refund becomes prorated. */ var termUsed = 0.0; if (daysElapsed > gracePeriodInDays) { termUsed = (daysElapsed / totalDays); } var termLeft = 1.0 - termUsed; /* Finally we calculate the refund amount */ var proratedRefund = (purchasePrice * termLeft).toFixed(2); var finalRefund = (proratedRefund - amtPaidInClaims).toFixed(2); if (finalRefund < 0.0) { finalRefund = 0.0; } /* List of content to append into document. */ var contentToAppend = [ "Product Purchase date: " + formatDate(productPurchaseDate), "Contract Purchase date: " + formatDate(contractPurchaseDate), "Total days: " + totalDays + " (" + termInYears + " years)", "Expiration date: " + formatDate(expirationDate), "Cancel date: " + formatDate(cancelDate), "Grace period: " + gracePeriodInDays + " days", "Days elapsed: " + daysElapsed + " (" + parseFloat(daysElapsed / 365).toFixed(4) + " years)", "Refund percent: " + (termLeft * 100).toFixed(2) + " %", "Purchase price: $ " + purchasePrice, "Prorated refund: $ " + proratedRefund, "Paid in claims: ($ " + amtPaidInClaims + ")", "Final refund: $ " + finalRefund ]; /* Append calculation results to HTML document. */ var outputParagraph = document.createElement("p"); contentToAppend.forEach(function(element) { outputParagraph.appendChild(document.createTextNode(element)); outputParagraph.appendChild(document.createElement("br")); }); document.body.appendChild(outputParagraph); return true; } /** Confirm that all dates are valid Date values and that they follow business rules. * @param {Date} productPurchaseDate Date of purchase of the product(s) covered by the contract. * @param {Date} contractPurchaseDate Date of purchase of the contract to be cancelled. * @param {Date} cancelDate Date on which the cancellation of the contract was requested. * @param {Date} expirationDate Date on which the contract expires and is no longer eligible for cancellation or claims payment. * @return {Array} Array of Strings containing all applicable error messages. */ function validateDates(productPurchaseDate, contractPurchaseDate, cancelDate, expirationDate) { "use strict"; var dateErrors = new Array(); if (!isValidDate(productPurchaseDate)) { dateErrors.push("Invalid Product Purchase Date: " + productPurchaseDate); } if (!isValidDate(contractPurchaseDate)) { dateErrors.push("Invalid Contract Purchase Date: " + contractPurchaseDate); } if (contractPurchaseDate < productPurchaseDate) { dateErrors.push("Contract cannot be purchased (" + formatDate(contractPurchaseDate) + ") prior to the product (" + formatDate(productPurchaseDate) + ")"); } if (!isValidDate(cancelDate)) { dateErrors.push("Invalid Cancel Date: " + cancelDate); } if (cancelDate < productPurchaseDate || cancelDate < contractPurchaseDate) { dateErrors.push("Cancel date (" + formatDate(cancelDate) + ") cannot be prior to Product (" + formatDate(productPurchaseDate) + ") or Contract purchase (" + formatDate(contractPurchaseDate) + ")"); } if (cancelDate > expirationDate) { dateErrors.push("Cancel date (" + formatDate(cancelDate) + ") cannot be past Expiration date (" + formatDate(expirationDate) + ")"); } return dateErrors; } /** Confirm that all numbers are valid numbers and that they follow business rules. * @param {number} purchasePrice The dollar amount purchase price of the contract. * @param {number} termInYears The duration term of the policy in 365-day years. Must be whole number. * @param {number} amtPaidInClaims The dollar amount of claims paid against the contract prior to cancellation. * @param {number} gracePeriodInDays Grace period during which a contract holder can cancel with full refund/credit. Must be whole number. * @return {Array} Array of Strings containing all applicable error messages. */ function validateNums (purchasePrice, termInYears, amtPaidInClaims, gracePeriodInDays) { "use strict"; var numErrors = new Array(); if (isNaN(purchasePrice) || purchasePrice < 0) { numErrors.push("Invalid purchase price: " + purchasePrice); } if (isNaN(termInYears) || termInYears < 0) { numErrors.push("Invalid Term (in years): " + termInYears); } if (isNaN(amtPaidInClaims) || amtPaidInClaims < 0) { numErrors.push("Invalid paid claims amount: " + amtPaidInClaims); } if (isNaN(gracePeriodInDays) || gracePeriodInDays < 0) { numErrors.push("Invalid grace period: " + gracePeriodInDays); } if (termInYears % 1 !== 0) { numErrors.push("Term (in years) " + termInYears + " is not a whole number."); } if (gracePeriodInDays % 1 !== 0) { numErrors.push("Grace Period (in days) " + gracePeriodInDays + " is not a whole number."); } return numErrors; } /** Utility function to make sure an input is a correct Date format * @param {Date} date A date or date-time value. * @returns {boolean} Whether the input date is a valid date. */ function isValidDate(date) { "use strict"; if (isNaN(date.getTime())) { return false; } return (Object.prototype.toString.call(date) === "[object Date]"); } /** Utility function to convert a Date to MM/DD/YYYY formatted String. * @param {Date} date A date or date-time value. * @returns {string} A String formatted as MM/DD/YYYY if date is valid, otherwise a String with error message. */ function formatDate(date) { "use strict"; var inputDate = new Date(date); if (isValidDate(inputDate)) { var year = inputDate.getFullYear().toString(); var month = (1 + inputDate.getMonth()).toString(); // months are 0-indexed hence the 1 + getMonth() var day = inputDate.getDate().toString(); return(month + '/' + day + '/' + year); } else { return("Invalid date: " + inputDate); } } </script> </body> </html> <!DOCTYPE html> <html> <head> <title>Prorated Refund Calculator</title> <style> body { font-family: Calibri, Arial, sans-serif; font-size: 1.0em; } h1 { font-size: 1.2em; } </style> </head> <body> <h1>Prorated Refund Calculator</h1> <p>Input into the following fields and press Calculate.</p> <p style="color: red;">Enter date format as MM/DD/YYYY</p> <form> <label>Product Purchase Date: <input type="text" id="productPurchaseDate" /> </label><br/> <label>Contract Purchase Date: <input type="text" id="contractPurchaseDate" /> </label><br/> <label>Purchase Price: <input type="text" id="purchasePrice" /> </label><br/> <label>Term (in years): <input type="text" id="termInYears" value="10" /> </label><br/> <label>Cancel Date: <input type="text" id="cancelDate" /> </label><br/> <label>Amount paid in claims: <input type="text" id="amtPaidInClaims" value="0" /> </label><br/> <label>Grace period (in days): <input type="text" id="gracePeriodInDays" value="60" /></label><br/> </form> <br/> <button onclick="calculateProratedRefund()">Calculate</button> <script type="text/javascript"> /** /* Main function called by HTML form. * Validates input values, then performs calculations * and adds the result into the HTML document to display to the user. */ function calculateProratedRefund() { "use strict"; var productPurchaseDate = new Date (document.getElementById("productPurchaseDate").value); var contractPurchaseDate = new Date (document.getElementById("contractPurchaseDate").value); var purchasePrice = parseFloat (document.getElementById("purchasePrice").value).toFixed(2); var termInYears = parseInt (document.getElementById("termInYears").value, 10); var cancelDate = new Date (document.getElementById("cancelDate").value); var amtPaidInClaims = parseFloat (document.getElementById("amtPaidInClaims").value).toFixed(2); var gracePeriodInDays = parseInt (document.getElementById("gracePeriodInDays").value, 10); /** * Underwriting policies specify that a Year of coverage is exactly 365 Days, regardless of Leap Years. * Hence the following calculations: */ var totalDays = termInYears * 365; var expirationDate = new Date(productPurchaseDate); expirationDate.setDate(productPurchaseDate.getDate() + (totalDays)); /** * Validation of user input. * If any values are invalid, we return early and exit the function with error message to the user. * If all the input values are valid, we proceed to calculations. * NOTE: The two validation functions return an array of errors pushed from the called function. * If the array's length is 0 (i.e., empty array) there are no errors. */ var datesValid = validateDates(productPurchaseDate, contractPurchaseDate, cancelDate, expirationDate); var numsValid = validateNums(purchasePrice, termInYears, amtPaidInClaims, gracePeriodInDays); if (datesValid.length > 0 || numsValid.length > 0) { window.alert("Some values are invalid: \n" + "\n" + datesValid.join("\n") + "\n" + numsValid.join("\n") ); return false; } /** * All terms are calculated in Days, hence the following conversion from JavaScript's millisecond precision to Days. * (ms * secs * mins * hours) = 1 Day */ var msPerDay = 1000 * 60 * 60 * 24; var daysElapsed = Math.floor((Date.parse(cancelDate) - Date.parse(contractPurchaseDate)) / msPerDay); /** * Policy holder is entitled to a full refund within the grace period. * Otherwise, if days elapsed exceed the grace period, the refund becomes prorated. */ var termUsed = 0.0; if (daysElapsed > gracePeriodInDays) { termUsed = (daysElapsed / totalDays); } var termLeft = 1.0 - termUsed; /** * Finally we calculate the refund amount */ var proratedRefund = (purchasePrice * termLeft).toFixed(2); var finalRefund = (proratedRefund - amtPaidInClaims).toFixed(2); if (finalRefund < 0.0) { finalRefund = 0.0; } /** * List of content to append into document. */ var contentToAppend = [ "Product Purchase date: " + formatDate(productPurchaseDate), "Contract Purchase date: " + formatDate(contractPurchaseDate), "Total days: " + totalDays + " (" + termInYears + " years)", "Expiration date: " + formatDate(expirationDate), "Cancel date: " + formatDate(cancelDate), "Grace period: " + gracePeriodInDays + " days", "Days elapsed: " + daysElapsed + " (" + parseFloat(daysElapsed / 365).toFixed(4) + " years)", "Refund percent: " + (termLeft * 100).toFixed(2) + " %", "Purchase price: $ " + purchasePrice, "Prorated refund: $ " + proratedRefund, "Paid in claims: ($ " + amtPaidInClaims + ")", "Final refund: $ " + finalRefund ]; /** * Append calculation results to HTML document. */ var outputParagraph = document.createElement("p"); contentToAppend.forEach(function(element) { outputParagraph.appendChild(document.createTextNode(element)); outputParagraph.appendChild(document.createElement("br")); }); document.body.appendChild(outputParagraph); return true; } /** * Confirm that all dates are valid Date values and that they follow business rules. * @param productPurchaseDate@param {Date} -productPurchaseDate Date of purchase of the product(s) covered by the contract. * @param contractPurchaseDate@param {Date} -contractPurchaseDate Date of purchase of the contract to be cancelled. * @param {Date} cancelDate Date - Date on which the cancellation of the contract was requested. * @param {Date} expirationDate Date - Date on which the contract expires and is no longer eligible for cancellation or claims payment. * @return {Array-} Array of Strings containing all applicable error messages. */ function validateDates(productPurchaseDate, contractPurchaseDate, cancelDate, expirationDate) { "use strict"; var dateErrors = new Array(); if (!isValidDate(productPurchaseDate)) { dateErrors.push("Invalid Product Purchase Date: " + productPurchaseDate); } if (!isValidDate(contractPurchaseDate)) { dateErrors.push("Invalid Contract Purchase Date: " + contractPurchaseDate); } if (contractPurchaseDate < productPurchaseDate) { dateErrors.push("Contract cannot be purchased (" + formatDate(contractPurchaseDate) + ") prior to the product (" + formatDate(productPurchaseDate) + ")"); } if (!isValidDate(cancelDate)) { dateErrors.push("Invalid Cancel Date: " + cancelDate); } if (cancelDate < productPurchaseDate || cancelDate < contractPurchaseDate) { dateErrors.push("Cancel date (" + formatDate(cancelDate) + ") cannot be prior to Product (" + formatDate(productPurchaseDate) + ") or Contract purchase (" + formatDate(contractPurchaseDate) + ")"); } if (cancelDate > expirationDate) { dateErrors.push("Cancel date (" + formatDate(cancelDate) + ") cannot be past Expiration date (" + formatDate(expirationDate) + ")"); } return dateErrors; } /** * Confirm that all numbers are valid numbers and that they follow business rules. * @param {number} purchasePrice float - The dollar amount purchase price of the contract. * @param {number} termInYears int - The duration term of the policy in 365-day years. Must be whole number. * @param {number} amtPaidInClaims float - The dollar amount of claims paid against the contract prior to cancellation. * @param gracePeriodInDays int@param -{number} ThegracePeriodInDays graceGrace period during which a contract holder can cancel with full refund/credit. Must be whole number. * @return {Array} - Array of Strings containing all applicable error messages. */ function validateNums (purchasePrice, termInYears, amtPaidInClaims, gracePeriodInDays) { "use strict"; var numErrors = new Array(); if (isNaN(purchasePrice) || purchasePrice < 0) { numErrors.push("Invalid purchase price: " + purchasePrice); } if (isNaN(termInYears) || termInYears < 0) { numErrors.push("Invalid term period: " + termInYears); } if (isNaN(amtPaidInClaims) || amtPaidInClaims < 0) { numErrors.push("Invalid paid claims amount: " + amtPaidInClaims); } if (isNaN(gracePeriodInDays) || gracePeriodInDays < 0) { numErrors.push("Invalid grace period: " + gracePeriodInDays); } if (termInYears % 1 !== 0) { numErrors.push("Term " + termInYears + " is not a whole number."); } if (gracePeriodInDays % 1 !== 0) { numErrors.push("Grace period " + gracePeriodInDays + " is not a whole number."); } return numErrors; } /** * Utility function to make sure an input is a correct Date format * @param date@param {Date} -date A date or date-time value. * @returns {boolean} - Whether the input date is a valid date. */ function isValidDate(date) { "use strict"; if (isNaN(date.getTime())) { return false; } return (Object.prototype.toString.call(date) === "[object Date]"); } /** * Utility function to convert a Date to MM/DD/YYYY formatted String. * @param date@param {Date} -date A date or date-time value. * @returns String{string} - A String formatted as MM/DD/YYYY if date is valid, otherwise a String with error message. */ function formatDate(date) { "use strict"; var inputDate = new Date(date); if (isValidDate(inputDate)) { var year = inputDate.getFullYear().toString(); var month = (1 + inputDate.getMonth()).toString(); // months are 0-indexed hence the 1 + getMonth() var day = inputDate.getDate().toString(); return(month + '/' + day + '/' + year); } else { return("Invalid date: " + inputDate); } } </script> </body> </html> <!DOCTYPE html> <html> <head> <title>Prorated Refund Calculator</title> <style> body { font-family: Calibri, Arial, sans-serif; font-size: 1.0em; } h1 { font-size: 1.2em; } </style> </head> <body> <h1>Prorated Refund Calculator</h1> <p>Input into the following fields and press Calculate.</p> <p style="color: red;">Enter date format as MM/DD/YYYY</p> <form> <label>Product Purchase Date: <input type="text" id="productPurchaseDate" /> </label><br/> <label>Contract Purchase Date: <input type="text" id="contractPurchaseDate" /> </label><br/> <label>Purchase Price: <input type="text" id="purchasePrice" /> </label><br/> <label>Term (in years): <input type="text" id="termInYears" value="10" /> </label><br/> <label>Cancel Date: <input type="text" id="cancelDate" /> </label><br/> <label>Amount paid in claims: <input type="text" id="amtPaidInClaims" value="0" /> </label><br/> <label>Grace period (in days): <input type="text" id="gracePeriodInDays" value="60" /></label><br/> </form> <br/> <button onclick="calculateProratedRefund()">Calculate</button> <script type="text/javascript"> /** * Main function called by HTML form. * Validates input values, then performs calculations * and adds the result into the HTML document to display to the user. */ function calculateProratedRefund() { "use strict"; var productPurchaseDate = new Date(document.getElementById("productPurchaseDate").value); var contractPurchaseDate = new Date(document.getElementById("contractPurchaseDate").value); var purchasePrice = parseFloat(document.getElementById("purchasePrice").value).toFixed(2); var termInYears = parseInt(document.getElementById("termInYears").value, 10); var cancelDate = new Date(document.getElementById("cancelDate").value); var amtPaidInClaims = parseFloat(document.getElementById("amtPaidInClaims").value).toFixed(2); var gracePeriodInDays = parseInt(document.getElementById("gracePeriodInDays").value, 10); /** * Underwriting policies specify that a Year of coverage is exactly 365 Days, regardless of Leap Years. * Hence the following calculations: */ var totalDays = termInYears * 365; var expirationDate = new Date(productPurchaseDate); expirationDate.setDate(productPurchaseDate.getDate() + (totalDays)); /** * Validation of user input. * If any values are invalid, we return early and exit the function with error message to the user. * If all the input values are valid, we proceed to calculations. * NOTE: The two validation functions return an array of errors pushed from the called function. * If the array's length is 0 (i.e., empty array) there are no errors. */ var datesValid = validateDates(productPurchaseDate, contractPurchaseDate, cancelDate, expirationDate); var numsValid = validateNums(purchasePrice, termInYears, amtPaidInClaims, gracePeriodInDays); if (datesValid.length > 0 || numsValid.length > 0) { window.alert("Some values are invalid: \n" + "\n" + datesValid.join("\n") + "\n" + numsValid.join("\n") ); return false; } /** * All terms are calculated in Days, hence the following conversion from JavaScript's millisecond precision to Days. * (ms * secs * mins * hours) = 1 Day */ var msPerDay = 1000 * 60 * 60 * 24; var daysElapsed = Math.floor((Date.parse(cancelDate) - Date.parse(contractPurchaseDate)) / msPerDay); /** * Policy holder is entitled to a full refund within the grace period. * Otherwise, if days elapsed exceed the grace period, the refund becomes prorated. */ var termUsed = 0.0; if (daysElapsed > gracePeriodInDays) { termUsed = (daysElapsed / totalDays); } var termLeft = 1.0 - termUsed; /** * Finally we calculate the refund amount */ var proratedRefund = (purchasePrice * termLeft).toFixed(2); var finalRefund = (proratedRefund - amtPaidInClaims).toFixed(2); if (finalRefund < 0.0) { finalRefund = 0.0; } /** * List of content to append into document. */ var contentToAppend = [ "Product Purchase date: " + formatDate(productPurchaseDate), "Contract Purchase date: " + formatDate(contractPurchaseDate), "Total days: " + totalDays + " (" + termInYears + " years)", "Expiration date: " + formatDate(expirationDate), "Cancel date: " + formatDate(cancelDate), "Grace period: " + gracePeriodInDays + " days", "Days elapsed: " + daysElapsed + " (" + parseFloat(daysElapsed / 365).toFixed(4) + " years)", "Refund percent: " + (termLeft * 100).toFixed(2) + " %", "Purchase price: $ " + purchasePrice, "Prorated refund: $ " + proratedRefund, "Paid in claims: ($ " + amtPaidInClaims + ")", "Final refund: $ " + finalRefund ]; /** * Append calculation results to HTML document. */ var outputParagraph = document.createElement("p"); contentToAppend.forEach(function(element) { outputParagraph.appendChild(document.createTextNode(element)); outputParagraph.appendChild(document.createElement("br")); }); document.body.appendChild(outputParagraph); return true; } /** * Confirm that all dates are valid Date values and that they follow business rules. * @param productPurchaseDate Date - Date of purchase of the product(s) covered by the contract. * @param contractPurchaseDate Date - Date of purchase of the contract to be cancelled. * @param cancelDate Date - Date on which the cancellation of the contract was requested. * @param expirationDate Date - Date on which the contract expires and is no longer eligible for cancellation or claims payment. * @return Array- Array of Strings containing all applicable error messages. */ function validateDates(productPurchaseDate, contractPurchaseDate, cancelDate, expirationDate) { "use strict"; var dateErrors = new Array(); if (!isValidDate(productPurchaseDate)) { dateErrors.push("Invalid Product Purchase Date: " + productPurchaseDate); } if (!isValidDate(contractPurchaseDate)) { dateErrors.push("Invalid Contract Purchase Date: " + contractPurchaseDate); } if (contractPurchaseDate < productPurchaseDate) { dateErrors.push("Contract cannot be purchased (" + formatDate(contractPurchaseDate) + ") prior to the product (" + formatDate(productPurchaseDate) + ")"); } if (!isValidDate(cancelDate)) { dateErrors.push("Invalid Cancel Date: " + cancelDate); } if (cancelDate < productPurchaseDate || cancelDate < contractPurchaseDate) { dateErrors.push("Cancel date (" + formatDate(cancelDate) + ") cannot be prior to Product (" + formatDate(productPurchaseDate) + ") or Contract purchase (" + formatDate(contractPurchaseDate) + ")"); } if (cancelDate > expirationDate) { dateErrors.push("Cancel date (" + formatDate(cancelDate) + ") cannot be past Expiration date (" + formatDate(expirationDate) + ")"); } return dateErrors; } /** * Confirm that all numbers are valid numbers and that they follow business rules. * @param purchasePrice float - The dollar amount purchase price of the contract. * @param termInYears int - The duration term of the policy in 365-day years. * @param amtPaidInClaims float - The dollar amount of claims paid against the contract prior to cancellation. * @param gracePeriodInDays int - The grace period during which a contract holder can cancel with full refund/credit. * @return Array - Array of Strings containing all applicable error messages. */ function validateNums (purchasePrice, termInYears, amtPaidInClaims, gracePeriodInDays) { "use strict"; var numErrors = new Array(); if (isNaN(purchasePrice) || purchasePrice < 0) { numErrors.push("Invalid purchase price: " + purchasePrice); } if (isNaN(termInYears) || termInYears < 0) { numErrors.push("Invalid term period: " + termInYears); } if (isNaN(amtPaidInClaims) || amtPaidInClaims < 0) { numErrors.push("Invalid paid claims amount: " + amtPaidInClaims); } if (isNaN(gracePeriodInDays) || gracePeriodInDays < 0) { numErrors.push("Invalid grace period: " + gracePeriodInDays); } return numErrors; } /** * Utility function to make sure an input is a correct Date format * @param date Date - A date or date-time value. * @returns boolean - Whether the input date is a valid date. */ function isValidDate(date) { "use strict"; if (isNaN(date.getTime())) { return false; } return (Object.prototype.toString.call(date) === "[object Date]"); } /** * Utility function to convert a Date to MM/DD/YYYY formatted String. * @param date Date - A date or date-time value. * @returns String - A String formatted as MM/DD/YYYY if date is valid, otherwise a String with error message. */ function formatDate(date) { "use strict"; var inputDate = new Date(date); if (isValidDate(inputDate)) { var year = inputDate.getFullYear().toString(); var month = (1 + inputDate.getMonth()).toString(); // months are 0-indexed hence the 1 + getMonth() var day = inputDate.getDate().toString(); return(month + '/' + day + '/' + year); } else { return("Invalid date: " + inputDate); } } </script> </body> </html> <!DOCTYPE html> <html> <head> <title>Prorated Refund Calculator</title> <style> body { font-family: Calibri, Arial, sans-serif; font-size: 1.0em; } h1 { font-size: 1.2em; } </style> </head> <body> <h1>Prorated Refund Calculator</h1> <p>Input into the following fields and press Calculate.</p> <p style="color: red;">Enter date format as MM/DD/YYYY</p> <form> <label>Product Purchase Date: <input type="text" id="productPurchaseDate" /> </label><br/> <label>Contract Purchase Date: <input type="text" id="contractPurchaseDate" /> </label><br/> <label>Purchase Price: <input type="text" id="purchasePrice" /> </label><br/> <label>Term (in years): <input type="text" id="termInYears" value="10" /> </label><br/> <label>Cancel Date: <input type="text" id="cancelDate" /> </label><br/> <label>Amount paid in claims: <input type="text" id="amtPaidInClaims" value="0" /> </label><br/> <label>Grace period (in days): <input type="text" id="gracePeriodInDays" value="60" /></label><br/> </form> <br/> <button onclick="calculateProratedRefund()">Calculate</button> <script type="text/javascript"> /* Main function called by HTML form. * Validates input values, then performs calculations * and adds the result into the HTML document to display to the user. */ function calculateProratedRefund() { "use strict"; var productPurchaseDate = new Date (document.getElementById("productPurchaseDate").value); var contractPurchaseDate = new Date (document.getElementById("contractPurchaseDate").value); var purchasePrice = parseFloat (document.getElementById("purchasePrice").value).toFixed(2); var termInYears = parseInt (document.getElementById("termInYears").value, 10); var cancelDate = new Date (document.getElementById("cancelDate").value); var amtPaidInClaims = parseFloat (document.getElementById("amtPaidInClaims").value).toFixed(2); var gracePeriodInDays = parseInt (document.getElementById("gracePeriodInDays").value, 10); /* Underwriting policies specify that a Year of coverage is exactly 365 Days, regardless of Leap Years. * Hence the following calculations: */ var totalDays = termInYears * 365; var expirationDate = new Date(productPurchaseDate); expirationDate.setDate(productPurchaseDate.getDate() + (totalDays)); /* Validation of user input. * If any values are invalid, we return early and exit the function with error message to the user. * If all the input values are valid, we proceed to calculations. * NOTE: The two validation functions return an array of errors pushed from the called function. * If the array's length is 0 (i.e., empty array) there are no errors. */ var datesValid = validateDates(productPurchaseDate, contractPurchaseDate, cancelDate, expirationDate); var numsValid = validateNums(purchasePrice, termInYears, amtPaidInClaims, gracePeriodInDays); if (datesValid.length > 0 || numsValid.length > 0) { window.alert("Some values are invalid: \n" + "\n" + datesValid.join("\n") + "\n" + numsValid.join("\n") ); return false; } /* All terms are calculated in Days, hence the following conversion from JavaScript's millisecond precision to Days. * (ms * secs * mins * hours) = 1 Day */ var msPerDay = 1000 * 60 * 60 * 24; var daysElapsed = Math.floor((Date.parse(cancelDate) - Date.parse(contractPurchaseDate)) / msPerDay); /* Policy holder is entitled to a full refund within the grace period. * Otherwise, if days elapsed exceed the grace period, the refund becomes prorated. */ var termUsed = 0.0; if (daysElapsed > gracePeriodInDays) { termUsed = (daysElapsed / totalDays); } var termLeft = 1.0 - termUsed; /* Finally we calculate the refund amount */ var proratedRefund = (purchasePrice * termLeft).toFixed(2); var finalRefund = (proratedRefund - amtPaidInClaims).toFixed(2); if (finalRefund < 0.0) { finalRefund = 0.0; } /* List of content to append into document. */ var contentToAppend = [ "Product Purchase date: " + formatDate(productPurchaseDate), "Contract Purchase date: " + formatDate(contractPurchaseDate), "Total days: " + totalDays + " (" + termInYears + " years)", "Expiration date: " + formatDate(expirationDate), "Cancel date: " + formatDate(cancelDate), "Grace period: " + gracePeriodInDays + " days", "Days elapsed: " + daysElapsed + " (" + parseFloat(daysElapsed / 365).toFixed(4) + " years)", "Refund percent: " + (termLeft * 100).toFixed(2) + " %", "Purchase price: $ " + purchasePrice, "Prorated refund: $ " + proratedRefund, "Paid in claims: ($ " + amtPaidInClaims + ")", "Final refund: $ " + finalRefund ]; /* Append calculation results to HTML document. */ var outputParagraph = document.createElement("p"); contentToAppend.forEach(function(element) { outputParagraph.appendChild(document.createTextNode(element)); outputParagraph.appendChild(document.createElement("br")); }); document.body.appendChild(outputParagraph); return true; } /** Confirm that all dates are valid Date values and that they follow business rules. * @param {Date} productPurchaseDate Date of purchase of the product(s) covered by the contract. * @param {Date} contractPurchaseDate Date of purchase of the contract to be cancelled. * @param {Date} cancelDate Date on which the cancellation of the contract was requested. * @param {Date} expirationDate Date on which the contract expires and is no longer eligible for cancellation or claims payment. * @return {Array} Array of Strings containing all applicable error messages. */ function validateDates(productPurchaseDate, contractPurchaseDate, cancelDate, expirationDate) { "use strict"; var dateErrors = new Array(); if (!isValidDate(productPurchaseDate)) { dateErrors.push("Invalid Product Purchase Date: " + productPurchaseDate); } if (!isValidDate(contractPurchaseDate)) { dateErrors.push("Invalid Contract Purchase Date: " + contractPurchaseDate); } if (contractPurchaseDate < productPurchaseDate) { dateErrors.push("Contract cannot be purchased (" + formatDate(contractPurchaseDate) + ") prior to the product (" + formatDate(productPurchaseDate) + ")"); } if (!isValidDate(cancelDate)) { dateErrors.push("Invalid Cancel Date: " + cancelDate); } if (cancelDate < productPurchaseDate || cancelDate < contractPurchaseDate) { dateErrors.push("Cancel date (" + formatDate(cancelDate) + ") cannot be prior to Product (" + formatDate(productPurchaseDate) + ") or Contract purchase (" + formatDate(contractPurchaseDate) + ")"); } if (cancelDate > expirationDate) { dateErrors.push("Cancel date (" + formatDate(cancelDate) + ") cannot be past Expiration date (" + formatDate(expirationDate) + ")"); } return dateErrors; } /** Confirm that all numbers are valid numbers and that they follow business rules. * @param {number} purchasePrice The dollar amount purchase price of the contract. * @param {number} termInYears The duration term of the policy in 365-day years. Must be whole number. * @param {number} amtPaidInClaims The dollar amount of claims paid against the contract prior to cancellation. * @param {number} gracePeriodInDays Grace period during which a contract holder can cancel with full refund/credit. Must be whole number. * @return {Array} Array of Strings containing all applicable error messages. */ function validateNums (purchasePrice, termInYears, amtPaidInClaims, gracePeriodInDays) { "use strict"; var numErrors = new Array(); if (isNaN(purchasePrice) || purchasePrice < 0) { numErrors.push("Invalid purchase price: " + purchasePrice); } if (isNaN(termInYears) || termInYears < 0) { numErrors.push("Invalid term period: " + termInYears); } if (isNaN(amtPaidInClaims) || amtPaidInClaims < 0) { numErrors.push("Invalid paid claims amount: " + amtPaidInClaims); } if (isNaN(gracePeriodInDays) || gracePeriodInDays < 0) { numErrors.push("Invalid grace period: " + gracePeriodInDays); } if (termInYears % 1 !== 0) { numErrors.push("Term " + termInYears + " is not a whole number."); } if (gracePeriodInDays % 1 !== 0) { numErrors.push("Grace period " + gracePeriodInDays + " is not a whole number."); } return numErrors; } /** Utility function to make sure an input is a correct Date format * @param {Date} date A date or date-time value. * @returns {boolean} Whether the input date is a valid date. */ function isValidDate(date) { "use strict"; if (isNaN(date.getTime())) { return false; } return (Object.prototype.toString.call(date) === "[object Date]"); } /** Utility function to convert a Date to MM/DD/YYYY formatted String. * @param {Date} date A date or date-time value. * @returns {string} A String formatted as MM/DD/YYYY if date is valid, otherwise a String with error message. */ function formatDate(date) { "use strict"; var inputDate = new Date(date); if (isValidDate(inputDate)) { var year = inputDate.getFullYear().toString(); var month = (1 + inputDate.getMonth()).toString(); // months are 0-indexed hence the 1 + getMonth() var day = inputDate.getDate().toString(); return(month + '/' + day + '/' + year); } else { return("Invalid date: " + inputDate); } } </script> </body> </html> I applied @janos' idea of adding error messages to arrays, then checking for array.length > 0 and print those values in an alert to the user, like so:
<!DOCTYPE html> <html> <head> <title>Prorated Refund Calculator</title> <style> body { font-family: Calibri, Arial, sans-serif; font-size: 1.0em; } h1 { font-size: 1.2em; } </style> </head> <body> <h1>Prorated Refund Calculator</h1> <p>Input into the following fields and press Calculate.</p> <p style="color: red;">Enter date format as MM/DD/YYYY</p> <form> <label>Product Purchase Date: <input type="text" id="productPurchaseDate" /> </label><br/> <label>Contract Purchase Date: <input type="text" id="contractPurchaseDate" /> </label><br/> <label>Purchase Price: <input type="text" id="purchasePrice" /> </label><br/> <label>Term (in years): <input type="text" id="termInYears" value="10" /> </label><br/> <label>Cancel Date: <input type="text" id="cancelDate" /> </label><br/> <label>Amount paid in claims: <input type="text" id="amtPaidInClaims" value="0" /> </label><br/> <label>Grace period (in days): <input type="text" id="gracePeriodInDays" value="60" /></label><br/> </form> <br/> <button onclick="calculateProratedRefund()">Calculate</button> <script type="text/javascript"> /** * Main function called by HTML form. * Validates input values, then performs calculations * and adds the result into the HTML document to display to the user. */ function calculateProratedRefund() { "use strict"; var productPurchaseDate = new Date(document.getElementById("productPurchaseDate").value); var contractPurchaseDate = new Date(document.getElementById("contractPurchaseDate").value); var purchasePrice = parseFloat(document.getElementById("purchasePrice").value).toFixed(2); var termInYears = parseInt(document.getElementById("termInYears").value, 10); var cancelDate = new Date(document.getElementById("cancelDate").value); var amtPaidInClaims = parseFloat(document.getElementById("amtPaidInClaims").value).toFixed(2); var gracePeriodInDays = parseInt(document.getElementById("gracePeriodInDays").value, 10); /** * Underwriting policies specify that a Year of coverage is exactly 365 Days, regardless of Leap Years. * Hence the following calculations: */ var totalDays = termInYears * 365; var expirationDate = new Date(productPurchaseDate); expirationDate.setDate(productPurchaseDate.getDate() + (totalDays)); /** * Validation of user input. * If any values are invalid, we return early and exit the function with error message to the user. * If all the input values are valid, we proceed to calculations. * NOTE: The two validation functions return an array of errors pushed from the called function. * If the array's length is 0 (i.e., empty array) there are no errors. */ var datesValid = validateDates(productPurchaseDate, contractPurchaseDate, cancelDate, expirationDate); var numsValid = validateNums(purchasePrice, termInYears, amtPaidInClaims, gracePeriodInDays); if (!datesValid.length > 0 || !numsValid.length > 0) { window.alert("Some values are invalid: \n" + "\n" + datesValid.join("\n") Please check your input and try again + "\n" + numsValid."join("\n") ); return false; } /** * All terms are calculated in Days, hence the following conversion from JavaScript's millisecond precision to Days. * (ms * secs * mins * hours) = 1 Day */ var msPerDay = 1000 * 60 * 60 * 24; var daysElapsed = Math.floor((Date.parse(cancelDate) - Date.parse(contractPurchaseDate)) / msPerDay); /** * Policy holder is entitled to a full refund within the grace period. * Otherwise, if days elapsed exceed the grace period, the refund becomes prorated. */ var termUsed = 0.0; if (daysElapsed > gracePeriodInDays) { termUsed = (daysElapsed / totalDays); } var termLeft = 1.0 - termUsed; /** * Finally we calculate the refund amount */ var proratedRefund = (purchasePrice * termLeft).toFixed(2); var finalRefund = (proratedRefund - amtPaidInClaims).toFixed(2); if (finalRefund < 0.0) { finalRefund = 0.0; } /** * List of content to append into document. */ var contentToAppend = [ "Product Purchase date: " + formatDate(productPurchaseDate), "Contract Purchase date: " + formatDate(contractPurchaseDate), "Total days: " + totalDays + " (" + termInYears + " years)", "Expiration date: " + formatDate(expirationDate), "Cancel date: " + formatDate(cancelDate), "Grace period: " + gracePeriodInDays + " days", "Days elapsed: " + daysElapsed + " (" + parseFloat(daysElapsed / 365).toFixed(4) + " years)", "Refund percent: " + (termLeft * 100).toFixed(2) + " %", "Purchase price: $ " + purchasePrice, "Prorated refund: $ " + proratedRefund, "Paid in claims: ($ " + amtPaidInClaims + ")", "Final refund: $ " + finalRefund ]; /** * Append calculation results to HTML document. */ var outputParagraph = document.createElement("p"); contentToAppend.forEach(function(element) { outputParagraph.appendChild(document.createTextNode(element)); outputParagraph.appendChild(document.createElement("br")); }); document.body.appendChild(outputParagraph); return true; } /** * Confirm that all dates are valid Date values and that they follow business rules. * @param productPurchaseDate Date - Date of purchase of the product(s) covered by the contract. * @param contractPurchaseDate Date - Date of purchase of the contract to be cancelled. * @param cancelDate Date - Date on which the cancellation of the contract was requested. * @param expirationDate Date - Date on which the contract expires and is no longer eligible for cancellation or claims payment. * @return Array- Array of Strings containing all applicable error messages. */ function validateDates(productPurchaseDate, contractPurchaseDate, cancelDate, expirationDate) { "use strict"; var dateErrors = new Array(); if (!isValidDate(productPurchaseDate)) { windowdateErrors.alertpush("Invalid Product Purchase Date."); : " return+ false;productPurchaseDate); } if (!isValidDate(contractPurchaseDate)) { windowdateErrors.alertpush("Invalid Contract Purchase Date."); : " return+ false;contractPurchaseDate); } if (contractPurchaseDate < productPurchaseDate) { windowdateErrors.alertpush("Contract cannot be purchased prior(" to+ theformatDate(contractPurchaseDate) product. + "); prior to the product (" + formatDate(productPurchaseDate) return+ false;")"); } if (!isValidDate(cancelDate)) { windowdateErrors.alertpush("Invalid Cancel Date."); : " return+ false;cancelDate); } if (cancelDate < productPurchaseDate || cancelDate < contractPurchaseDate) { windowdateErrors.alertpush("Cancel date (" + formatDate(cancelDate) + ") cannot be prior to Product or Contract(" purchase+ date."formatDate(productPurchaseDate); return false; + ") or Contract purchase (" + formatDate(contractPurchaseDate) + ")"); } if (cancelDate > expirationDate) { windowdateErrors.alertpush("Cancel date cannot(" be+ pastformatDate(cancelDate) Expiration date. + "); cannot be past Expiration date (" + returnformatDate(expirationDate) false;+ ")"); } return true;dateErrors; } /** * Confirm that all numbers are valid numbers and that they follow business rules. * @param purchasePrice float - The dollar amount purchase price of the contract. * @param termInYears int - The duration term of the policy in 365-day years. * @param amtPaidInClaims float - The dollar amount of claims paid against the contract prior to cancellation. * @param gracePeriodInDays int - The grace period during which a contract holder can cancel with full refund/credit. * @return Array - Array of Strings containing all applicable error messages. */ function validateNums (purchasePrice, termInYears, amtPaidInClaims, gracePeriodInDays) { "use strict;"strict"; var numErrors = new Array(); if (isNaN(purchasePrice) || purchasePrice < 0) { windownumErrors.alertpush("Invalid purchase price."); : " return+ false;purchasePrice); } if (isNaN(termInYears) || termInYears < 0) { windownumErrors.alertpush("Invalid term period."); : " return+ false;termInYears); } if (isNaN(amtPaidInClaims) || amtPaidInClaims < 0) { windownumErrors.alertpush("Invalid paid claims amount."); : " return+ false;amtPaidInClaims); } if (isNaN(gracePeriodInDays) || gracePeriodInDays < 0) { windownumErrors.alertpush("Invalid grace period."); : " return+ false;gracePeriodInDays); } return true;numErrors; } /** * Utility function to make sure an input is a correct Date format * @param date Date - A date or date-time value. * @returns boolean - Whether the input date is a valid date. */ function isValidDate(date) { "use strict"; if (isNaN(date.getTime())) { return false; } return (Object.prototype.toString.call(date) === "[object Date]"); } /** * Utility function to convert a Date to MM/DD/YYYY formatted String. * @param date Date - A date or date-time value. * @returns String - A String formatted toas MM/DD/YYYY date if date is valid, otherwise a String with error message. */ function formatDate(date) { "use strict"; var inputDate = new Date(date); if (isValidDate(inputDate)) { var year = inputDate.getFullYear().toString(); var month = (1 + inputDate.getMonth()).toString(); // months are 0-indexed hence the 1 + getMonth() var day = inputDate.getDate().toString(); return(month + '/' + day + '/' + year); } else { return("Invalid date: " + inputDate); } } </script> </body> </html> <!DOCTYPE html> <html> <head> <title>Prorated Refund Calculator</title> <style> body { font-family: Calibri, Arial, sans-serif; font-size: 1.0em; } h1 { font-size: 1.2em; } </style> </head> <body> <h1>Prorated Refund Calculator</h1> <p>Input into the following fields and press Calculate.</p> <p style="color: red;">Enter date format as MM/DD/YYYY</p> <form> <label>Product Purchase Date: <input type="text" id="productPurchaseDate" /> </label><br/> <label>Contract Purchase Date: <input type="text" id="contractPurchaseDate" /> </label><br/> <label>Purchase Price: <input type="text" id="purchasePrice" /> </label><br/> <label>Term (in years): <input type="text" id="termInYears" value="10" /> </label><br/> <label>Cancel Date: <input type="text" id="cancelDate" /> </label><br/> <label>Amount paid in claims: <input type="text" id="amtPaidInClaims" value="0" /> </label><br/> <label>Grace period (in days): <input type="text" id="gracePeriodInDays" value="60" /></label><br/> </form> <br/> <button onclick="calculateProratedRefund()">Calculate</button> <script type="text/javascript"> /** * Main function called by HTML form. * Validates input values, then performs calculations * and adds the result into the HTML document to display to the user. */ function calculateProratedRefund() { "use strict"; var productPurchaseDate = new Date(document.getElementById("productPurchaseDate").value); var contractPurchaseDate = new Date(document.getElementById("contractPurchaseDate").value); var purchasePrice = parseFloat(document.getElementById("purchasePrice").value).toFixed(2); var termInYears = parseInt(document.getElementById("termInYears").value, 10); var cancelDate = new Date(document.getElementById("cancelDate").value); var amtPaidInClaims = parseFloat(document.getElementById("amtPaidInClaims").value).toFixed(2); var gracePeriodInDays = parseInt(document.getElementById("gracePeriodInDays").value, 10); /** * Underwriting policies specify that a Year of coverage is exactly 365 Days, regardless of Leap Years. * Hence the following calculations: */ var totalDays = termInYears * 365; var expirationDate = new Date(productPurchaseDate); expirationDate.setDate(productPurchaseDate.getDate() + (totalDays)); /** * Validation of user input. * If any values are invalid, we return early and exit the function with error message to the user. * If all the input values are valid, we proceed to calculations. */ var datesValid = validateDates(productPurchaseDate, contractPurchaseDate, cancelDate, expirationDate); var numsValid = validateNums(purchasePrice, termInYears, amtPaidInClaims, gracePeriodInDays); if (!datesValid || !numsValid) { window.alert("Some values are invalid. Please check your input and try again."); return false; } /** * All terms are calculated in Days, hence the following conversion from JavaScript's millisecond precision to Days. * (ms * secs * mins * hours) = 1 Day */ var msPerDay = 1000 * 60 * 60 * 24; var daysElapsed = Math.floor((Date.parse(cancelDate) - Date.parse(contractPurchaseDate)) / msPerDay); /** * Policy holder is entitled to a full refund within the grace period. */ var termUsed = 0.0; if (daysElapsed > gracePeriodInDays) { termUsed = (daysElapsed / totalDays); } var termLeft = 1.0 - termUsed; /** * Finally we calculate the refund amount */ var proratedRefund = (purchasePrice * termLeft).toFixed(2); var finalRefund = (proratedRefund - amtPaidInClaims).toFixed(2); if (finalRefund < 0.0) { finalRefund = 0.0; } /** * List of content to append into document. */ var contentToAppend = [ "Product Purchase date: " + formatDate(productPurchaseDate), "Contract Purchase date: " + formatDate(contractPurchaseDate), "Total days: " + totalDays + " (" + termInYears + " years)", "Expiration date: " + formatDate(expirationDate), "Cancel date: " + formatDate(cancelDate), "Grace period: " + gracePeriodInDays + " days", "Days elapsed: " + daysElapsed + " (" + parseFloat(daysElapsed / 365).toFixed(4) + " years)", "Refund percent: " + (termLeft * 100).toFixed(2) + " %", "Purchase price: $ " + purchasePrice, "Prorated refund: $ " + proratedRefund, "Paid in claims: $ " + amtPaidInClaims, "Final refund: $ " + finalRefund ]; /** * Append calculation results to HTML document. */ var outputParagraph = document.createElement("p"); contentToAppend.forEach(function(element) { outputParagraph.appendChild(document.createTextNode(element)); outputParagraph.appendChild(document.createElement("br")); }); document.body.appendChild(outputParagraph); return true; } /** * Confirm that all dates are valid Date values and that they follow business rules. */ function validateDates(productPurchaseDate, contractPurchaseDate, cancelDate, expirationDate) { "use strict"; if (!isValidDate(productPurchaseDate)) { window.alert("Invalid Product Purchase Date."); return false; } if (!isValidDate(contractPurchaseDate)) { window.alert("Invalid Contract Purchase Date."); return false; } if (contractPurchaseDate < productPurchaseDate) { window.alert("Contract cannot be purchased prior to the product."); return false; } if (!isValidDate(cancelDate)) { window.alert("Invalid Cancel Date."); return false; } if (cancelDate < productPurchaseDate || cancelDate < contractPurchaseDate) { window.alert("Cancel date cannot be prior to Product or Contract purchase date."); return false; } if (cancelDate > expirationDate) { window.alert("Cancel date cannot be past Expiration date."); return false; } return true; } /** * Confirm that all numbers are valid numbers and that they follow business rules. */ function validateNums (purchasePrice, termInYears, amtPaidInClaims, gracePeriodInDays) { "use strict;" if (isNaN(purchasePrice) || purchasePrice < 0) { window.alert("Invalid purchase price."); return false; } if (isNaN(termInYears) || termInYears < 0) { window.alert("Invalid term period."); return false; } if (isNaN(amtPaidInClaims) || amtPaidInClaims < 0) { window.alert("Invalid paid claims amount."); return false; } if (isNaN(gracePeriodInDays) || gracePeriodInDays < 0) { window.alert("Invalid grace period."); return false; } return true; } /** * Utility function to make sure an input is a correct Date format * @param date Date - A date or date-time value. * @returns boolean - Whether the input date is a valid date. */ function isValidDate(date) { "use strict"; if (isNaN(date.getTime())) { return false; } return (Object.prototype.toString.call(date) === "[object Date]"); } /** * Utility function to convert a Date to MM/DD/YYYY formatted String. * @param date Date - A date or date-time value. * @returns String - A String formatted to MM/DD/YYYY date if date is valid, otherwise a String with error message. */ function formatDate(date) { "use strict"; var inputDate = new Date(date); if (isValidDate(inputDate)) { var year = inputDate.getFullYear(); var month = (1 + inputDate.getMonth()).toString(); // months are 0-indexed hence the 1 + getMonth() var day = inputDate.getDate().toString(); return(month + '/' + day + '/' + year); } else { return("Invalid date: " + inputDate); } } </script> </body> </html> I applied @janos' idea of adding error messages to arrays, then checking for array.length > 0 and print those values in an alert to the user, like so:
<!DOCTYPE html> <html> <head> <title>Prorated Refund Calculator</title> <style> body { font-family: Calibri, Arial, sans-serif; font-size: 1.0em; } h1 { font-size: 1.2em; } </style> </head> <body> <h1>Prorated Refund Calculator</h1> <p>Input into the following fields and press Calculate.</p> <p style="color: red;">Enter date format as MM/DD/YYYY</p> <form> <label>Product Purchase Date: <input type="text" id="productPurchaseDate" /> </label><br/> <label>Contract Purchase Date: <input type="text" id="contractPurchaseDate" /> </label><br/> <label>Purchase Price: <input type="text" id="purchasePrice" /> </label><br/> <label>Term (in years): <input type="text" id="termInYears" value="10" /> </label><br/> <label>Cancel Date: <input type="text" id="cancelDate" /> </label><br/> <label>Amount paid in claims: <input type="text" id="amtPaidInClaims" value="0" /> </label><br/> <label>Grace period (in days): <input type="text" id="gracePeriodInDays" value="60" /></label><br/> </form> <br/> <button onclick="calculateProratedRefund()">Calculate</button> <script type="text/javascript"> /** * Main function called by HTML form. * Validates input values, then performs calculations * and adds the result into the HTML document to display to the user. */ function calculateProratedRefund() { "use strict"; var productPurchaseDate = new Date(document.getElementById("productPurchaseDate").value); var contractPurchaseDate = new Date(document.getElementById("contractPurchaseDate").value); var purchasePrice = parseFloat(document.getElementById("purchasePrice").value).toFixed(2); var termInYears = parseInt(document.getElementById("termInYears").value, 10); var cancelDate = new Date(document.getElementById("cancelDate").value); var amtPaidInClaims = parseFloat(document.getElementById("amtPaidInClaims").value).toFixed(2); var gracePeriodInDays = parseInt(document.getElementById("gracePeriodInDays").value, 10); /** * Underwriting policies specify that a Year of coverage is exactly 365 Days, regardless of Leap Years. * Hence the following calculations: */ var totalDays = termInYears * 365; var expirationDate = new Date(productPurchaseDate); expirationDate.setDate(productPurchaseDate.getDate() + (totalDays)); /** * Validation of user input. * If any values are invalid, we return early and exit the function with error message to the user. * If all the input values are valid, we proceed to calculations. * NOTE: The two validation functions return an array of errors pushed from the called function. * If the array's length is 0 (i.e., empty array) there are no errors. */ var datesValid = validateDates(productPurchaseDate, contractPurchaseDate, cancelDate, expirationDate); var numsValid = validateNums(purchasePrice, termInYears, amtPaidInClaims, gracePeriodInDays); if (datesValid.length > 0 || numsValid.length > 0) { window.alert("Some values are invalid: \n" + "\n" + datesValid.join("\n") + "\n" + numsValid.join("\n") ); return false; } /** * All terms are calculated in Days, hence the following conversion from JavaScript's millisecond precision to Days. * (ms * secs * mins * hours) = 1 Day */ var msPerDay = 1000 * 60 * 60 * 24; var daysElapsed = Math.floor((Date.parse(cancelDate) - Date.parse(contractPurchaseDate)) / msPerDay); /** * Policy holder is entitled to a full refund within the grace period. * Otherwise, if days elapsed exceed the grace period, the refund becomes prorated. */ var termUsed = 0.0; if (daysElapsed > gracePeriodInDays) { termUsed = (daysElapsed / totalDays); } var termLeft = 1.0 - termUsed; /** * Finally we calculate the refund amount */ var proratedRefund = (purchasePrice * termLeft).toFixed(2); var finalRefund = (proratedRefund - amtPaidInClaims).toFixed(2); if (finalRefund < 0.0) { finalRefund = 0.0; } /** * List of content to append into document. */ var contentToAppend = [ "Product Purchase date: " + formatDate(productPurchaseDate), "Contract Purchase date: " + formatDate(contractPurchaseDate), "Total days: " + totalDays + " (" + termInYears + " years)", "Expiration date: " + formatDate(expirationDate), "Cancel date: " + formatDate(cancelDate), "Grace period: " + gracePeriodInDays + " days", "Days elapsed: " + daysElapsed + " (" + parseFloat(daysElapsed / 365).toFixed(4) + " years)", "Refund percent: " + (termLeft * 100).toFixed(2) + " %", "Purchase price: $ " + purchasePrice, "Prorated refund: $ " + proratedRefund, "Paid in claims: ($ " + amtPaidInClaims + ")", "Final refund: $ " + finalRefund ]; /** * Append calculation results to HTML document. */ var outputParagraph = document.createElement("p"); contentToAppend.forEach(function(element) { outputParagraph.appendChild(document.createTextNode(element)); outputParagraph.appendChild(document.createElement("br")); }); document.body.appendChild(outputParagraph); return true; } /** * Confirm that all dates are valid Date values and that they follow business rules. * @param productPurchaseDate Date - Date of purchase of the product(s) covered by the contract. * @param contractPurchaseDate Date - Date of purchase of the contract to be cancelled. * @param cancelDate Date - Date on which the cancellation of the contract was requested. * @param expirationDate Date - Date on which the contract expires and is no longer eligible for cancellation or claims payment. * @return Array- Array of Strings containing all applicable error messages. */ function validateDates(productPurchaseDate, contractPurchaseDate, cancelDate, expirationDate) { "use strict"; var dateErrors = new Array(); if (!isValidDate(productPurchaseDate)) { dateErrors.push("Invalid Product Purchase Date: " + productPurchaseDate); } if (!isValidDate(contractPurchaseDate)) { dateErrors.push("Invalid Contract Purchase Date: " + contractPurchaseDate); } if (contractPurchaseDate < productPurchaseDate) { dateErrors.push("Contract cannot be purchased (" + formatDate(contractPurchaseDate) + ") prior to the product (" + formatDate(productPurchaseDate) + ")"); } if (!isValidDate(cancelDate)) { dateErrors.push("Invalid Cancel Date: " + cancelDate); } if (cancelDate < productPurchaseDate || cancelDate < contractPurchaseDate) { dateErrors.push("Cancel date (" + formatDate(cancelDate) + ") cannot be prior to Product (" + formatDate(productPurchaseDate) + ") or Contract purchase (" + formatDate(contractPurchaseDate) + ")"); } if (cancelDate > expirationDate) { dateErrors.push("Cancel date (" + formatDate(cancelDate) + ") cannot be past Expiration date (" + formatDate(expirationDate) + ")"); } return dateErrors; } /** * Confirm that all numbers are valid numbers and that they follow business rules. * @param purchasePrice float - The dollar amount purchase price of the contract. * @param termInYears int - The duration term of the policy in 365-day years. * @param amtPaidInClaims float - The dollar amount of claims paid against the contract prior to cancellation. * @param gracePeriodInDays int - The grace period during which a contract holder can cancel with full refund/credit. * @return Array - Array of Strings containing all applicable error messages. */ function validateNums (purchasePrice, termInYears, amtPaidInClaims, gracePeriodInDays) { "use strict"; var numErrors = new Array(); if (isNaN(purchasePrice) || purchasePrice < 0) { numErrors.push("Invalid purchase price: " + purchasePrice); } if (isNaN(termInYears) || termInYears < 0) { numErrors.push("Invalid term period: " + termInYears); } if (isNaN(amtPaidInClaims) || amtPaidInClaims < 0) { numErrors.push("Invalid paid claims amount: " + amtPaidInClaims); } if (isNaN(gracePeriodInDays) || gracePeriodInDays < 0) { numErrors.push("Invalid grace period: " + gracePeriodInDays); } return numErrors; } /** * Utility function to make sure an input is a correct Date format * @param date Date - A date or date-time value. * @returns boolean - Whether the input date is a valid date. */ function isValidDate(date) { "use strict"; if (isNaN(date.getTime())) { return false; } return (Object.prototype.toString.call(date) === "[object Date]"); } /** * Utility function to convert a Date to MM/DD/YYYY formatted String. * @param date Date - A date or date-time value. * @returns String - A String formatted as MM/DD/YYYY if date is valid, otherwise a String with error message. */ function formatDate(date) { "use strict"; var inputDate = new Date(date); if (isValidDate(inputDate)) { var year = inputDate.getFullYear().toString(); var month = (1 + inputDate.getMonth()).toString(); // months are 0-indexed hence the 1 + getMonth() var day = inputDate.getDate().toString(); return(month + '/' + day + '/' + year); } else { return("Invalid date: " + inputDate); } } </script> </body> </html> default

