From 26ce9b5c8adba10375a5cb4fc5e920d23f6f5bcb Mon Sep 17 00:00:00 2001 From: Hao Tran Date: Sat, 11 Jan 2025 08:38:12 -0500 Subject: [PATCH] Fix short-rate calculation, add styling, add error messages, include disclaimer --- assets/calculator.js | 561 ++++++++++++++++++++++++++++++++++++++++++ assets/favicon.ico | Bin 0 -> 318 bytes assets/style.css | 190 ++++++++++++++ index.html | 230 +++++++++-------- scripts/calculator.js | 114 --------- style.css | 76 ------ 6 files changed, 879 insertions(+), 292 deletions(-) create mode 100644 assets/calculator.js create mode 100644 assets/favicon.ico create mode 100644 assets/style.css delete mode 100644 scripts/calculator.js delete mode 100644 style.css diff --git a/assets/calculator.js b/assets/calculator.js new file mode 100644 index 0000000..33a4341 --- /dev/null +++ b/assets/calculator.js @@ -0,0 +1,561 @@ +const shortRate = { + 1: 0.05, + 2: 0.06, + 3: 0.07, + 4: 0.07, + 5: 0.08, + 6: 0.08, + 7: 0.09, + 8: 0.09, + 9: 0.10, + 10: 0.10, + 11: 0.11, + 12: 0.11, + 13: 0.12, + 14: 0.12, + 15: 0.13, + 16: 0.13, + 17: 0.14, + 18: 0.14, + 19: 0.15, + 20: 0.15, + 21: 0.16, + 22: 0.16, + 23: 0.17, + 24: 0.17, + 25: 0.17, + 26: 0.18, + 27: 0.18, + 28: 0.18, + 29: 0.18, + 30: 0.19, + 31: 0.19, + 32: 0.19, + 33: 0.20, + 34: 0.20, + 35: 0.20, + 36: 0.20, + 37: 0.21, + 38: 0.21, + 39: 0.21, + 40: 0.21, + 41: 0.22, + 42: 0.22, + 43: 0.22, + 44: 0.77, + 45: 0.77, + 46: 0.77, + 47: 0.77, + 48: 0.24, + 49: 0.24, + 50: 0.24, + 51: 0.24, + 52: 0.25, + 53: 0.25, + 54: 0.25, + 55: 0.26, + 56: 0.26, + 57: 0.26, + 58: 0.26, + 59: 0.27, + 60: 0.27, + 61: 0.27, + 62: 0.27, + 63: 0.28, + 64: 0.28, + 65: 0.28, + 66: 0.29, + 67: 0.29, + 68: 0.29, + 69: 0.29, + 70: 0.30, + 71: 0.30, + 72: 0.30, + 73: 0.30, + 74: 0.31, + 75: 0.31, + 76: 0.31, + 77: 0.32, + 78: 0.32, + 79: 0.32, + 80: 0.32, + 81: 0.33, + 82: 0.33, + 83: 0.33, + 84: 0.34, + 85: 0.34, + 86: 0.34, + 87: 0.34, + 88: 0.35, + 89: 0.35, + 90: 0.35, + 91: 0.35, + 92: 0.36, + 93: 0.36, + 94: 0.36, + 95: 0.37, + 96: 0.37, + 97: 0.37, + 98: 0.37, + 99: 0.38, + 100: 0.38, + 101: 0.38, + 102: 0.38, + 103: 0.39, + 104: 0.39, + 105: 0.39, + 106: 0.40, + 107: 0.40, + 108: 0.40, + 109: 0.40, + 110: 0.41, + 111: 0.41, + 112: 0.41, + 113: 0.41, + 114: 0.42, + 115: 0.42, + 116: 0.42, + 117: 0.43, + 118: 0.43, + 119: 0.43, + 120: 0.43, + 121: 0.44, + 122: 0.44, + 123: 0.44, + 124: 0.44, + 125: 0.45, + 126: 0.45, + 127: 0.45, + 128: 0.46, + 129: 0.46, + 130: 0.46, + 131: 0.46, + 132: 0.47, + 133: 0.47, + 134: 0.47, + 135: 0.47, + 136: 0.48, + 137: 0.48, + 138: 0.48, + 139: 0.49, + 140: 0.49, + 141: 0.49, + 142: 0.49, + 143: 0.50, + 144: 0.50, + 145: 0.50, + 146: 0.50, + 147: 0.51, + 148: 0.51, + 149: 0.51, + 150: 0.52, + 151: 0.52, + 152: 0.52, + 153: 0.52, + 154: 0.53, + 155: 0.53, + 156: 0.53, + 157: 0.53, + 158: 0.54, + 159: 0.54, + 160: 0.54, + 161: 0.55, + 162: 0.55, + 163: 0.55, + 164: 0.55, + 165: 0.56, + 166: 0.56, + 167: 0.56, + 168: 0.57, + 169: 0.57, + 170: 0.57, + 171: 0.57, + 172: 0.58, + 173: 0.58, + 174: 0.58, + 175: 0.58, + 176: 0.59, + 177: 0.59, + 178: 0.59, + 179: 0.60, + 180: 0.60, + 181: 0.60, + 182: 0.60, + 183: 0.61, + 184: 0.61, + 185: 0.61, + 186: 0.61, + 187: 0.61, + 188: 0.62, + 189: 0.62, + 190: 0.62, + 191: 0.62, + 192: 0.63, + 193: 0.63, + 194: 0.63, + 195: 0.63, + 196: 0.63, + 197: 0.64, + 198: 0.64, + 199: 0.64, + 200: 0.64, + 201: 0.65, + 202: 0.65, + 203: 0.65, + 204: 0.65, + 205: 0.65, + 206: 0.66, + 207: 0.66, + 208: 0.66, + 209: 0.66, + 210: 0.67, + 211: 0.67, + 212: 0.67, + 213: 0.67, + 214: 0.67, + 215: 0.68, + 216: 0.68, + 217: 0.68, + 218: 0.68, + 219: 0.69, + 220: 0.69, + 221: 0.69, + 222: 0.69, + 223: 0.69, + 224: 0.70, + 225: 0.70, + 226: 0.70, + 227: 0.70, + 228: 0.70, + 229: 0.71, + 230: 0.71, + 231: 0.71, + 232: 0.71, + 233: 0.72, + 234: 0.72, + 235: 0.72, + 236: 0.72, + 237: 0.72, + 238: 0.73, + 239: 0.73, + 240: 0.73, + 241: 0.73, + 242: 0.74, + 243: 0.74, + 244: 0.74, + 245: 0.74, + 246: 0.74, + 247: 0.75, + 248: 0.75, + 249: 0.75, + 250: 0.75, + 251: 0.76, + 252: 0.76, + 253: 0.76, + 254: 0.76, + 255: 0.76, + 256: 0.77, + 257: 0.77, + 258: 0.77, + 259: 0.77, + 260: 0.77, + 261: 0.78, + 262: 0.78, + 263: 0.78, + 264: 0.78, + 265: 0.79, + 266: 0.79, + 267: 0.79, + 268: 0.79, + 269: 0.79, + 270: 0.80, + 271: 0.80, + 272: 0.80, + 273: 0.80, + 274: 0.81, + 275: 0.81, + 276: 0.81, + 277: 0.81, + 278: 0.81, + 279: 0.82, + 280: 0.82, + 281: 0.82, + 282: 0.82, + 283: 0.83, + 284: 0.83, + 285: 0.83, + 286: 0.83, + 287: 0.83, + 288: 0.84, + 289: 0.84, + 290: 0.84, + 291: 0.84, + 292: 0.85, + 293: 0.85, + 294: 0.85, + 295: 0.85, + 296: 0.85, + 297: 0.86, + 298: 0.86, + 299: 0.86, + 300: 0.86, + 301: 0.86, + 302: 0.87, + 303: 0.87, + 304: 0.87, + 305: 0.87, + 306: 0.88, + 307: 0.88, + 308: 0.88, + 309: 0.88, + 310: 0.88, + 311: 0.89, + 312: 0.89, + 313: 0.89, + 314: 0.89, + 315: 0.90, + 316: 0.90, + 317: 0.90, + 318: 0.90, + 319: 0.90, + 320: 0.91, + 321: 0.91, + 322: 0.91, + 323: 0.91, + 324: 0.92, + 325: 0.92, + 326: 0.92, + 327: 0.92, + 328: 0.92, + 329: 0.93, + 330: 0.93, + 331: 0.93, + 332: 0.93, + 333: 0.94, + 334: 0.94, + 335: 0.94, + 336: 0.94, + 337: 0.94, + 338: 0.95, + 339: 0.95, + 340: 0.95, + 341: 0.95, + 342: 0.95, + 343: 0.96, + 344: 0.96, + 345: 0.96, + 346: 0.96, + 347: 0.97, + 348: 0.97, + 349: 0.97, + 350: 0.97, + 351: 0.97, + 352: 0.98, + 353: 0.98, + 354: 0.98, + 355: 0.98, + 356: 0.99, + 357: 0.99, + 358: 0.99, + 360: 0.99, + 359: 0.99, + 361: 1.00, + 362: 1.00, + 363: 1.00, + 364: 1.00, + 365: 1.00, + 366: 1.00, +}; + +function calculator() { + // pull from input fields + var effectiveDate = document.getElementById("effectiveDate").value; + var expiryDate = document.getElementById("expiryDate").value; + var cancelDate = document.getElementById("cancelDate").value; + var totalPremium = document.getElementById("totalPremium").value; + var breakDO = document.getElementById("breakDO").value || 0; + var breakEO = document.getElementById("breakEO").value || 0; + var breakCyber = document.getElementById("breakCyber").value || 0; + var breakLEI = document.getElementById("breakLEI").value || 0; + var breakCGL = document.getElementById("breakCGL").value || 0; + var breakProperty = document.getElementById("breakProperty").value || 0; + var breakEB = document.getElementById("breakEB").value || 0; + + // calculate dates in policy term + var policyDays = new Date(expiryDate).getTime() - new Date(effectiveDate).getTime(); + var termDays = policyDays / (1000 * 60 * 60 * 24); + + // calculate dates involved with cancellation + var cancelDays = new Date(cancelDate).getTime() - new Date(effectiveDate).getTime(); + var forceDays = cancelDays / (1000 * 60 * 60 * 24); + var remainingDays = termDays - forceDays; + + // calculate pro rata + if(document.getElementById('calcProRata').checked) { + var earnedFactor = Math.round(((forceDays / termDays) + Number.EPSILON)*1000)/1000; + var unearnedFactor = Math.round(((remainingDays / termDays) + Number.EPSILON)*1000)/1000; + document.getElementById("earnedFactor").className = 'blue'; + document.getElementById("unearnedFactor").className = 'blue'; + // calculate short rate + }else if(document.getElementById('calcShortRate').checked) { + const searchDate = forceDays; + const shortRateFactor = shortRate[searchDate]; + var earnedFactor = shortRateFactor; + var unearnedFactor = Math.round(((1 - shortRateFactor) + Number.EPSILON)*1000)/1000; + document.getElementById("earnedFactor").className = 'blue'; + document.getElementById("unearnedFactor").className = 'blue'; + }else { + var earnedFactor = 'ERROR' + var unearnedFactor = 'ERROR' + document.getElementById("earnedFactor").className = 'red'; + document.getElementById("unearnedFactor").className = 'red'; + } + // calculate premiums + var earnedPremium = Math.round(((totalPremium * earnedFactor) + Number.EPSILON)*100)/100; + var unearnedPremium = Math.round(((totalPremium * unearnedFactor) + Number.EPSILON)*100)/100; + document.getElementById("earnedPremium").className = 'green'; + document.getElementById("unearnedPremium").className = 'orange'; + + // calculate breakdown + var calcBreak = +breakDO + +breakEO + +breakCyber + +breakLEI + +breakCGL + +breakProperty + +breakEB; + // check if breakdown matches total premium + var calcMatch = calcBreak-totalPremium; + if(totalPremium 1) { + var checkMatch = "❌ Total breakdown does not match total premium. It is too high by " + calcMatch + "."; + document.getElementById("checkMatch").className = 'red'; + var calculateBreakdown = false; + }else if(totalPremium>calcBreak && totalPremium > 1) { + var checkMatch = "❌ Total breakdown does not match total premium. It is too low by " + calcMatch + "."; + document.getElementById("checkMatch").className = 'red'; + var calculateBreakdown = false; + }else if(totalPremium > 1) { + var checkMatch = "✅ Total breakdown matches total premium!"; + document.getElementById("checkMatch").className = 'green'; + var calculateBreakdown = true; + }else { + var checkMatch = "⚠️ More information is required to provide premium breakdown."; + document.getElementById("checkMatch").className = 'orange'; + var calculateBreakdown = false; + } + + // calculate breakdowns + if(calculateBreakdown == true) { + var percentDO = Math.round((((breakDO / totalPremium) * 100) + Number.EPSILON)*100)/100; + var earnedDO = Math.round(((breakDO * earnedFactor) + Number.EPSILON)*100)/100; + var unearnedDO = Math.round(((breakDO * unearnedFactor) + Number.EPSILON)*100)/100; + var percentEO = Math.round((((breakEO / totalPremium) * 100) + Number.EPSILON)*100)/100; + var earnedEO = Math.round(((breakEO * earnedFactor) + Number.EPSILON)*100)/100; + var unearnedEO = Math.round(((breakEO * unearnedFactor) + Number.EPSILON)*100)/100; + var percentCyber = Math.round((((breakCyber / totalPremium) * 100) + Number.EPSILON)*100)/100; + var earnedCyber = Math.round(((breakCyber * earnedFactor) + Number.EPSILON)*100)/100; + var unearnedCyber = Math.round(((breakCyber * unearnedFactor) + Number.EPSILON)*100)/100; + var percentLEI = Math.round((((breakLEI / totalPremium) * 100) + Number.EPSILON)*100)/100; + var earnedLEI = Math.round(((breakLEI * earnedFactor) + Number.EPSILON)*100)/100; + var unearnedLEI = Math.round(((breakLEI * unearnedFactor) + Number.EPSILON)*100)/100; + var percentCGL = Math.round((((breakCGL / totalPremium) * 100) + Number.EPSILON)*100)/100; + var earnedCGL = Math.round(((breakCGL * earnedFactor) + Number.EPSILON)*100)/100; + var unearnedCGL = Math.round(((breakCGL * unearnedFactor) + Number.EPSILON)*100)/100; + var percentProperty = Math.round((((breakProperty / totalPremium) * 100) + Number.EPSILON)*100)/100; + var earnedProperty = Math.round(((breakProperty * earnedFactor) + Number.EPSILON)*100)/100; + var unearnedProperty = Math.round(((breakProperty * unearnedFactor) + Number.EPSILON)*100)/100; + var percentEB = Math.round((((breakEB / totalPremium) * 100) + Number.EPSILON)*100)/100; + var earnedEB = Math.round(((breakEB * earnedFactor) + Number.EPSILON)*100)/100; + var unearnedEB = Math.round(((breakEB * unearnedFactor) + Number.EPSILON)*100)/100; + document.getElementById("percentDO").className = 'blue'; + document.getElementById("earnedDO").className = 'green'; + document.getElementById("unearnedDO").className = 'orange'; + document.getElementById("percentEO").className = 'blue'; + document.getElementById("earnedEO").className = 'green'; + document.getElementById("unearnedEO").className = 'orange'; + document.getElementById("percentCyber").className = 'blue'; + document.getElementById("earnedCyber").className = 'green'; + document.getElementById("unearnedCyber").className = 'orange'; + document.getElementById("percentLEI").className = 'blue'; + document.getElementById("earnedLEI").className = 'green'; + document.getElementById("unearnedLEI").className = 'orange'; + document.getElementById("percentCGL").className = 'blue'; + document.getElementById("earnedCGL").className = 'green'; + document.getElementById("unearnedCGL").className = 'orange'; + document.getElementById("percentProperty").className = 'blue'; + document.getElementById("earnedProperty").className = 'green'; + document.getElementById("unearnedProperty").className = 'orange'; + document.getElementById("percentEB").className = 'blue'; + document.getElementById("earnedEB").className = 'green'; + document.getElementById("unearnedEB").className = 'orange'; + }else { + var percentDO = 'ERROR' + var earnedDO = 'ERROR' + var unearnedDO = 'ERROR' + var percentEO = 'ERROR' + var earnedEO = 'ERROR' + var unearnedEO = 'ERROR' + var percentCyber = 'ERROR' + var earnedCyber = 'ERROR' + var unearnedCyber = 'ERROR' + var percentLEI = 'ERROR' + var earnedLEI = 'ERROR' + var unearnedLEI = 'ERROR' + var percentCGL = 'ERROR' + var earnedCGL = 'ERROR' + var unearnedCGL = 'ERROR' + var percentProperty = 'ERROR' + var earnedProperty = 'ERROR' + var unearnedProperty = 'ERROR' + var percentEB = 'ERROR' + var earnedEB = 'ERROR' + var unearnedEB = 'ERROR' + document.getElementById("percentDO").className = 'red'; + document.getElementById("earnedDO").className = 'red'; + document.getElementById("unearnedDO").className = 'red'; + document.getElementById("percentEO").className = 'red'; + document.getElementById("earnedEO").className = 'red'; + document.getElementById("unearnedEO").className = 'red'; + document.getElementById("percentCyber").className = 'red'; + document.getElementById("earnedCyber").className = 'red'; + document.getElementById("unearnedCyber").className = 'red'; + document.getElementById("percentLEI").className = 'red'; + document.getElementById("earnedLEI").className = 'red'; + document.getElementById("unearnedLEI").className = 'red'; + document.getElementById("percentCGL").className = 'red'; + document.getElementById("earnedCGL").className = 'red'; + document.getElementById("unearnedCGL").className = 'red'; + document.getElementById("percentProperty").className = 'red'; + document.getElementById("earnedProperty").className = 'red'; + document.getElementById("unearnedProperty").className = 'red'; + document.getElementById("percentEB").className = 'red'; + document.getElementById("earnedEB").className = 'red'; + document.getElementById("unearnedEB").className = 'red'; + } + + // display policy terms + document.getElementById("termDays").innerHTML = termDays; + document.getElementById("forceDays").innerHTML = forceDays; + document.getElementById("remainingDays").innerHTML = remainingDays; + document.getElementById("earnedFactor").innerHTML = earnedFactor; + document.getElementById("unearnedFactor").innerHTML = unearnedFactor; + document.getElementById("earnedPremium").innerHTML = earnedPremium; + document.getElementById("unearnedPremium").innerHTML = unearnedPremium; + // display breakdown + document.getElementById("checkMatch").innerHTML = checkMatch; + document.getElementById("percentDO").innerHTML = percentDO; + document.getElementById("earnedDO").innerHTML = earnedDO; + document.getElementById("unearnedDO").innerHTML = unearnedDO; + document.getElementById("percentEO").innerHTML = percentEO; + document.getElementById("earnedEO").innerHTML = earnedEO; + document.getElementById("unearnedEO").innerHTML = unearnedEO; + document.getElementById("percentCyber").innerHTML = percentCyber; + document.getElementById("earnedCyber").innerHTML = earnedCyber; + document.getElementById("unearnedCyber").innerHTML = unearnedCyber; + document.getElementById("percentLEI").innerHTML = percentLEI; + document.getElementById("earnedLEI").innerHTML = earnedLEI; + document.getElementById("unearnedLEI").innerHTML = unearnedLEI; + document.getElementById("percentCGL").innerHTML = percentCGL; + document.getElementById("earnedCGL").innerHTML = earnedCGL; + document.getElementById("unearnedCGL").innerHTML = unearnedCGL; + document.getElementById("percentProperty").innerHTML = percentProperty; + document.getElementById("earnedProperty").innerHTML = earnedProperty; + document.getElementById("unearnedProperty").innerHTML = unearnedProperty; + document.getElementById("percentEB").innerHTML = percentEB; + document.getElementById("earnedEB").innerHTML = earnedEB; + document.getElementById("unearnedEB").innerHTML = unearnedEB; +} diff --git a/assets/favicon.ico b/assets/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..f0ff017237fcb130eb84285d9c33e55692236978 GIT binary patch literal 318 zcmZQzU<5(|0RbS%!l1#(z#zuJz@P!d0zj+)#2|4HXaJKC0wf0lqKhst@bklX5HV6n TK`4Nlz(_9|W-lpj#ikYjN9+X` literal 0 HcmV?d00001 diff --git a/assets/style.css b/assets/style.css new file mode 100644 index 0000000..5de6146 --- /dev/null +++ b/assets/style.css @@ -0,0 +1,190 @@ +html, body, div, span, applet, object, iframe, +:root { + --width: 900px; + --font-family: Verdana, sans-serif; + --font-scale: 1em; + --bg-100: #100F0F; + --bg-200: #1C1B1A; + --ui-100: #282726; + --ui-200: #343331; + --ui-300: #403E3C; + --text-100: #CECDC3; + --text-200: #878580; + --text-300: #575653; + + --blue-400: #4385BE; + --cyan-400: #3AA99F; + --green-400: #879A39; + --orange-400: #DA702C; + --purple-400: #8B7EC8; + --red-400: #D14D41; + --yellow-400: #D0A215; +} +@media (prefers-color-scheme: dark) { + :root { + } +} + +body { + margin: 0 auto; + padding: 0 16px; + max-width: var(--width); + background-color: var(--bg-100); + font-family: var(--font-family); + font-size: var(--font-scale); + color: var(--text-100); +} + +.blue { color: var(--blue-400); } +.cyan { color: var(--cyan-400); } +.green { color: var(--green-400); } +.orange { color: var(--orange-400); } +.purple { color: var(--purple-400); } +.red { color: var(--red-400); } + +h1, h2, h3 { + margin: 0; + padding: 0; +} +h2 { + margin: 1rem 0; +} + +a, +a:visited { + color: var(--text-100); + text-decoration: underline; + text-underline-offset: 3px; + text-decoration-thickness: 1px; + text-decoration-style: solid; + text-decoration-color: var(--cyan-400); +} +a:hover { + color: var(--cyan-400); + text-decoration: underline; + text-decoration-style: solid; + text-decoration-color: var(--cyan-400); +} + +ul { + margin: 0; + padding: 0 0 0 1rem; +} +li { + list-style-type: square; +} + +form { + margin: 0; + padding: 0; +} +button { + margin-top: 2rem; + padding: 10px; + width: 100%; + border: 1px solid var(--ui-100); + background-color: var(--bg-200); + color: var(--text-100); +} +button:hover{ + border: 1px solid var(--ui-300); +} +input { + border: 1px solid var(--ui-100); + background-color: var(--bg-200); + color: var(--text-100); +} +input:hover { + border-color: var(--ui-300); +} +input:focus { + outline: none; + border-color: var(--cyan-400); +} +input::-webkit-outer-spin-button, +input::-webkit-inner-spin-button { + -webkit-appearance: none; + margin: 0; +} +input[type="number"] { + -moz-appearance: textfield; +} + +blockquote { + margin: 1rem 0; + padding: 16px; + border-top: 1px dotted var(--yellow-400); + border-right: 1px dotted var(--yellow-400); + border-bottom: 1px dotted var(--yellow-400); + border-left: 8px solid var(--yellow-400); + background-color: var(--bg-200); +} + +table { + width: 100%; + border-collapse: collapse; + border: 1px solid var(--ui-100); + background-color: var(--bg-200); +} +tr { + border: 1px solid var(--ui-100); +} +th { + padding: 4px 16px; + border-right: 1px solid var(--ui-100); + background-color: var(--ui-200); +} +td { + padding: 4px 16px; + border-right: 1px solid var(--ui-100); +} +tr td:nth-child(3) { + text-align: center; +} +tr td:nth-child(4), +tr td:nth-child(5) { + text-align: right; +} + +header { + margin-top: 4rem; +} + +main { + margin: 4rem 0; +} + +.flex-container { + display: flex; + margin: 0; + padding: 0; + flex-direction: row; + gap: 2rem 1rem; + flex-wrap: wrap; + align-items: flex-start; + justify-content: center; +} +.flex-1 { + order: 1; + flex-grow: 1; +} +.flex-2{ + order: 2; + flex-grow: 1 +} +.flex-3 { + order: 3; + flex-grow: 2; +} +.flex-4 { + order: 4; + flex-grow: 2; +} + +footer { + margin-bottom: 4rem; + padding-top: 2rem; + border-top: 1px dotted var(--ui-100); + font-size: .875em; + color: var(--text-200); +} diff --git a/index.html b/index.html index ad78beb..805d631 100644 --- a/index.html +++ b/index.html @@ -3,122 +3,148 @@ + Calculator - + + + + + +
-

Calculator

+

Premium Calculator

-
-
-
-

Policy Details

- - -
- - -
- Days in policy term: - -

- - -
- Days in force: - -
- Days remaining: - -

- Factor method: - Pro Rata - Short Rate -

- Earned factor: - -
- Unearned factor: - -

- - -
- Earned premium: - -
- Return premium: - -
- -
-

Breakdown

-

Total breakdown: N/A

- - - -
- Earned premium: - -
- Return premium: - -

- - - -
- Earned premium: - -
- Return premium: - -

- - - -
- Earned premium: - -
- Return premium: - -

- - - -
- Earned premium: - -
- Return premium: - -

- - - -
- Earned premium: - -
- Return premium: - -

- - - -
- Earned premium: - -
- Return premium: - -

- - - -
- Earned premium: - -
- Return premium: - -

-
+
+
+

Policy Details

+ + +
+ + +
+ Days in policy term: - +

+ + +
+ Days in force: - +
+ Days remaining: - +

+ + +
+ +
+

Factor Method

+ Factor method: + Pro Rata + Short Rate +

+ + + + + + + + + + + + + + + + +
EarnedUnearned
Factor--
Premium--
+
+ +
+

Premium Breakdown

+
Total breakdown: N/A
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
CoveragePremium% of TotalEarned PremiumUnearned Premium
---
---
---
---
---
---
---
- - +
+ +
+
-

Created by Hao Tran.

-

Note: Calculations are rounded to the nearest hundredth decimal. As such, there may sometimes be issues of rounding error.

+
    +
  • Created by Hao Tran.
  • +
  • Calculations are rounded to the nearest hundredth decimal. As such, there may sometimes be issues of rounding error.
  • +
  • Although effort was made to insure the accuracy of this calculator, there is no guarantee on the accuracy of the calculations and results. This calculator is intended for personal and informational use only and does not constitute advice.
  • +
+ + - diff --git a/scripts/calculator.js b/scripts/calculator.js deleted file mode 100644 index afd291d..0000000 --- a/scripts/calculator.js +++ /dev/null @@ -1,114 +0,0 @@ -function calculator() { - // pull from input fields - var effectiveDate = document.getElementById("effectiveDate").value; - var expiryDate = document.getElementById("expiryDate").value; - var cancelDate = document.getElementById("cancelDate").value; - var totalPremium = document.getElementById("totalPremium").value; - var breakDO = document.getElementById("breakDO").value || 0; - var breakEO = document.getElementById("breakEO").value || 0; - var breakCyber = document.getElementById("breakCyber").value || 0; - var breakLEI = document.getElementById("breakLEI").value || 0; - var breakCGL = document.getElementById("breakCGL").value || 0; - var breakProperty = document.getElementById("breakProperty").value || 0; - var breakEB = document.getElementById("breakEB").value || 0; - - // calculate dates in policy term - var policyDays = new Date(expiryDate).getTime() - new Date(effectiveDate).getTime(); - var termDays = policyDays / (1000 * 60 * 60 * 24); - - // calculate dates involved with cancellation - var cancelDays = new Date(cancelDate).getTime() - new Date(effectiveDate).getTime(); - var forceDays = cancelDays / (1000 * 60 * 60 * 24); - var remainingDays = termDays - forceDays; - - // calculate pro rata - if(document.getElementById('calcProRata').checked) { - var earnedFactor = Math.round(((forceDays / termDays) + Number.EPSILON)*100)/100; - var unearnedFactor = Math.round(((remainingDays / termDays) + Number.EPSILON)*100)/100; - // calculate short rate - }else if(document.getElementById('calcShortRate').checked) { - var earnedFactor = Math.round(((1 - ((remainingDays / termDays ) * 0.9)) + Number.EPSILON)*100)/100; - var unearnedFactor = Math.round((((remainingDays / termDays) * 0.9) + Number.EPSILON)*100)/100; - } - - // calculate premiums - var earnedPremium = Math.round(((totalPremium * earnedFactor) + Number.EPSILON)*100)/100; - var unearnedPremium = Math.round(((totalPremium * unearnedFactor) + Number.EPSILON)*100)/100; - - // calculate breakdown - var calcBreak = +breakDO + +breakEO + +breakCyber + +breakLEI + +breakCGL + +breakProperty + +breakEB; - // check if breakdown matches total premium - var calcMatch = calcBreak-totalPremium; - if(totalPremiumcalcBreak) { - var checkMatch = "Total breakdown is too low by " + calcMatch + "."; - document.getElementById("checkMatch").className = 'red'; - var calculateBreakdown = false; - }else { - var checkMatch = "Total breakdown matches total premium! Success!"; - document.getElementById("checkMatch").className = 'green'; - var calculateBreakdown = true; - } - - // calculate breakdowns - if(calculateBreakdown == true) { - var earnedDO = Math.round(((breakDO * earnedFactor) + Number.EPSILON)*1000)/1000; - var unearnedDO = Math.round(((breakDO * unearnedFactor) + Number.EPSILON)*1000)/1000; - var earnedEO = Math.round(((breakEO * earnedFactor) + Number.EPSILON)*1000)/1000; - var unearnedEO = Math.round(((breakEO * unearnedFactor) + Number.EPSILON)*1000)/1000; - var earnedCyber = Math.round(((breakCyber * earnedFactor) + Number.EPSILON)*1000)/1000; - var unearnedCyber = Math.round(((breakCyber * unearnedFactor) + Number.EPSILON)*1000)/1000; - var earnedLEI = Math.round(((breakLEI * earnedFactor) + Number.EPSILON)*1000)/1000; - var unearnedLEI = Math.round(((breakLEI * unearnedFactor) + Number.EPSILON)*1000)/1000; - var earnedCGL = Math.round(((breakCGL * earnedFactor) + Number.EPSILON)*1000)/1000; - var unearnedCGL = Math.round(((breakCGL * unearnedFactor) + Number.EPSILON)*1000)/1000; - var earnedProperty = Math.round(((breakProperty * earnedFactor) + Number.EPSILON)*1000)/1000; - var unearnedProperty = Math.round(((breakProperty * unearnedFactor) + Number.EPSILON)*1000)/1000; - var earnedEB = Math.round(((breakEB * earnedFactor) + Number.EPSILON)*1000)/1000; - var unearnedEB = Math.round(((breakEB * unearnedFactor) + Number.EPSILON)*1000)/1000; - }else { - var earnedDO = 'ERROR' - var unearnedDO = 'ERROR' - var earnedEO = 'ERROR' - var unearnedEO = 'ERROR' - var earnedCyber = 'ERROR' - var unearnedCyber = 'ERROR' - var earnedLEI = 'ERROR' - var unearnedLEI = 'ERROR' - var earnedCGL = 'ERROR' - var unearnedCGL = 'ERROR' - var earnedProperty = 'ERROR' - var unearnedProperty = 'ERROR' - var earnedEB = 'ERROR' - var unearnedEB = 'ERROR' - } - - // display policy terms - document.getElementById("termDays").innerHTML = termDays; - document.getElementById("forceDays").innerHTML = forceDays; - document.getElementById("remainingDays").innerHTML = remainingDays; - document.getElementById("earnedFactor").innerHTML = earnedFactor; - document.getElementById("unearnedFactor").innerHTML = unearnedFactor; - document.getElementById("earnedPremium").innerHTML = earnedPremium; - document.getElementById("unearnedPremium").innerHTML = unearnedPremium; - // display breakdown - document.getElementById("checkMatch").innerHTML = checkMatch; - document.getElementById("earnedDO").innerHTML = earnedDO; - document.getElementById("unearnedDO").innerHTML = unearnedDO; - document.getElementById("earnedEO").innerHTML = earnedEO; - document.getElementById("unearnedEO").innerHTML = unearnedEO; - document.getElementById("earnedCyber").innerHTML = earnedCyber; - document.getElementById("unearnedCyber").innerHTML = unearnedCyber; - document.getElementById("earnedLEI").innerHTML = earnedLEI; - document.getElementById("unearnedLEI").innerHTML = unearnedLEI; - document.getElementById("earnedCGL").innerHTML = earnedCGL; - document.getElementById("unearnedCGL").innerHTML = unearnedCGL; - document.getElementById("earnedProperty").innerHTML = earnedProperty; - document.getElementById("unearnedProperty").innerHTML = unearnedProperty; - document.getElementById("earnedEB").innerHTML = earnedEB; - document.getElementById("unearnedEB").innerHTML = unearnedEB; -} -doSomething diff --git a/style.css b/style.css deleted file mode 100644 index c861333..0000000 --- a/style.css +++ /dev/null @@ -1,76 +0,0 @@ -:root { - --width: 900px; - --font-family: Verdana, sans-serif; - --font-scale: 1em; - --bg-100: #100F0F; - --bg-200: #1C1B1A; - --ui-100: #292726; - --ui-200: #343331; - --ui-300: #403E3C; - --text-100: #CECDC3; - - - --cyan-400: #3AA99F; - --green-400: #879A39; - --red-400: #D14D41; -} -@media (prefers-color-scheme: dark) { - :root { - } -} - -body { - margin: 0 auto; - padding: 0 16px; - max-width: var(--width); - background-color: var(--bg-100); - font-family: var(--font-family); - font-size: var(--font-scale); - color: var(--text-100); -} - -.green { color: var(--green-400); } -.red { color: var(--red-400); } - - - -button { - margin-top: 2rem; - padding: 10px; - width: 100%; - border: 1px solid var(--ui-300); - background-color: var(--green-400); - color: var(--text-100); -} -input { - border: 1px solid var(--ui-300); - background-color: var(--ui-100); - color: var(--text-100); -} -input:focus { - outline: none; - border-color: var(--cyan-400); -} - - -header { - margin-top: 4rem; -} - -main { - margin: 4rem 0; -} - -.flex-container { - display: flex; - flex-direction: row; - column-gap: 1rem; -} -.flex-1 { - order: 1; - width: 400px; -} - -.flex-2 { - order: 2; -}